MCP博客

当前版本: 0.2.0 --设置在 pyproject.toml ([project].version)以及 blogging_mcp.__version__.在这着陆之后 main,Docker Hub将发布 alsaheem/blogging-mcp:0.2.0, alsaheem/blogging-mcp:0.2.0-,并更新 alsaheem/blogging-mcp:latest.
文档和快速设置:
快速启动(托管MCP)
使用 远程 服务器——没有克隆,没有Python,没有本地进程。您只需要dev.to和Hashnode凭据以及客户端配置。
端点: https://blogging-mcp.adebisiayomide.com/mcp
对您的凭据进行编码
HTTP客户端发送三个标头。值必须为 标准Base64 (UTF-8,然后编码)。服务器对每个请求进行Base64解码;如果解码失败,则尝试原始字符串,以便纯文本仍然可以工作。
echo -n 'paste-your-real-devto-key-here' | base64
echo -n 'paste-your-hashnode-token-here' | base64
echo -n 'yourblog.hashnode.dev' | base64使用 echo -n 因此,您无需添加尾随换行符。
| 从哪里获取值 | 标头名称 |
|---|---|
| dev.to API密钥 → DEV社区API密钥 | X-DEVTO-API-KEY |
| 哈希节点PAT | X-HASHNODE-TOKEN |
您的博客主机,例如。 username.hashnode.dev | X-HASHNODE-PUBLICATION-HOST |
粘贴每个 单行 Base64输出到下面的匹配字段。片段使用 虚拟的 Base64——用你的替换。
安全: 做 不 将真实代币提交给git。 mcp.json 和 claude_desktop_config.json 秘密应该只留在你的机器上。
一个 Authorization: Bearer … 标题是 不 除非您添加一个将其映射到这三个值的代理,否则对于此服务器来说已经足够了。
光标(远程)
文件: ~/.cursor/mcp.json (macOS/Linux)或 %USERPROFILE%\.cursor\mcp.json (Windows)。您还可以从以下位置进行编辑 光标设置→ MCP.
{
"mcpServers": {
"blogging-mcp": {
"url": "https://blogging-mcp.adebisiayomide.com/mcp",
"headers": {
"X-DEVTO-API-KEY": "ZXhhbXBsZS1kZXZ0by1rZXktcGxhY2Vob2xkZXI=",
"X-HASHNODE-TOKEN": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAx",
"X-HASHNODE-PUBLICATION-HOST": "ZXhhbXBsZWJsb2cuaGFzaG5vZGUuZGV2"
}
}
}
}完全地 退出Cursor 并重新打开,以便MCP重新加载。
示例文件: mcp.cursor.json.remote.example.
克劳德桌面(远程)
克劳德知道 不 支持Cursor的 "url" + "headers" 块。使用 mcp-remote (节点18+, npx)要连接到 相同的HTTPS URL. 不要 通过 --allow-http 对于此托管URL。
文件:
| 操作系统 | 路径 |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| 窗户 | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
合并 "mcpServers" 使用任何现有密钥(例如。 "preferences").
{
"mcpServers": {
"blogging-mcp": {
"command": "npx",
"args": [
"mcp-remote",
"https://blogging-mcp.adebisiayomide.com/mcp",
"--header",
"X-DEVTO-API-KEY: ZXhhbXBsZS1kZXZ0by1rZXktcGxhY2Vob2xkZXI=",
"--header",
"X-HASHNODE-TOKEN: MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAx",
"--header",
"X-HASHNODE-PUBLICATION-HOST: ZXhhbXBsZWJsb2cuaGFzaG5vZGUuZGV2"
]
}
}
}如果 npx 首次运行时提示安装,使用 "args": ["-y", "mcp-remote", ...] 而不是 "mcp-remote" 作为第一个arg。
完全地 退出克劳德桌面 并重新开放。 克劳德网络/连接器 通常无法发送这些标头;使用 桌面+ mcp-remote (或克隆的stdio——见下文)。
示例文件: mcp.claude.json.remote.example.
______________________________________________________________________
本地和自托管(可选)
如果需要离线使用、自定义URL或开发,请在您的计算机或您自己的主机上运行MCP。
光标(本地URL)
启动服务器(运行服务器),然后点 mcp.json 在 http://127.0.0.1:8765/mcp 具有相同的三个Base64标头。例子: mcp.cursor.json.local.example.
克劳德桌面(本地+ mcp-remote)
带着一个 本地 HTTP服务器必须允许非TLS HTTP:
{
"mcpServers": {
"blogging-mcp": {
"command": "npx",
"args": [
"mcp-remote",
"http://127.0.0.1:8765/mcp",
"--allow-http",
"--header",
"X-DEVTO-API-KEY: ZXhhbXBsZS1kZXZ0by1rZXktcGxhY2Vob2xkZXI=",
"--header",
"X-HASHNODE-TOKEN: MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAx",
"--header",
"X-HASHNODE-PUBLICATION-HOST: ZXhhbXBsZWJsb2cuaGFzaG5vZGUuZGV2"
]
}
}
}例子: mcp.claude.json.local.example.
从源运行(stdio)
克隆仓库并使用 标准 朴素地 env (无Base64)。替换 cwd 使用克隆路径:
{
"mcpServers": {
"blogging-mcp": {
"command": "uv",
"args": ["run", "python", "-m", "blogging_mcp"],
"cwd": "/absolute/path/to/blogging-mcp",
"env": {
"DEVTO_API_KEY": "your-devto-api-key-here",
"HASHNODE_TOKEN": "your-hashnode-personal-access-token-here",
"HASHNODE_PUBLICATION_HOST": "yourblog.hashnode.dev"
}
}
}
}安全: 如果任何人都可以访问没有身份验证的公共HTTP MCP URL,则可能会被滥用。此项目不在HTTP侦听器上提供OAuth;需要时在自托管部署前使用auth。
______________________________________________________________________
需求
- Python 3.11+
- 紫外线
设置(本地开发)
克隆存储库并安装依赖项:
cd blogging-mcp
uv sync --all-groups复制 .env.example 到 .env 并设置 DEVTO_API_KEY, HASHNODE_TOKEN,以及 HASHNODE_PUBLICATION_HOST 你真正的价值观(与 mcp.json 标头 如果你使用HTTP——永远不要提交 .env).
谁配置什么: 每个 用户 使用自己的dev.to和Hashnode凭据。对于HTTP MCP,输入 Base64编码 值在 mcp.json headers;对于本地服务器/stdio,请使用 .env 或 env 在客户端配置中(纯值)。不要将真正的代币提交给git。
运行服务器
stdio(默认) --Cursor或Claude Desktop生成进程并通过stdin/stdout进行对话:
uv run python -m blogging_mcpHTTP(流式HTTP) --对于光标 统一资源定位符 模式或其他远程客户端。FastMCP为MCP端点提供服务 /mcp (默认)。
MCP_TRANSPORT=http MCP_HTTP_PORT=8765 uv run python -m blogging_mcp当进程在VM或Docker中运行时,绑定到所有接口(这样你的笔记本电脑就可以访问它):
MCP_TRANSPORT=http MCP_HTTP_HOST=0.0.0.0 MCP_HTTP_PORT=8765 uv run python -m blogging_mcp环境:
MCP_TRANSPORT—stdio(默认)或httpMCP_HTTP_HOST--绑定地址(默认127.0.0.1)MCP_HTTP_PORT--使用时的端口http(默认值8765)MCP_HTTP_TIMEOUT--dev.to/Hashnode调用的HTTP客户端超时时间(秒)(默认值30)
流式HTTP行为(JSON vs SSE,无状态模式)由以下因素控制 FastMCP --查看其文档和环境变量,例如 FASTMCP_JSON_RESPONSE / FASTMCP_STATELESS_HTTP 如果你需要调整交通。
或者:
uv run fastmcp run src/blogging_mcp/server.py:mcpHTTP部署(服务器、Docker、反向代理)
这与FastMCP指南中的模式相匹配: HTTP部署.
1.直接HTTP(内置Uvicorn) --相同的想法 mcp.run(transport="http", host="0.0.0.0", port=8000) 在文件中;这个项目把它连接起来 MCP_TRANSPORT 和 MCP_HTTP_*:
MCP_TRANSPORT=http MCP_HTTP_HOST=0.0.0.0 MCP_HTTP_PORT=8765 uv run python -m blogging_mcp客户端使用流式HTTP URL http://: /mcp (默认路径;请参阅FastMCP的 自定义路径 如果你需要另一个)。
2.Asgi应用程序+uvicorn --相同的想法 app = mcp.http_app() 在文件中;该应用程序显示为 blogging_mcp.asgi:
uv run uvicorn blogging_mcp.asgi:app --host 0.0.0.0 --port 8765当您想要与FastMCP指南相同的旋钮(工作器、中间件、在Starlette/FastAPI中安装等)时,请使用此选项。
生产说明(来自FastMCP): 将TLS和超时放在前面(例如nginx proxy_buffering off 对于SSE),请考虑 FASTMCP_STATELESS_HTTP=true 在负载平衡器后面,添加 认证 有关互联网上可访问的任何内容,请参阅 认证 在FastMCP文档中。
工具
创建(两个平台)
publish_article--在dev.to和Hashnode上创建(createDraft然后publishDraft当hashnode_published是真的)。每个平台的回报结果(ok,url,error,note).如果hashnode_published为false,仅为哈希节点 草稿 创建。
dev.to(REST) --响应使用 { "ok": true, "data": ... } 或 { "ok": false, "error": "..." }.
devto_get_article—GET /api/articles/{id}devto_list_my_articles—scope:published|unpublished|all,分页devto_update_article—PUT部分更新(最大 4 标签)devto_delete_article—DELETE /api/articles/{id}
哈希节点(GraphQL) --同样的 { ok, data | error } 形状。
hashnode_get_post/hashnode_get_draft--按id读取hashnode_list_posts/hashnode_list_drafts--列出发布内容(光标after职位)hashnode_update_post--更新a 发表 职位(updatePost)hashnode_remove_post--删除已发布的帖子(removePost)
Hashnode的公共API不公开 updateDraft 突变;在Hashnode编辑器中编辑草稿或发布,然后使用 hashnode_update_post.
其他
verify_credentials--检查dev.to键和Hashnode发布(无写入)。
发展
uv run ruff check .
uv run ruff format .
uv run pytestGitHub 操作→ Docker 中心
开 拉取请求,CI运行lint、测试和 Docker构建 标记的 sha- (图片为 不 推)。开 推至 main/master (在lint+测试通过后),CI构建 linux/amd64 并推动 alsaheem/blogging-mcp:latest, alsaheem/blogging-mcp:,以及 alsaheem/blogging-mcp:-,在哪里 `` 来自 pyproject.toml ([project].version).
添加这些 存储库机密 (设置→ 秘密和变量→ 行动):
| 秘密 | 价值 |
|---|---|
DOCKERHUB_USERNAME | 您的Docker Hub用户名(例如。 alsaheem) |
DOCKERHUB_TOKEN A. (创建于 *账户设置→ 安全*).比起您的帐户密码,更喜欢这个。 |
您还可以手动运行工作流(行动→ CI → 运行工作流).
贡献
欢迎捐款。看 贡献.md 用于设置、运行 ruff 和 pytest,并拉取请求期望。
对于 安全漏洞,使用 安全.md 并且不要公开漏洞利用细节。
当首先在问题中讨论时,大型行为或API更改更容易审查。
码头工人
图像构建自 pyproject.toml, uv.lock,以及 src/ 只有。 .env 在...里 .dockerignore --它不会复制到构建上下文中,因此笔记本电脑中的秘密 不 烘焙成图像层 除非 您添加 ARG/ENV 钥匙在 Dockerfile (不要)。
秘密属于运行时: 使用 -e NAME=value, --env-file 指向文件 在主机上,或您的编排器的秘密存储。你传递的任何东西 -e 存在于 运行容器的环境,不是在图像tarball你 docker push (假设您没有将密钥也提交到Dockerfile中)。
云运行(linux/amd64,x86_64)
云运行 跑 linux/amd64 默认情况下为图像。如果你在Apple Silicon(arm64)上构建 docker build 产生一个 手臂 除非你设置了平台。
建立并推动 amd64 和 Buildx:
docker login # Docker Hub (or Artifact Registry docker auth)
docker buildx build \
--platform linux/amd64 \
-t alsaheem/blogging-mcp:latest \
--push .加载到本地Docker(amd64镜像;通过Apple Silicon上的仿真运行):
docker buildx build --platform linux/amd64 -t alsaheem/blogging-mcp:latest --load .本地构建(本地平台)
docker build -t alsaheem/blogging-mcp:latest .
docker login # as Docker Hub user alsaheem
docker push alsaheem/blogging-mcp:latest
docker run --rm -i \
--env-file .env \
alsaheem/blogging-mcp:latest或者显式设置变量(如果使用粘贴,请避免在共享历史记录中记录命令):
docker run --rm -i \
-e DEVTO_API_KEY=... \
-e HASHNODE_TOKEN=... \
-e HASHNODE_PUBLICATION_HOST=you.hashnode.dev \
alsaheem/blogging-mcp:latest集装箱运行 uv run python -m blogging_mcp (参见 Dockerfile CMD).
超文本传输协议 (例如,主机的游标URL模式):
docker run --rm -p 8765:8765 \
-e MCP_TRANSPORT=http \
-e MCP_HTTP_HOST=0.0.0.0 \
-e MCP_HTTP_PORT=8765 \
--env-file .env \
alsaheem/blogging-mcp:latest然后Cursor可以使用 "url": "http://127.0.0.1:8765/mcp".
许可证
该项目根据 MIT许可证.
