使用说明
MoodMNKY MCP服务器堆栈
A. 第一原理 在Docker中运行、公开和集成多个MCP服务器的指南——通过服务器发送事件(SSE)为OpenAI代理SDK和其他客户端实现无缝访问。
目录
引言
这 MoodMNKY MCP服务器堆栈 是一个独立的存储库,可以编排各种各样的 模型上下文协议(MCP) 服务器——全部通过Docker容器化——在一个方便的 docker-compose.yml此堆栈支持:
- 快速部署 许多提供工具的MCP服务器(例如,Notion、Sequential Thinking、Brave Search、Tavily、Firecrawl、Fetch、GitHub、Supabase Dev、Context7、YouTube Transcript、通过Redis的内存等)。
- 统一配置 通过单一
.env包含所有主机端口绑定、API密钥和路径的文件。 - 开箱即用的集成 为了 OpenAI代理SDK (通过苏格兰和南方能源公司)和其他具有苏格兰和南方电力公司能力的客户。
- 可选曝光 使用 Cloudflare 隧道--保护防火墙安全,同时提供安全的外部访问。
此README需要一个 第一原则方法:它解释了每个步骤背后的“为什么”(而不仅仅是“如何”),这样不熟悉MCP、SSE、Docker或Cloudflare Tunnels的开发人员仍然可以准确地了解正在发生的事情、为什么它很重要,以及如何使其适应未来的需求。
MCP和SSE的第一原理
什么是MCP?
- MCP(模型上下文协议) 是一个允许人工智能的开源规范 代理 (例如,GPT-4驱动的助手)调用外部“工具”服务。
- 每个MCP服务器发布一组 工具签名 (名称、参数、描述)通过HTTP端点(通常
/tools). - 当代理需要“调用”工具时,它会发送一个JSON编码的POST到
/call,MCP服务器执行该工具(例如,获取网页、查询数据库、运行代码)并将结果流式传输回来。
关键利益:
- 关注点分离代理人专注于计划和推理;MCP服务器处理专门的任务。
- 语言诊断工具:MCP服务器可以用任何语言(Node、Python、Go等)编写,只要它们讲MCP规范。
- 可扩展性:只需将新的MCP服务器添加到堆栈中即可添加新工具;代理在运行时发现它们。
为什么选择SSE?
-
SSE(服务器发送的事件) 是一种基于HTTP的单向流媒体协议,服务器可以通过持久连接将JSON事件推送到客户端。
-
在MCP环境中,SSE用于两个阶段:
- 工具发现(列表):代理向发送GET
http://<mcp-url>/tools并在SSE流上监听描述每个可用工具的JSON。 - 刀具调用(CALL):代理向发送POST
http://<mcp-url>/call使用JSON参数。MCP服务器处理请求,然后通过现有的SSE连接将结果流式传输回来。
- 工具发现(列表):代理向发送GET
为什么SSE通过WebSocket或轮询?
- 简洁:SSE基于普通HTTP构建,因此它可以通过大多数代理、防火墙和负载均衡器工作,而无需特殊配置。
- 自动重新连接:本机重新连接语义处理瞬态网络光点。
- 低开销:没有WebSocket握手或协议帧,只有基于文本的事件。
- 单向:代理仍然通过正常的HTTP发送工具调用。SSE仅用于接收流式结果,这与MCP的模型非常吻合。
流媒体与SSE传输
-
一些MCP服务器实现了单独的“流式HTTP”传输(分块传输编码),而不是SSE。
-
SSE(此处受欢迎):
- 标准化事件格式(
data: { ... }). - 内置重新连接。
- 适用于大多数HTTP/2兼容环境。
- 标准化事件格式(
-
流媒体/分块HTTP:
- 对于极其轻量级的服务器来说更简单。
- 没有内置的“事件”框架——客户端必须手动解析块。
-
推荐:除非你有非常具体的原因,否则使用 SSE。此堆栈中的所有参考MCP服务器默认为SSE,确保行为一致。
存储库结构
moodmnky-mcp-server-stack/
├── README.md
├── docker-compose.yml # Orchestrates all MCP services
└── .env.example # Template for environment variables
README.md:(此文件)解释设置、用法、基本原理和教程。docker-compose.yml:声明18个服务(MCP服务器+Redis)。每个都引用环境变量以获取机密、主机端口绑定或路径。.env.example:列出所有必需的变量<PLACEHOLDER>价值观。复制到.env,用实际值替换占位符,永远不要提交实际值.env.
先决条件
Docker&Docker编写
-
Docker引擎 (20.10+)和 Docker Compose (v2+)安装在您的主机(Linux、macOS或Windows)上。
-
确认安装:
docker --version docker-compose --version
Cloudflare隧道(Cloudflared)
-
如果你打算 公开MCP服务器 (例如,远程托管的代理),安装 Cloudflare的
cloudflared在同一台主机上:-
下载 您的操作系统的最新版本 Cloudflare 隧道 文档。
-
安装 (例如,在Ubuntu上):
curl -LO https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared-linux-amd64.deb -
验证:
cloudflared version
-
域和DNS设置
- 你需要一个 注册域名 由Cloudflare管理(例如。,
example.com). - 对于您希望公开的每个MCP服务器,您将创建一个 别名 Cloudflare DNS仪表板中指向隧道自动配置主机名的记录(例如。,
mcp-tunnel.cfargotunnel.com).
OpenAI代理SDK
-
要集成这些MCP服务器,您需要 Python环境 随着 OpenAI代理SDK 安装:
pip install openai-agents -
代理将通过以下方式在代码中引用MCP端点(SSE)
MCPServerSse.
环境变量
.env.example
下面是完整的 .env.example 文件包含 占位符值. 不要承诺 名为的文件 .env。请将此复制到 .env 并替换每个占位符(<...>)使用您的实际密钥、主机端口和路径。
###############################################
# Rename this to ".env" and fill in your values
###############################################
###############################################
# 1. Notion MCP Server
###############################################
NOTION_MCP_HEADERS={"Authorization":"Bearer <YOUR_NOTION_PAT>","Notion-Version":"2022-06-28"}
NOTION_HOST_PORT=<YOUR_NOTION_HOST_PORT> # e.g., 8100
###############################################
# 2. 21st-Dev Magic MCP Server
###############################################
MAGIC_API_KEY=<YOUR_MAGIC_API_KEY>
MAGIC_HOST_PORT=<YOUR_MAGIC_HOST_PORT> # e.g., 8101
###############################################
# 3. Filesystem MCP Server
###############################################
FILESYSTEM_HOST_PATH=<ABSOLUTE_PATH_TO_SHARE> # e.g., /home/ubuntu/new-wave-protocol
FILESYSTEM_HOST_PORT=<YOUR_FILESYSTEM_HOST_PORT> # e.g., 8102
###############################################
# 4. Discord MCP Server
###############################################
DISCORD_TOKEN=<YOUR_DISCORD_TOKEN>
DISCORD_BOT_PERMISSIONS=<YOUR_DISCORD_BOT_PERMISSIONS>
DISCORD_HOST_PORT=<YOUR_DISCORD_HOST_PORT> # e.g., 8103
###############################################
# 5. Sequential Thinking MCP Server
###############################################
SEQUENTIAL_THINKING_HOST_PORT=<YOUR_SEQUENTIAL_THINKING_HOST_PORT> # e.g., 8104
###############################################
# 6. Brave Search MCP Server
###############################################
BRAVE_API_KEY=<YOUR_BRAVE_API_KEY>
BRAVE_SEARCH_HOST_PORT=<YOUR_BRAVE_SEARCH_HOST_PORT> # e.g., 8105
###############################################
# 7. Tavily Search MCP Server
###############################################
TAVILY_API_KEY=<YOUR_TAVILY_API_KEY>
TAVILY_HOST_PORT=<YOUR_TAVILY_HOST_PORT> # e.g., 8106
###############################################
# 8. Firecrawl MCP Server
###############################################
FIRECRAWL_API_URL=<YOUR_FIRECRAWL_API_URL> # e.g., https://api.firecrawl.dev/v1
FIRECRAWL_RETRY_MAX_ATTEMPTS=<YOUR_FIRECRAWL_RETRY_MAX_ATTEMPTS> # e.g., 5
FIRECRAWL_RETRY_INITIAL_DELAY=<YOUR_FIRECRAWL_RETRY_INITIAL_DELAY> # e.g., 2000
FIRECRAWL_RETRY_MAX_DELAY=<YOUR_FIRECRAWL_RETRY_MAX_DELAY> # e.g., 30000
FIRECRAWL_RETRY_BACKOFF_FACTOR=<YOUR_FIRECRAWL_RETRY_BACKOFF_FACTOR> # e.g., 3
FIRECRAWL_CREDIT_WARNING_THRESHOLD=<YOUR_FIRECRAWL_CREDIT_WARNING_THRESHOLD> # e.g., 2000
FIRECRAWL_CREDIT_CRITICAL_THRESHOLD=<YOUR_FIRECRAWL_CREDIT_CRITICAL_THRESHOLD> # e.g., 500
FIRECRAWL_API_KEY=<YOUR_FIRECRAWL_API_KEY>
FIRECRAWL_HOST_PORT=<YOUR_FIRECRAWL_HOST_PORT> # e.g., 8107
###############################################
# 9. Fetch MCP Server
###############################################
FETCH_HOST_PORT=<YOUR_FETCH_HOST_PORT> # e.g., 8108
###############################################
# 10. Playwright MCP Server
###############################################
PLAYWRIGHT_HOST_PORT=<YOUR_PLAYWRIGHT_HOST_PORT> # e.g., 8109
###############################################
# 11. GitHub MCP Server
###############################################
GITHUB_PERSONAL_ACCESS_TOKEN=<YOUR_GITHUB_PERSONAL_ACCESS_TOKEN>
GITHUB_HOST_PORT=<YOUR_GITHUB_HOST_PORT> # e.g., 8110
###############################################
# 12. Desktop Commander MCP Server
###############################################
DESKTOP_COMMANDER_HOST_PORT=<YOUR_DESKTOP_COMMANDER_HOST_PORT> # e.g., 8111
###############################################
# 13. Supabase-Dev (Postgres MCP) Server
###############################################
SUPABASE_DEV_CONN=<YOUR_SUPABASE_DEV_CONNECTION_URL> # e.g., postgresql://postgres:postgres@127.0.0.1:54322/postgres
SUPABASE_DEV_HOST_PORT=<YOUR_SUPABASE_DEV_HOST_PORT> # e.g., 8112
###############################################
# 14. Context7 MCP Server
###############################################
CONTEXT7_HOST_PORT=<YOUR_CONTEXT7_HOST_PORT> # e.g., 8113
###############################################
# 15. YouTube Transcript MCP Server
###############################################
YOUTUBE_TRANSCRIPT_HOST_PORT=<YOUR_YOUTUBE_TRANSCRIPT_HOST_PORT> # e.g., 8114
###############################################
# 16. Redis (for Memory MCP)
###############################################
REDIS_HOST_PORT=<YOUR_REDIS_HOST_PORT> # e.g., 6379
###############################################
# 17. Memory MCP Server
###############################################
MEMORY_HOST_PORT=<YOUR_MEMORY_HOST_PORT> # e.g., 8115
###############################################
# 18. @magicuidesign/mcp MCP Server
###############################################
MAGICUIDESIGN_HOST_PORT=<YOUR_MAGICUIDESIGN_HOST_PORT> # e.g., 8116
备注:唯一进入你真实生活的“生产就绪”价值观
.env是:
- API密钥和令牌 (Notion PAT、Brave、Tavily、Firecrawl、GitHub、Discord等)。
- 绝对路径 为了
FILESYSTEM_HOST_PATH(例如。,/home/moodmnky/new-wave-protocol).- 主机端口 是任意的,但不得与计算机上的其他服务冲突。
Docker Compose入门
1.克隆存储库
git clone https://github.com/<your-org>/moodmnky-mcp-server-stack.git
cd moodmnky-mcp-server-stack
2.复制并编辑 .env
cp .env.example .env
notepad .env
- 更换每个
<PLACEHOLDER>使用您的实际值(API键、主机端口、路径)。 - 保持所有其他线路完整,然后执行 不 承诺结果
.envGit。
3.启动所有MCP服务器
docker-compose up -d
-
Docker Compose将:
- 拉取每个图像(例如。,
mcp/notion:latest,node:18-alpine,redis:7-alpine). - 创建并启动18个容器,将每个容器端口映射到中设置的主机端口
.env. - 将您的主机目录装载到
filesystem集装箱在/mnt/shared.
- 拉取每个图像(例如。,
4.验证本地 /tools 端点
打开一个新的PowerShell窗口或选项卡并运行SSE风格 curl 对于每项服务:
# Notion MCP
curl.exe -N http://localhost:8100/tools
# Magic MCP
curl.exe -N http://localhost:8101/tools
# Filesystem MCP
curl.exe -N http://localhost:8102/tools
# Discord MCP
curl.exe -N http://localhost:8103/tools
# Sequential Thinking MCP
curl.exe -N http://localhost:8104/tools
# Brave Search MCP
curl.exe -N http://localhost:8105/tools
# Tavily MCP
curl.exe -N http://localhost:8106/tools
# Firecrawl MCP
curl.exe -N http://localhost:8107/tools
# Fetch MCP
curl.exe -N http://localhost:8108/tools
# Playwright MCP
curl.exe -N http://localhost:8109/tools
# GitHub MCP
curl.exe -N http://localhost:8110/tools
# Desktop Commander MCP
curl.exe -N http://localhost:8111/tools
# Supabase-Dev (Postgres MCP)
curl.exe -N http://localhost:8112/tools
# Context7 MCP
curl.exe -N http://localhost:8113/tools
# YouTube Transcript MCP
curl.exe -N http://localhost:8114/tools
# Memory MCP (requires Redis)
curl.exe -N http://localhost:8115/tools
# @magicuidesign/mcp
curl.exe -N http://localhost:8116/tools
成功的回应是 无限SSE流 描述每个工具的JSON对象(名称、参数、描述)。如果连接立即关闭,请仔细检查您的主机端口是否匹配,以及容器是否已打开。
通过Cloudflare隧道暴露MCP服务器
如果您希望从本地网络外部访问MCP端点,同时保持防火墙锁定,您可以使用 Cloudflare隧道(cloudflared)。本节将介绍一个典型的“每次服务隧道”设置。
为什么要使用隧道?
- 没有开放的入站端口:您永远不会暴露原始TCP/UDP——Cloudflare处理TLS和持久性。
- TLS终止:Cloudflare为您的域/子域提供证书。
- 自动重新连接:如果隧道下降,
cloudflared自动重新连接。 - 访问控制:可选择与Zero Trust集成,以限制谁可以访问您的MCP服务。
1.安装并验证 cloudflared
-
下载并安装 (例如Ubuntu Linux):
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared-linux-amd64.deb -
登录 (这将打开一个浏览器选项卡进行身份验证):
cloudflared tunnel login- 选择您的Cloudflare帐户,然后选择要在其中创建DNS记录的域(例如。,
mcp.example.com). - 此步骤创建
~/.cloudflared/cert.pem文件在您的主机上。
- 选择您的Cloudflare帐户,然后选择要在其中创建DNS记录的域(例如。,
2.创建命名隧道
cloudflared tunnel create mcp-tunnel
- 这将输出a 隧道ID (例如。,
abcd1234-ef56-7890-ghij-klmnopqrstuv). - 凭证文件(例如。,
~/.cloudflared/abcd1234-ef56-7890-ghij-klmnopqrstuv.json)是自动创建的。
3.配置DNS路由
对于每个MCP服务,我们将创建一个指向的Cloudflare DNS CNAME记录 <tunnel_id>.cfargotunnel.com子域名示例:
| MCP服务 | 本地端口 | 所需子域 |
|---|---|---|
| MCP概念 | 8100 | notion-mcp.example.com |
| 魔术MCP | 8101 | magic-mcp.example.com |
| 文件系统MCP | 8102 | filesystem-mcp.example.com |
| MCP不一致 | 8103 | discord-mcp.example.com |
| 顺序思维MCP | 8104 | sequential-mcp.example.com |
| 勇敢搜索MCP | 8105 | brave-mcp.example.com |
| 塔维利MCP | 8106 | tavily-mcp.example.com |
| 防火墙MCP | 8107 | firecrawl-mcp.example.com |
| 获取MCP | 8108 | fetch-mcp.example.com |
| 剧作家MCP | 8109 | playwright-mcp.example.com |
| GitHub MCP | 8110 | github-mcp.example.com |
| 桌面命令器MCP | 8111 | desktop-mcp.example.com |
| Supabase开发(Postgres MCP) | 8112 | supabase-mcp.example.com |
| 上下文7 MCP | 8113 | context7-mcp.example.com |
| YouTube转录MCP | 8114 | yt-transcript-mcp.example.com |
| 存储器MCP | 8115 | memory-mcp.example.com |
| @magicuidesign/mcp | 8116 | magicuidesign-mcp.example.com |
运行以下命令(替换 <tunnel-id> 使用您的实际隧道ID和相应的每个子域):
cloudflared tunnel route dns mcp-tunnel notion-mcp.example.com
cloudflared tunnel route dns mcp-tunnel magic-mcp.example.com
cloudflared tunnel route dns mcp-tunnel filesystem-mcp.example.com
cloudflared tunnel route dns mcp-tunnel discord-mcp.example.com
cloudflared tunnel route dns mcp-tunnel sequential-mcp.example.com
cloudflared tunnel route dns mcp-tunnel brave-mcp.example.com
cloudflared tunnel route dns mcp-tunnel tavily-mcp.example.com
cloudflared tunnel route dns mcp-tunnel firecrawl-mcp.example.com
cloudflared tunnel route dns mcp-tunnel fetch-mcp.example.com
cloudflared tunnel route dns mcp-tunnel playwright-mcp.example.com
cloudflared tunnel route dns mcp-tunnel github-mcp.example.com
cloudflared tunnel route dns mcp-tunnel desktop-mcp.example.com
cloudflared tunnel route dns mcp-tunnel supabase-mcp.example.com
cloudflared tunnel route dns mcp-tunnel context7-mcp.example.com
cloudflared tunnel route dns mcp-tunnel yt-transcript-mcp.example.com
cloudflared tunnel route dns mcp-tunnel memory-mcp.example.com
cloudflared tunnel route dns mcp-tunnel magicuidesign-mcp.example.com
备注:您必须首先创建相应的 别名 Cloudflare仪表板中的记录(DNS→ 添加记录→ 键入“CNAME”→ 名称=子域→ 目标=
<tunnel-id>.cfargotunnel.com).或者,Cloudflare可能会在您运行route dns命令。
4.创建 cloudflared 配置
在以下位置创建文件 ~/.cloudflared/config.yml 内容如下。替换 <tunnel-id> 使用您的实际隧道ID,并进行调整 hostname 与所选子域匹配的条目:
tunnel: <tunnel-id>
credentials-file: /home/<your-username>/.cloudflared/<tunnel-id>.json
ingress:
- hostname: notion-mcp.example.com
service: http://localhost:8100
- hostname: magic-mcp.example.com
service: http://localhost:8101
- hostname: filesystem-mcp.example.com
service: http://localhost:8102
- hostname: discord-mcp.example.com
service: http://localhost:8103
- hostname: sequential-mcp.example.com
service: http://localhost:8104
- hostname: brave-mcp.example.com
service: http://localhost:8105
- hostname: tavily-mcp.example.com
service: http://localhost:8106
- hostname: firecrawl-mcp.example.com
service: http://localhost:8107
- hostname: fetch-mcp.example.com
service: http://localhost:8108
- hostname: playwright-mcp.example.com
service: http://localhost:8109
- hostname: github-mcp.example.com
service: http://localhost:8110
- hostname: desktop-mcp.example.com
service: http://localhost:8111
- hostname: supabase-mcp.example.com
service: http://localhost:8112
- hostname: context7-mcp.example.com
service: http://localhost:8113
- hostname: yt-transcript-mcp.example.com
service: http://localhost:8114
- hostname: memory-mcp.example.com
service: http://localhost:8115
- hostname: magicuidesign-mcp.example.com
service: http://localhost:8116
# Fallback for any unmatched request
- service: http_status:404
5.跑步 cloudflared 作为系统服务
在Linux上(例如Ubuntu)
-
创建systemd单元文件 在
/etc/systemd/system/cloudflared.service:sudo tee /etc/systemd/system/cloudflared.service > /dev/null << 'EOF' [Unit] Description=Cloudflare Tunnel After=network.target [Service] Type=notify ExecStart=/usr/local/bin/cloudflared tunnel --config /home/<your-username>/.cloudflared/config.yml run Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target EOF -
重新加载系统d 和 启用/启动 服务:
sudo systemctl daemon-reload sudo systemctl enable cloudflared sudo systemctl start cloudflared sudo systemctl status cloudflared -
确保服务 “活动(运行)”。如果是这样,Cloudflare Tunnel现在正在将您的公共子域转发到localhost。
与OpenAI代理SDK集成
一旦您的MCP服务器在本地运行(并可选择通过Cloudflare隧道公开),您就可以连接 OpenAI代理 通过 MCPServerSse。下面是一个Python代码片段,演示如何连接多个MCP端点:
import os
import asyncio
from agents import Agent, Runner
from agents.mcp.server import MCPServerSse
# 1. Read MCP SSE URLs (either localhost or public via Cloudflare)
NOTION_MCP_URL = os.getenv("NOTION_SSE_URL", "http://localhost:8100")
MAGIC_MCP_URL = os.getenv("MAGIC_SSE_URL", "http://localhost:8101")
FILESYSTEM_MCP_URL = os.getenv("FILESYSTEM_SSE_URL", "http://localhost:8102")
DISCORD_MCP_URL = os.getenv("DISCORD_SSE_URL", "http://localhost:8103")
SEQUENTIAL_MCP_URL = os.getenv("SEQUENTIAL_SSE_URL", "http://localhost:8104")
BRAVE_MCP_URL = os.getenv("BRAVE_SSE_URL", "http://localhost:8105")
TAVILY_MCP_URL = os.getenv("TAVILY_SSE_URL", "http://localhost:8106")
FIRECRAWL_MCP_URL = os.getenv("FIRECRAWL_SSE_URL", "http://localhost:8107")
FETCH_MCP_URL = os.getenv("FETCH_SSE_URL", "http://localhost:8108")
PLAYWRIGHT_MCP_URL = os.getenv("PLAYWRIGHT_SSE_URL", "http://localhost:8109")
GITHUB_MCP_URL = os.getenv("GITHUB_SSE_URL", "http://localhost:8110")
DESKTOP_MCP_URL = os.getenv("DESKTOP_SSE_URL", "http://localhost:8111")
SUPABASE_MCP_URL = os.getenv("SUPABASE_SSE_URL", "http://localhost:8112")
CONTEXT7_MCP_URL = os.getenv("CONTEXT7_SSE_URL", "http://localhost:8113")
YOUTUBE_MCP_URL = os.getenv("YOUTUBE_SSE_URL", "http://localhost:8114")
MEMORY_MCP_URL = os.getenv("MEMORY_SSE_URL", "http://localhost:8115")
MAGICUIDESIGN_MCP_URL= os.getenv("MAGICUIDESIGN_SSE_URL", "http://localhost:8116")
def make_sse_server(url: str, name: str):
return MCPServerSse(params={"url": url}, name=name)
async def main():
# 2. Instantiate MCP servers
mcp_servers = [
make_sse_server(NOTION_MCP_URL, "NotionMCP"),
make_sse_server(MAGIC_MCP_URL, "MagicMCP"),
make_sse_server(FILESYSTEM_MCP_URL, "FileMCP"),
make_sse_server(DISCORD_MCP_URL, "DiscordMCP"),
make_sse_server(SEQUENTIAL_MCP_URL, "SequentialMCP"),
make_sse_server(BRAVE_MCP_URL, "BraveMCP"),
make_sse_server(TAVILY_MCP_URL, "TavilyMCP"),
make_sse_server(FIRECRAWL_MCP_URL, "FirecrawlMCP"),
make_sse_server(FETCH_MCP_URL, "FetchMCP"),
make_sse_server(PLAYWRIGHT_MCP_URL, "PlaywrightMCP"),
make_sse_server(GITHUB_MCP_URL, "GitHubMCP"),
make_sse_server(DESKTOP_MCP_URL, "DesktopMCP"),
make_sse_server(SUPABASE_MCP_URL, "SupabaseMCP"),
make_sse_server(CONTEXT7_MCP_URL, "Context7MCP"),
make_sse_server(YOUTUBE_MCP_URL, "YouTubeMCP"),
make_sse_server(MEMORY_MCP_URL, "MemoryMCP"),
make_sse_server(MAGICUIDESIGN_MCP_URL,"MagicUIDesignMCP"),
]
# 3. Build an Agent with multiple tool sources
agent = Agent(
name="MoodMNKYUnifiedAgent",
instructions=(
"You have access to multiple MCP servers over SSE. "
"Use NotionMCP to query Notion data, FileMCP to read files, "
"MemoryMCP to store/retrieve memory, etc."
),
tools=[], # No built-in local tools
mcp_servers=mcp_servers
)
# 4. Run a simple example prompt
runner = Runner(agent)
response = await runner.complete(
"List all Notion pages, then fetch the contents of README.md from the filesystem."
)
print(response)
if __name__ == "__main__":
asyncio.run(main())
- 环境变量:您可以覆盖每个
*_SSE_URL指向a Cloudflare‐隧道 URL(例如。,https://notion-mcp.example.com). - MCPServerSse 服务器:在引擎盖下,
MCPServerSse.connect()将打开一个持久的HTTP GEThttp://<url>/tools,解析JSON流,并公开每个工具。当代理人这样做时CALL <tool>,SDK POST到http://<url>/call,服务器将结果流式传输回来。
SSE与流式HTTP:权衡
-
SSE(服务器发送事件)
-
协议:HTTP GET到
/tools返回连续的流data: { ... }文本/事件流格式的事件。 -
优点:
- 本机自动重新连接语义。
- 通过HTTP/2和大多数代理/负载均衡器工作。
- 清晰的“事件”框架。
-
缺点:
- 仅服务器→ 客户。代理必须使用常规POST发送工具调用。
-
-
流式HTTP(分块响应)
-
协议:客户端发送GET或POST;服务器以分块传输编码(无显式
event:框架)。 -
优点:
- 在某些语言中实现稍微简单一些。
-
缺点:
- 客户端必须手动解析原始块。
- 没有内置的“重新连接”语义。
-
为什么选择苏格兰和南方能源公司 对于大多数MCP服务器:
- 跨参考实现的统一、记录良好的格式。
- 中断后自动处理重新连接。
- 代理SDK(例如OpenAI代理SDK)原生支持SSE(通过
MCPServerSse).
故障排除和最佳实践
1.健康检查
为中的每个服务添加健康检查 docker-compose.yml 为了验证这一点 /tools 返回200状态(SSE握手成功)。例子:
services:
new-wave-protocol-notion:
# … existing config …
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:${NOTION_HOST_PORT}/tools"]
interval: 30s
timeout: 5s
retries: 3
对其他关键服务重复此操作。
2.港口冲突
- 确保 每
${*_HOST_PORT}在你的.env是唯一的,不被其他本地服务使用。 - 使用
ss -tulpn(Linux)或netstat -anb(Windows)在分配之前验证端口可用性。
3.保密
-
永不承诺 你的真实
.env文件。添加到.gitignore(提供)。 -
对于 生产,考虑:
- Docker的秘密:将API密钥存储在Docker的秘密管理中,而不是以纯文本存储。
- 保险库解决方案:HashiCorp Vault、AWS Secrets Manager或Azure Key Vault,用于在运行时进行动态注入。
4.Redis持久化
-
这
redis服务使用命名卷redis-data为了耐用性。要备份或迁移,请执行以下操作:- 备份:
docker run --rm -v redis-data:/data -v $(pwd):/backup alpine:latest sh -c "cd /data && tar czf /backup/redis-backup.tar.gz ." - 恢复:停止Redis,替换
redis-data使用提取的数据,然后重新启动。
- 备份:
5.更新MCP版本
-
默认情况下,
docker-compose.yml用途mcp/<service>:latest为了保持稳定性,请固定在特定的标签或摘要上:image: mcp/notion:0.2.1 -
监控上游MCP仓库的新版本:
当新版本到来时,更新 docker-compose.yml 相应地,在本地测试,然后在Git中升级版本。
扩展MCP堆栈
像 新的MCP服务器 或 工具实现 emerge,您可以通过以下方式扩展此堆栈:
- 添加新服务 在……里面
docker-compose.yml(或创建一个单独的Dockerfile如有必要)。 - 添加匹配变量 向
.env.example(然后发送到您当地的.env). - 测试 当地与
curl -N http://localhost:<NEW_PORT>/tools. - 添加DNS路由 &
cloudflared如果你需要公开曝光,请进行配置。
示例:添加“Slack MCP服务器”
-
附加
docker-compose.yml:slack-mcp: image: mcp/slack:latest container_name: mcp-slack restart: unless-stopped ports: - "${SLACK_HOST_PORT}:8080" environment: SLACK_BOT_TOKEN: "${SLACK_BOT_TOKEN}" SLACK_SIGNING_SECRET: "${SLACK_SIGNING_SECRET}" -
更新
.env.example:############################################### # 19. Slack MCP Server ############################################### SLACK_BOT_TOKEN=<YOUR_SLACK_BOT_TOKEN> SLACK_SIGNING_SECRET=<YOUR_SLACK_SIGNING_SECRET> SLACK_HOST_PORT=<YOUR_SLACK_HOST_PORT> # e.g., 8117 -
拉动更改 (如果你之前克隆过)和 延伸 你的
.env因此。
许可证
此存储库分布在 MIT许可证。参见 许可证 了解详情。
结论
遵循以下步骤 第一原理 README,您将:
- 理解 为什么 每个组件(MCP、SSE、Docker、Cloudflare隧道)都存在。
- 知道 如何 配置、启动和公开MCP服务器。
- 能够将任何支持SSE的客户端(OpenAI代理SDK、Node/Python脚本等)连接到丰富的工具生态系统。
- 为添加未来的MCP服务器和集成提供清晰、可扩展的基础。
欢迎来到一个完全容器化、安全和可扩展的MCP服务器世界——在这里,您的代理可以调用他们需要的任何“工具”,您可以完全控制您的环境。
