LangGraph 入门实战(12)--使用MCP
LangGraph å ¥é¨å®æ(12)--使ç¨MCP
åæè½å¡å° 2026-08-20 0 é 读3åéLangGraph è°ç¨ Gitee MCPï¼ä¸ä¸ªå¯è¿è¡çæå°ç¤ºä¾
MCPï¼Model Context Protocolï¼å¯ä»¥æè¿ç¨æå¡æä¾çè½åå è£ ææ¨¡åå¯è°ç¨çå·¥å ·ãæ¬ä¾ä½¿ç¨ LangGraph ç¼æ DeepSeekï¼éè¿ Gitee 宿¹ MCP Server æ¥è¯¢ä»åºä¿¡æ¯ã
1. 工使µ
æµç¨å¾ç®åï¼
call_model让模åå¤æç´æ¥åçï¼è¿æ¯è°ç¨ Gitee å·¥å ·ãtoolsèç¹ç±ToolNodeæ§è¡ MCP å·¥å ·ãtools_conditionæ ¹æ®æ¨¡åæ¯å¦äº§çtool_callså³å®ç»ææç»§ç»å¾ªç¯ã
2. å®è£ ä¸é ç½®
å»ºè®®ä½¿ç¨ Python 3.10 ææ´é«çæ¬ï¼
cd docs/æélanggraph12使ç¨mcp
python -m venv .venv
source .venv/bin/activate
python -m pip install -U python-dotenv langgraph langchain-core langchain-deepseek langchain-mcp-adapters pydantic
å¨ docs/æélanggraph12使ç¨mcp/.env ä¸å¡«å两个å¯é¥ï¼
GITEE_ACCESS_TOKEN=ä½ ç Gitee 访é®ä»¤ç
DEEPSEEK_API_KEY=ä½ ç DeepSeek API Key
Gitee MCP å°åæ¯ https://api.gitee.com/mcpï¼ä»£ç ä½¿ç¨ streamable_http è¿æ¥ï¼å æ¤ä¸éè¦å¨æ¬æºå¯å¨ MCP Serverã
3. 宿´ä»£ç
å°ä¸é¢ä»£ç ä¿å为 index.pyï¼é¡¹ç®ä¸ç docs/æélanggraph12使ç¨mcp/index.py å·²å
å«åæ ·é»è¾ï¼ï¼
import asyncio
import os
import sys
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_deepseek import ChatDeepSeek
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.sessions import StreamableHttpConnection
from langgraph.graph import END, START, MessagesState, StateGraph
from langgraph.prebuilt import ToolNode, tools_condition
from pydantic import SecretStr
GITEE_MCP_URL = "https://api.gitee.com/mcp"
async def build_graph():
gitee_token = os.getenv("GITEE_ACCESS_TOKEN")
if not gitee_token:
raise RuntimeError("ç¼ºå° GITEE_ACCESS_TOKENï¼è¯·å
é
ç½® Gitee 访é®ä»¤çã")
# éè¿æµå¼ HTTP è¿æ¥ Gitee 宿¹ MCP Serverã
connection: StreamableHttpConnection = {
"transport": "streamable_http",
"url": GITEE_MCP_URL,
"headers": {"Authorization": f"Bearer {gitee_token}"},
}
client = MultiServerMCPClient({"gitee": connection})
tools = await client.get_tools()
if not tools:
raise RuntimeError("MCP Server 没æè¿åå¯ç¨å·¥å
·ã")
print(f"å·²ä» Gitee MCP Server å è½½ {len(tools)} 个工å
·ã")
print("é¨åå·¥å
·ï¼", ", ".join(tool.name for tool in tools[:8]))
deepseek_api_key = os.getenv("DEEPSEEK_API_KEY")
if not deepseek_api_key:
raise RuntimeError("ç¼ºå° DEEPSEEK_API_KEYï¼è¯·å
é
ç½® DeepSeek API Keyã")
model = ChatDeepSeek(
model="deepseek-v4-flash",
temperature=0,
base_url="https://api.deepseek.com",
api_key=SecretStr(deepseek_api_key),
)
model_with_tools = model.bind_tools(tools)
async def call_model(state: MessagesState):
# 模å读åå岿¶æ¯ï¼çææ®éåçæ tool_callsã
response = await model_with_tools.ainvoke(state["messages"])
return {"messages": [response]}
builder = StateGraph(MessagesState)
builder.add_node("call_model", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "call_model")
builder.add_conditional_edges(
"call_model", tools_condition, {"tools": "tools", END: END}
)
builder.add_edge("tools", "call_model")
return builder.compile()
async def main():
load_dotenv()
question = " ".join(sys.argv[1:]).strip()
if not question:
question = input("请è¾å
¥å
³äº Gitee çé®é¢ï¼").strip()
if not question:
raise RuntimeError("é®é¢ä¸è½ä¸ºç©ºã")
graph = await build_graph()
state: MessagesState = {
"messages": [
SystemMessage(
content=(
"ä½ æ¯ Gitee 婿ãè¯·æ ¹æ® Gitee MCP å·¥å
·è¿åçç宿°æ®åçï¼"
"ä¸è¦ç¼é ä»åºãIssue æ Pull Requestãé¤éç¨æ·æç¡®è¦æ±ï¼"
"å¦ååªæ§è¡è¯»åæä½ãåç使ç¨ç®ä½ä¸æã"
)
),
HumanMessage(content=question),
]
}
result = await graph.ainvoke(state)
print(" æç»åçï¼")
result["messages"][-1].pretty_print()
if __name__ == "__main__":
try:
asyncio.run(main())
except (RuntimeError, KeyboardInterrupt) as error:
print(f" è¿è¡å¤±è´¥ï¼{error}", file=sys.stderr)
raise SystemExit(1) from error
4. è¿è¡
å½ä»¤è¡ç´æ¥ä¼ å ¥é®é¢ï¼
python index.py "请ååºææè¿æ´æ°ç 5 个 Gitee ä»åº"
ä¹å¯ä»¥ä¸å¸¦åæ°ï¼å¯å¨å交äºè¾å ¥ã
5. è¾åºç¤ºä¾
å·¥å ·å表åä»åºå 容åå³äºå½åè´¦å·ï¼ä¸é¢æ¯ä¸æ¬¡æåè¿è¡çè¾åºæ ¼å¼ï¼
å·²ä» Gitee MCP Server å è½½ 8 个工å
·ã
é¨åå·¥å
·ï¼ list_user_repos, get_user_info, get_repo, list_repo_issues
æç»åçï¼
================================== Ai Message ==================================
ä½ æè¿æ´æ°ç 5 个 Gitee ä»åºå¦ä¸ï¼
1. demo-project
2. langgraph-example
3. notes
...
妿å¯é¥æ²¡æé
ç½®ï¼ç¨åºä¼æåæç¤º ç¼ºå° GITEE_ACCESS_TOKEN æ ç¼ºå° DEEPSEEK_API_KEYï¼ä¸ä¼ææ æè¯·æ±åéå°è¿ç¨æå¡ã
6. å ³é® API
MultiServerMCPClient.get_tools()ï¼åç° MCP Server æ´é²çå·¥å ·ãmodel.bind_tools(tools)ï¼æå·¥å ·æè¿°äº¤ç»æ¨¡åï¼ç±æ¨¡åå³å®æ¯å¦è°ç¨ãToolNode(tools)ï¼å®é æ§è¡å·¥å ·è°ç¨å¹¶çæToolMessageãtools_conditionï¼ætool_callsæ¶è¿å ¥å·¥å ·èç¹ï¼å¦åç»æå¾ãMessagesStateï¼ä¿åç³»ç»ãç¨æ·ã模ååå·¥å ·æ¶æ¯ã
è¿ä¸ªæ¨¡å¼è¿å¯ä»¥ç»§ç»æ©å±å¤ä¸ª MCP Serverãæä¹ 忣æ¥ç¹ï¼æå¨å·¥å ·èç¹åå å ¥äººå·¥å®¡æ ¸ã
Aitishiku.com