使用说明
LinkedIn MCP服务器
如果你在人工智能代理周围花了足够的时间,你会一遍又一遍地听到同样的承诺:代理不仅会回答问题,还会工作。
如果模型不能安全可靠地与真实系统交互,那么这一承诺只有一部分是正确的。
一个不会使用工具的代理人通常是一个很好的健谈者。一个能够发现工具、理解其输入并执行实际操作的代理开始变得有用。
这就是MCP发挥作用的地方。
这个项目是一个LinkedIn MCP服务器,通过一个干净的工具界面公开LinkedIn的功能。服务器没有要求模型猜测如何调用LinkedIn API,而是为模型提供了一组结构化的操作,用于个人资料查找、内容发布、图像发布和文章共享。
GitHub存储库: https://github.com/hashan-silva/linkedin-mcp-server
Docker镜像: hashan0314/linkedin-mcp-server
您需要一个具有适当范围的有效LinkedIn OAuth访问令牌。令牌不存储在此项目中;通过环境变量提供它们或使用内置的OAuth流。
什么是MCP
MCP代表模型上下文协议。
最简单的思考方式是:MCP为AI代理提供了一种使用工具的标准方法。
如果没有MCP,开发人员通常会在提示中描述API,并希望模型完全遵循这些说明。这种方法是脆弱的。模型可以发明参数,跳过所需的字段,或者滥用他们只能部分理解的API形状。
MCP用结构取代了这种猜测。
MCP服务器告诉代理:
- 存在哪些工具
- 每个工具的作用
- 需要哪些输入
- 结果如何返回
在这个项目中,服务器从标准输入读取JSON消息,并将JSON响应写入标准输出。传输故意轻量级,但接口明确可靠。
while True:
line = await reader.readline()
if not line:
break
message = json.loads(line.decode())
response = await self.handle_message(message)
if response is not None:
writer.write((json.dumps(response) + "\n").encode())
await writer.drain()
这就是MCP服务器的基本形状:接收结构化请求,路由它,返回结构化响应。
为什么MCP对Agent AI很重要
MCP的真正价值不在于它允许代理访问。它为他们提供了有纪律的访问权限。
这很重要,因为特工需要的不仅仅是情报。它需要可靠的方式与外部系统进行交互。MCP在几个重要方面对此有所帮助。
它使工具的使用变得明确
与其希望模型记住LinkedIn帖子的工作原理,不如公开一个类似的工具 create_text_post 或 create_article_post.
此项目中的一个工具定义如下:
{
"name": "create_article_post",
"description": "Create a LinkedIn article post with an external article link.",
"inputSchema": {
"type": "object",
"properties": {
"author": {"type": "string"},
"commentary": {"type": "string"},
"articleSource": {"type": "string"},
"articleTitle": {"type": "string"},
"articleDescription": {"type": "string"},
},
"required": [
"author",
"commentary",
"articleSource",
"articleTitle",
"articleDescription",
],
},
}
这比在提示中隐藏API指令要可靠得多。
它将推理与执行分开
模型决定它想做什么。服务器处理它是如何完成的。
这意味着代理可以专注于以下决策:
- 我应该先获取个人资料吗?
- 我应该创建文本帖子还是文章帖子?
- 在发布媒体之前,我需要初始化图像上传吗?
然后,服务器会处理其余的事情:
- 标头和身份验证
- LinkedIn API端点
- 有效载荷结构
- 上传流
- 错误处理
它使代理人更容易管理
一个聚焦的MCP服务器只公开您希望代理执行的操作。
这比给模型广泛的网络自由并希望它正确运行更安全。在这个项目中,模型只能使用服务器显式公开的LinkedIn操作。
它使集成可重用
一旦将功能包装为MCP,多个代理就可以使用它。同一台服务器可以插入Codex CLI、本地工作流或容器化环境。
这时,集成不再是一种快速的技巧,而是开始成为基础设施。
此服务器的功能
从高层次上讲,LinkedIn MCP服务器做了三件事:
- 将LinkedIn相关工具暴露给AI代理
- 将工具调用转换为LinkedIn REST API请求
- 通过访问令牌或内置OAuth流处理身份验证
该架构有意保持简洁。一层公开工具,一层与LinkedIn对话,一个助手处理OAuth。
外露工具
get_profileget_verification_reportget_userinfocreate_text_postcreate_reshareinitialize_image_uploadupload_image_binarycreate_image_postcreate_multi_image_postcreate_article_post
服务器将工具调用直接发送到LinkedIn客户端:
if name == "get_profile":
return self.client.get_profile()
if name == "create_text_post":
return self.client.create_post(
author=args.get("author", ""),
commentary=args.get("commentary", ""),
visibility=args.get("visibility", "PUBLIC"),
)
if name == "create_article_post":
return self.client.create_article_post(
author=args.get("author", ""),
commentary=args.get("commentary", ""),
article_source=args.get("articleSource", ""),
article_title=args.get("articleTitle", ""),
article_description=args.get("articleDescription", ""),
)
这种直接性是该项目的优势之一。MCP不必复杂才能有用。
LinkedIn功能
此服务器支持有意义的LinkedIn工作流,而不仅仅是展示玩具演示。
配置文件和身份查找
服务器可以检索:
- 当前成员配置文件
- 验证报告
- OpenID连接用户信息
个人资料查找是对LinkedIn身份端点的直接调用:
resp = self.session.get(
self._url("/rest/identityMe"),
headers={"LinkedIn-Version": "202510.03"},
)
这会在代理开始代表用户行事之前提供代理上下文。
文本帖子创建
这 create_text_post 该工具允许代理发布标准的纯文本LinkedIn帖子。
有效载荷包括作者、评论、可见性、分发设置和生命周期状态:
return {
"author": author_value,
"commentary": commentary_value,
"visibility": visibility,
"distribution": distribution or {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": [],
},
"lifecycleState": lifecycle_state,
"isReshareDisabledByAuthor": is_reshare_disabled_by_author,
}
代理不需要知道LinkedIn的有效载荷形状。它只是以正确的意图和论据调用工具。
重新共享
这 create_reshare 该工具允许代理人重新发布现有的领英帖子,并添加可选的评论。
有效载荷包括 reshareContext 这指向了父帖子:
payload = {
"author": author_value,
"visibility": visibility,
"distribution": distribution or {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": [],
},
"lifecycleState": lifecycle_state,
"isReshareDisabledByAuthor": is_reshare_disabled_by_author,
"reshareContext": {"parent": parent_value},
}
图片上传和图片发布
媒体发布被有意建模为一个多步骤的工作流程:
- 初始化上传
- 接收上传URL和图像URN
- 上传图像二进制文件
- 创建引用上传媒体的最终帖子
上传初始化步骤如下:
resp = self.session.post(
self._url("/rest/images?action=initializeUpload"),
json={"initializeUploadRequest": {"owner": owner_value}},
headers={"LinkedIn-Version": linkedin_version},
)
然后,二进制上传直接发送到提供的上传URL:
with path.open("rb") as handle:
resp = requests.put(
url_value,
data=handle,
headers={"Content-Type": "application/octet-stream"},
)
这反映了真实的LinkedIn流程,而不是将其隐藏在不切实际的一步抽象之后。
多图像帖子
这 create_multi_image_post 该工具允许代理通过构建一个 multiImage 内容结构:
return {
"author": author_value,
"commentary": commentary_value,
"visibility": visibility,
"distribution": distribution or {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": [],
},
"lifecycleState": lifecycle_state,
"isReshareDisabledByAuthor": is_reshare_disabled_by_author,
"content": {"multiImage": {"images": image_items}},
}
文章帖子
这 create_article_post 该工具对于较长的表单内容工作流特别有用。它允许代理发布链接到外部文章的LinkedIn帖子,如Medium帖子。
return {
"author": author_value,
"commentary": commentary_value,
"visibility": visibility,
"lifecycleState": lifecycle_state,
"content": {
"article": {
"source": source_value,
"title": title_value,
"description": description_value,
}
},
"distribution": distribution or {"feedDistribution": "MAIN_FEED"},
}
这是MCP将混乱的外部API功能转变为代理可以使用的干净工具的一个有力例子。
认证
身份验证是许多演示变得不切实际的地方。这个项目以一种实用的方式处理它。
您可以:
- 提供
LINKEDIN_ACCESS_TOKEN直接 - 使用以下命令启动服务器
--auth并完成OAuth流程
授权URL的构建方式如下:
params = {
"response_type": "code",
"client_id": client_id,
"redirect_uri": redirect_uri,
"scope": scope,
"state": state,
}
然后,服务器等待重定向,捕获授权码,并将其交换为访问令牌。内置的OAuth助手使该项目在实践中更容易使用。
特性
- 获取个人资料
- 获取验证报告
- 获取用户信息
- 创建纯文本帖子
- 创建转发帖子
- 创建图片帖子
- 创建多图像帖子
- 创建文章帖子
在本地运行
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export LINKEDIN_ACCESS_TOKEN="<your-token>"
# optional: override API base
# export LINKEDIN_BASE_URL="https://api.linkedin.com"
python -m src.mcp_server
服务器与stdio保持连接,可以在兼容的客户端中配置为MCP服务器。
内置OAuth助手
如果您有LinkedIn应用程序客户端ID和密码,则可以使用OAuth辅助身份验证启动服务器:
export LINKEDIN_CLIENT_ID="your-client-id"
export LINKEDIN_CLIENT_SECRET="your-client-secret"
export LINKEDIN_REDIRECT_URI="http://127.0.0.1:8765/callback"
# optional: scopes
# export LINKEDIN_SCOPE="r_liteprofile w_member_social"
python -m src.mcp_server --auth
服务器打印一个授权URL,等待重定向,用代码交换访问令牌,然后启动MCP循环。
码头工人
构建并运行:
docker build -t linkedin-mcp-server .
docker run --rm -e LINKEDIN_ACCESS_TOKEN="$LINKEDIN_ACCESS_TOKEN" linkedin-mcp-server
使用备用基URL运行:
docker run --rm -e LINKEDIN_ACCESS_TOKEN=... -e LINKEDIN_BASE_URL=https://api.linkedin.com linkedin-mcp-server
直接使用已发布的图像:
docker run --rm -i -e LINKEDIN_ACCESS_TOKEN=... hashan0314/linkedin-mcp-server
不要在图像中添加秘密。在运行时使用环境变量传递凭据,或 --env-file.
Docker中的OAuth:
docker run --rm \
-p 8765:8765 \
-e LINKEDIN_CLIENT_ID=... \
-e LINKEDIN_CLIENT_SECRET=... \
-e LINKEDIN_REDIRECT_URI=http://127.0.0.1:8765/callback \
hashan0314/linkedin-mcp-server python -m src.mcp_server --auth
Codex CLI示例
将stdio MCP服务器条目添加到 ~/.codex/config.toml:
[mcp_servers.linkedin]
command = "docker"
args = ["run", "--rm", "-i", "-e", "LINKEDIN_ACCESS_TOKEN", "hashan0314/linkedin-mcp-server"]
env = {"LINKEDIN_ACCESS_TOKEN"="<your_token>"}
startup_timeout_ms = 30000
备注
- 有意尽量减少验证;LinkedIn API错误会返回给调用方。
- 请注意LinkedIn的费率限制和代币范围。
- 如果您看到401或403,则您的令牌可能已过期或缺少所需的作用域。
- 除了LinkedIn API本身之外,没有实现任何持久性。
为什么这个项目有用
这个项目足够小,可以快速理解,但足够真实,可以证明MCP的重要性。
它显示:
- 一种真正的stdio MCP传输
- 明确的工具定义
- 结构化工具输入
- 协议和API执行之间的清晰分离
- 一个实用的身份验证故事
- 代理可以实际使用的读写工作流
如果你想了解为什么MCP对代理AI很重要,这是核心思想:给模型结构化的工具,把执行逻辑放在提示之外,让代理通过稳定的接口工作,而不是即兴创作。