模型上下文协议服务器

MCP服务器是一个用于注册和执行工具、处理资源请求的协议实现,适用于开发工具集成和API交互场景。

  • by burrsutter
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 burrsutter/mcp-server-tutorial

使用说明

MCP服务器教程

示例1:最简单的MCP服务器

这是最基础的MCP(模型上下文协议)服务器实现。它通过一个工具展示了MCP服务器的基本结构。

这个例子所展示的内容

  • 基本MCP服务器设置
  • 注册单个工具(echo)
  • 工具输入模式定义
  • 处理工具执行
  • 使用stdio传输进行通信

文件

  • server-stdio-echo.py - 使用 https://pypi.org/project/mcp/ 实现的MCP服务器

它是如何工作的

服务器提供了一个工具:

  • 回声接收一条消息字符串并将其原样返回

安装

  1. 创建一个虚拟环境:
python3 -m venv .venv
source .venv/bin/activate  # On Windows: venv\Scripts\activate
  1. 安装依赖项:
pip install -r requirements.txt

通过标准输入输出运行服务器

MCP服务器使用stdio(标准输入/输出)进行通信,因此它被设计为由MCP客户端运行,而不是直接运行:

python 01-simple-server/server-stdio-echo.py

然而,直接运行它会等待输入。它旨在与客户端(见示例2)或MCP主机(如Claude Desktop或Cline)一起使用。或者也可以使用MCP检查器。

cntrl-c

使用MCP检测员进行测试

brew install mcp-inspector
mcp-inspector python 01-simple-server/server-stdio-echo.py
mcp-inspector python 01-simple-server/server-stdio-math.py

示例2:最简单的MCP客户端

这是最基础的MCP(模型上下文协议)客户端实现。它展示了如何连接到MCP服务器并与之进行交互。

这个例子所展示的内容

  • 使用stdio传输方式连接到MCP服务器
  • 初始化客户端会话
  • 列出服务器上可用的工具
  • 调用带有参数的工具
  • 处理工具响应

先决条件

您需要示例1服务器来运行此客户端。请确保服务器位于正确的相对路径中(../01-simple-server/server.py)。

运行客户端

python 02-simple-client/client-stdio-echo.py
python 02-simple-client/client-stdio-math.py
python 02-simple-client/client-stdio-math-divide-by-zero.py

预期的Echo输出

Connected to MCP server!

=== Listing Available Tools ===

Tool: echo
Description: Echoes back the input text
Input Schema: {'type': 'object', 'properties': {...}, 'required': ['message']}

==================================================

=== Calling the 'echo' Tool ===
Result: Echo: Hello from the MCP client!

==================================================

=== Calling 'echo' Again ===
Result: Echo: MCP is working!

示例3:使用FastMCP的HTTP MCP服务器

python 03-http-server-fastmcp/fastmcp-server-hello-world.py
python 03-http-server-fastmcp/fastmcp-server-math.py

示例4:资源

资源 是只读数据源:

  • 表示可检索的数据
  • 使用URI进行标识
  • 适用于:配置、文档编写、数据导出

工具 是可执行函数:

  • 执行操作或计算
  • 可以修改状态
  • 适用于:操作、转换、API调用

可用资源

静态资源

  1. 注://静态/欢迎

    • 纯文本欢迎信息
    • 总是返回相同的内容
  2. 注://静态/信息

    • JSON服务器信息
    • 包含时间戳(每次读取时都会变化)

动态资源(模板)

  1. 笔记://笔记/{id}
    • 通过ID访问备注
    • 可用ID: note1, note2
    • 示例: note://notes/note1

运行示例,客户端调用服务器

python 04-server-with-resources/mcp-client-resources.py
==================================================
AVAILABLE RESOURCES
==================================================

  📄 Welcome Note
     URI: note://static/welcome
     Type: text/plain
     Description: A static welcome message

  📄 Server Info
     URI: note://static/info
     Type: application/json
     Description: Information about this MCP server

==================================================
RESOURCE TEMPLATES
==================================================

  📋 Note by ID
     URI Pattern: note://notes/{id}
     Type: text/plain
     Description: Access a specific note. Available IDs: note1, note2

==================================================
READING: note://static/welcome
==================================================
Welcome to the MCP Resource Server!

This server demonstrates static and dynamic resources.

==================================================
READING: note://static/info
==================================================
{
  "name": "Resource Demo Server",
  "version": "1.0.0",
  "capabilities": [
    "static_resources",
    "resource_templates"
  ],
  "timestamp": "2025-10-09T18:05:14.764054"
}

==================================================
READING: note://notes/note1
==================================================
Title: Meeting Notes
Created: 2024-01-15

Discussed project timeline and milestones

==================================================
READING: note://notes/note2
==================================================
Title: Ideas
Created: 2024-01-16

New features to implement in Q2

==================================================
ALL TESTS COMPLETED SUCCESSFULLY
==================================================

示例5:资源与工具

python 05-complete-server/mcp-client-resources-tools.py

示例6:

暂时跳过

示例7:天气API封装器

mcp-inspector python 07-weather-api-server/server-stdio-weather-dot-gov.py
mcp-inspector python 07-weather-api-server/server-stdio-weather-open-meteo.py

FastMCP天气API封装器

python 07-weather-api-server/server-fastmcp-weather-dot-gov.py
mcp-inspector

示例8:自定义API的MCP封装

pip install -r 08-fastapi-mcp-wrapper/requirements.txt
python 08-fastapi-mcp-wrapper/fastapi_app.py

这是为了查看它是否能编译,没有输出结果

python 08-fastapi-mcp-wrapper/api-wrapper-stdio.py

多次按 Ctrl+C

mcp-inspector python 08-fastapi-mcp-wrapper/api-wrapper-stdio.py

FastMCP 版本

确保API已启动

python 08-fastapi-mcp-wrapper/fastapi_app.py

启动MCP服务器

python 08-fastapi-mcp-wrapper/api-wrapper-fastmcp.py
mcp-inspector

示例9:部署到Kubernetes

这个示例包含一个与MCP服务器交互的FastAPI端点。不涉及大型语言模型(LLM)。

cd 09-kubernetes-deployment
oc new-project mcp-servers-basic

或者

kubectl create namespace mcp-servers-basic
kubens mcp-servers-basic

“kubens”源自 brew install kubectx它会修改你的KUBECONFIG文件。

kubectl config view | grep -B 3 -A 3 "mcp-servers-basic"

~/.kube/config 

此脚本假设已在 quay.io 上创建了公共容器镜像,因此无需在 Kubernetes 侧设置 pull-secret。

./deploy.sh

你需要配置路由(如果使用原生 Kubernetes,则需配置入口)

export MCP_URL=https://$(oc get routes -l app=mcp-server -o jsonpath="{range .items[*]}{.status.ingress[0].host}{end}")/mcp
echo $MCP_URL
mcp-inspector

示例10:基本代理

python 10-basic-langgraph-agent/mcp-server-math/mcp-server.py

使用mcp-inspector进行测试

pip install -r 10-basic-langgraph-agent/requirements.txt
export OPENAI_API_KEY=sk-proj-ghs22s90wrow0-more-stuff
python 10-basic-langgraph-agent/my-langgraph-agent/langgraph_agent_add.py

示例11:通过FastAPI暴露的LangGraph Agent

export OPENAI_API_KEY=sk-proj-ghs22s90wrow0-more-stuff
pip install -r 11-agent-with-api/requirements.txt

这假设你也 pip install 根目录下的 requirements.txt 文件,你正在使用 python3 -m venv .venv

运行MCP服务器

python 11-agent-with-api/mcp-server-math/mcp-server.py
python 11-agent-with-api/my-l
python 11-agent-with-api/my-langgraph-agent/fastapi_wrapper_langgraph.py
curl http://localhost:8000/health
curl -X POST http://localhost:8000/add \
    -H "Content-Type: application/json" \
    -d '{"a": 2.0, "b": 3.0}'

你可以 .env.example .env 并将URL更改为MCP服务器以及FastAPI的端口

示例12:代理 + API + MCP服务器 + OpenShift

一个用于代理的Pod及其API 用于MCP服务器的Pod

cd 12-agent-with-api-openshift
oc new-project agent-with-mcp

使用 podman 并且使用 quay.io 而不是 docker 以及 docker.io。选择你最喜欢的,并确保你可以构建并推送镜像到一个已知的位置。注意:quay.io 默认将你的容器镜像标记为私有,你可能需要深入设置将其设为公开。参见 ./images/quayio-private-to-public.png 为了截个图。

brew install podman 
podman machine start

podman login quay.io

MCP Server 作为一个 Pod

podman build --arch amd64 --os linux -t quay.io/burrsutter/mcp-server-math:1.0.0 ./mcp-server-math
podman push quay.io/burrsutter/mcp-server-math:1.0.0

测试MCP服务器的容器镜像

podman run \
  -p 9005:9005 \
  quay.io/burrsutter/mcp-server-math:1.0.0

测试与(某设备/系统)的连接性 curl

curl -N -H "Accept: text/event-stream" http://localhost:9005/mcp

你收到的错误信息是“缺少会话ID”而不是“连接被拒绝”,这表明服务器正在运行并且有响应!这个错误是预料之中的,因为可流式传输的HTTP MCP需要建立会话。

它可能会以 curl: (7) Failed to connect to localhost port 9005 after 0 ms: Couldn't connect to server 在这种情况下,curl 没有找到在端口 9005 上运行的服务

测试与(某设备/系统)的连接性 mcp-inspector

mcp-inspector

使用 Ctrl-C 来终止 Podman 容器

podman ps
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

部署到 Kubernetes/OpenShift。您应该处于 agent-with-mcp 上下文中。您可以使用以下命令来检查: oc project 或者 kubectx 命令。

kubectl apply -f mcp-server-math-kubernetes/mcp-server-deployment.yaml
kubectl apply -f mcp-server-math-kubernetes/mcp-server-service.yaml

如果使用OpenShift,请使用路由。如果使用原生的Kubernetes,请向系统管理员询问如何配置入口(ingress)

oc get pods
kubectl apply -f mcp-server-math-kubernetes/mcp-server-route.yaml
export MCP_URL=https://$(oc get routes -l app=mcp-server -o jsonpath="{range .items[*]}{.status.ingress[0].host}{end}")/mcp
echo $MCP_URL

注:该 https 开始和 mcp 结束

与……一起测试 mcp-inspector 确认你有网络连接。

注:您可能不希望您的MCP服务器(尤其是像现在这样没有安全认证/授权的服务器)对外公开访问。

带有API作为插件的代理

podman build --arch amd64 --os linux -t quay.io/burrsutter/my-langgraph-agent:1.0.0 ./my-langgraph-agent
podman push quay.io/burrsutter/my-langgraph-agent:1.0.0

作为本地容器进行测试时,首先确保你正在运行mcp服务器

podman run -p 9005:9005 quay.io/burrsutter/mcp-server-math:1.0.0
podman run -p 8000:8000 \
    -e MCP_SERVER_URL=http://host.containers.internal:9005/mcp \
    -e OPENAI_API_KEY=$OPENAI_API_KEY \
    quay.io/burrsutter/my-langgraph-agent:1.0.0

通过测试 curl

curl -X POST http://localhost:8000/add \
    -H "Content-Type: application/json" \
    -d '{"a": 2.0, "b": 3.0}'

并且

curl -sS -X POST http://localhost:8000/add \
    -H "Content-Type: application/json" \
    -d '{
      "a": 42.5,
      "b": 57.5
    }' | jq
{
  "result": 100.0,
  "query": "Use the add tool to add 42.5 and 57.5",
  "agent_response": "The result of adding 42.5 and 57.5 is 100.0."
}

部署到 Kubernetes/OpenShift。您应该处于 agent-with-mcp 上下文中。您可以使用以下命令来检查这一点: oc project 或者 kubectx 命令。

使用相应的密钥更新 openai-secret.yaml 文件。

apiVersion: v1
kind: Secret
metadata:
  name: openai-secret
type: Opaque
stringData:
  api-key: "sk-proj-g2n-blah-blah"
kubectl apply -f my-langgraph-agent-kubernetes/openai-secret.yaml
kubectl apply -f my-langgraph-agent-kubernetes/fastapi-langgraph-deployment.yaml

这个(或:该) health 终端还会检查MCP服务器是否可用,这意味着在尝试建立连接时,可能会遇到崩溃循环/错误。

kubectl get pods
NAME                                             READY   STATUS    RESTARTS   AGE
mcp-server-deployment-58b48b8fd4-77dk9           1/1     Running   0          47m
my-langgraph-agent-deployment-86cccbc894-64d6s   1/1     Running   0          3m47s

寻找两个重启次数为0的快乐节点(或“正常运行的节点”)

kubectl apply -f my-langgraph-agent-kubernetes/fastapi-langgraph-service.yaml
kubectl get services
NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
mcp-server-service           ClusterIP   172.30.117.54   <none>        9005/TCP   47m
my-langgraph-agent-service   ClusterIP   172.30.139.88   <none>        8000/TCP   3s

如果使用OpenShift,请使用路由。如果使用原生Kubernetes,请向您的系统管理员询问如何配置入口(ingress)

kubectl apply -f my-langgraph-agent-kubernetes/fastapi-langgraph-route.yaml
kubectl get routes
export AGENT_URL=https://$(oc get routes -l app=my-langgraph-agent -o jsonpath="{range .items[*]}{.status.ingress[0].host}{end}")
echo $AGENT_URL
curl -X POST $AGENT_URL/add \
    -H "Content-Type: application/json" \
    -d '{"a": 2.0, "b": 3.0}'
curl -sS -X POST $AGENT_URL/add \
    -H "Content-Type: application/json" \
    -d '{
      "a": 42.5,
      "b": 57.5
    }' | jq
{
  "result": 100.0,
  "query": "Use the add tool to add 42.5 and 57.5",
  "agent_response": "The result of adding 42.5 and 57.5 is 100.0."
}

如果你正在监控Pod日志,你会看到类似这样的内容:

mcp-server-deployment-58b48b8fd4-77dk9 mcp-server Add: 42.5 + 57.5 = 100.0