Skip to main content
Glama
midnight480

Backlog Remote MCP Server

by midnight480

Backlog Remote MCP Server

用于 Backlog 的远程 MCP(Model Context Protocol)服务器。 可部署到 Cloudflare Workers 或 AWS。

English | 日本語

功能

  • 多空间 — 通过单一服务器服务多个 Backlog 空间

  • 只读保护 — 将共享空间标记为 readOnly,拒绝所有写 API 调用

  • OAuth 2.1 + PKCE — 支持动态客户端注册(DCR),MCP 客户端可直接连接

  • 电子邮件允许列表 — 限制可使用此服务器的人员

  • 两种运行时 — 相同的业务逻辑可在 Cloudflare 或 AWS 上运行

Related MCP server: backlog-mcp-server

选择部署方式

Cloudflare Workers

AWS

运行时

Workers(边缘节点)

Lambda + API Gateway HTTP API

MCP 会话

Durable Objects

无状态

OAuth 授权服务器

@cloudflare/workers-oauth-provider

MCP SDK mcpAuthRouter

上游身份提供者 IdP

Cloudflare Access

Amazon Cognito

状态存储

Workers KV

DynamoDB(TTL)

密钥

Workers Secrets

Secrets Manager

IaC(基础设施即代码)

wrangler

AWS SAM

配置文件

.dev.vars

infra/aws/params.yaml

这两种工具及其行为完全相同。

预Estimated Cost

注意 以上仅为参考数字。 实际费用因区域、使用情况和价格变化而异。 如需实际估算,请使用官方计算工具。

前提假设

适用于个人使用或小型团队。

项目

假设值

用户数

1–5

MCP 请求数

~3,000 / 月

Backlog 空间数量

3

日志保留

30 天

固定费用(即使空闲也会产生)

Cloudflare

AWS

运行时

$0(免费套餐可用)

$0

授权平台

$0(Zero Trust 免费至 50 个用户)

$0(在 Cognito 免费套餐内)

密钥

$0(Workers Secrets 免费)

~$0.80(2 个 Secrets Manager 密钥)

证书

$0(公有 ACM 证书免费)

0 美元(ACM公有证书免费)

合计

$0

约 $1/月

在 AWS 上,固定费用主要就是 Secrets Manager 的费用,无论是否使用,每个密钥每月都会产生 费用。Cloudflare 无固定费用,因为 Workers Secrets 免费。

计费项(按使用量计费)

项目

Cloudflare

AWS

请求

Workers

Lambda + API Gateway

状态存储

Durable Objects + KV

DynamoDB

日志

Workers Logs

CloudWatch Logs

在假设的用量(每月约 3000 个请求)下,两者都在免费额度以内。API Gateway HTTP API 没有永久免费层级,因此 AWS 会按照请求数产生少量费用(大约每百万次请求 $1)。

需要了解的阈值

Cloudflare — Zero Trust 的 50 用户限制

Zero Trust(Access)最多 50 名用户免费。超过后需升级为付费计划,按用户数计费。这是与编码强度成正比的主要成本。

Cloudflare — Workers 免费计划限制

本项目使用基于 SQLite 的 Durable Objects,这些 Durable Objects 可以在 Workers 免费计划中运行(参考 官方说明)。 免费计划会限制每日请求次数及突增使用情况,超出后将返回错误。若持续使用,建议升级到 Workers 付费版(每月 $5 起)。

AWS — Lambda 免费额度是“永久”的

Lambda 提供了永久的免费额度,包括每月 100 万次请求和 400,000 GB-秒(内存消耗)。API Gateway 和 Secrets Manager 没有永久免费额度

AWS — CloudWatch Logs

日志按采集量计费。此项目通过 LogRetentionDays(默认 30 天)明确设置日志保留天数,因此日志不会无限累积。

Summary(汇总)

规模

Cloudflare

AWS

个人使用

大约 $0

~$1/月

数十个用户(区 50)

大约 $0–$5

$1 到几美元/月

51 个及以上用户

Zero Trust 改为按用户计费

取决于 Cognito MAU 免费额度的用量

对于小型团队来说,Cloudflare 更省钱且但无需固定成本。 AWS 虽然包含 Secrets Manager 的固定成本,但如果你希望将其整合到现有的 AWS 基础设施中,或需要通过 IAM 进行权限管理,那么该方案更有价值。

开始部署

0. 先决条件

需要 Node.js 20 或更新版本.

git clone <this-repo>
cd backlog-remote-mcp-server
npm install

其他工具取决于你的部署目标:

目标

部署要求

Cloudflare Workers

已启用 Workers 的 Cloudflare 账户,自定义域名(可选)

AWS

AWS 账户、AWS CLI v2、AWS SAM CLI

按以下顺序

  1. Backlog API 密钥与空间配置 — 两种平台同样适用

  2. 选择身份提供者(IdP)

  3. 选择部署平台

如果出错

问题排查部分位于各部署指南的末尾。

架构

MCP client (Claude, Kiro, Cursor, ...)
    ↓ Streamable HTTP + OAuth
Runtime (Cloudflare Workers or AWS Lambda)
    ↓ Upstream IdP (Cloudflare Access or Amazon Cognito)
    ↓ Email allowlist check
    ↓ Backlog API key routing
Backlog space A / B / C ...

目录结构

业务逻辑与运行时调用层分离。

src/
  core/                    Runtime-independent
    backlog-client.ts      Backlog API client (including the readOnly guard)
    tools/                 40 MCP tools
    create-server.ts       MCP server assembly and authorization
  platforms/
    cloudflare/            Cloudflare Workers wiring
    aws/                   AWS Lambda wiring
infra/
  aws/                     SAM template and parameters

src/core 仅依赖 @modelcontextprotocol/sdkzod,不引用任何运行时特有的 API。新增一种平台,只需在 ```src/platforms/`` 下增加适配器,同时重用相同的工具实现即可。

如何从 MCP 客户端连接

在 Claude Desktop / Kiro / Cursor 中通过 mcp-remote 代理使用

{
  "mcpServers": {
    "backlog": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://<MCP_HOSTNAME>/mcp"
      ]
    }
  }
}

首次连接时会自动打开浏览器窗口,用户需在其中完成身份验证。

在 MCP Inspector 中测试

npx @modelcontextprotocol/inspector@latest

在 inspector 中输入 https://<MCP_HOSTNAME>/mcp,然后在 OAuth Settings 中完成 OAuth 鉴权流程。

使用说明

指定空间

所有工具都接受一个可选的 space 参数来指定操作目标。

# Use default space
"Show me the issues for PROJECT-KEY"

# Specify a particular space
"List projects in the PERSONAL space"
→ space: "PERSONAL"

示例

# List configured spaces
"What Backlog spaces are available?" → list_spaces

# List projects
"Show COMPANY_A projects" → get_project_list(space: "COMPANY_A")

# Create an issue
"Create a new bug issue in PROJECT-KEY" → add_issue(...)

# List pull requests
"Show open PRs in repo-name" → get_pull_requests(...)

可用工具

分类

工具

空间

list_spaces, get_space, get_users, get_myself

项目

get_project_list, get_project, add_project, update_project, delete_project, get_project_users

问题

get_issue, get_issues, count_issues, add_issue, update_issue, delete_issue, get_issue_comments, add_issue_comment, get_priorities, get_issue_types, get_categories, get_version_milestones, add_version_milestone, get_resolutions

Wiki

get_wiki_page, get_wikis_count, get_wiki, add_wiki

Git

get_git_repositories, get_git_repository, get_pull_requests, get_pull_request, add_pull_request, update_pull_request, get_pull_request_comments, add_pull_request_comment

通知

get_notifications, get_notifications_count, reset_unread_notification_count, mark_notification_as_read

add_*update_*delete_* 为写操作。如果目标空间配置了 role。如果目标空间配置了 readOnly: true,在被拒绝之前不会向 Backlog API 发出任何请求。可以通过 list_spaces 查看每个空间当前的 readOnly 状态。

安全特性

  • 身份验证:Cloudflare Access → Google / Microsoft Entra ID。整个 OAuth 流程由 Cloudflare 管理。

  • 授权ALLOWED_EMAILS 提供应用级别的电子邮件白名单。

  • 双重检查:Cloudflare 侧 Access Policy + Worker 侧应用层 allowlist。

  • API 密钥保护:Backlog API 密钥存储在 Cloudflare Secrets 中,绝不会暴露给客户端。

  • PKCE + CSRF:OAuth 流程使用 PKCE (S256) 和 CSRF tokens 防护。

  • 客户端授权:Dynamic Client Registration 开放给任何人都可以进行,因此授权页面会显示客户端名称及其回调地址,并要求进行受 CSRF 保护的同意确认。授权以 client_idredirect_uri 为绑定对象,使用不同的回调地址重新注册,无法继承之前的授权。

  • 写保护:对于设置为 readOnly: true 的空间,所有非 GET 请求都会被拒绝。该检查位于 src/core/backlog-client.ts 的 API 调用层,不依赖工具内的具体实现。

  • 配置隔离:所有环境专属的取值都保存在 .dev.vars(不纳入版本控制)。仓库中仅提供占位符。

运维注意事项

  • ALLOWED_EMAILS 是本服务的实际授权边界。Worker 的前端没有 Zone 级别的 Access 应用。

  • npm run deploy .dev.vars 中的内容覆盖生产环境的 secrets。如果本地和生产环境需要不同的值,可以日常部署时使用 deploy:no-secrets,并在需要时通过 secrets:push 手动推送 secrets。

  • Backlog API 密钥拥有其持有者的全部权限。对于无需写入的空间,请申请只读密钥,并同时设置 readOnly: true

本地开发

本地运行使用 Cloudflare Workers 版本(wrangler dev)。由于业务逻辑位于 src/core,你在本地验证的结果同样适用于 AWS 部署。

cp .dev.vars.example .dev.vars   # fill in your values
npm run dev
# Server starts at http://localhost:8788/mcp

wrangler dev在本机模拟 KV 和 Durable Objects,因此不会与真实的 Cloudflare 资源产生交互。

验证设置

通过以下命令可以一键完成 从 OAuth 到工具调用的完整检查:

npm run check:local

它会执行以下操作,并在中途打开浏览器,方便你进行登录验证。

  1. 获取授权服务器元数据

  2. 动态客户端注册

  3. 在浏览器中批准 → IdP 登录

  4. 使用 PKCE 交换令牌

  5. initialize / tools/list

  6. 调用 get_space 并显示来自 Backlog 的真实响应

如果 tools/list 只返回 access_denied,说明你登录时使用的电子邮件地址不在 允许列表中。

它也适用于已部署的端点:

npm run check:local -- --base https://your-deployed-host

通过 HTTPS 运行

当 IdP 不接受 http:// 重定向 URL 时,请使用此方式。

npm run dev:https
# Server starts at https://localhost:8788/mcp (self-signed certificate)

类型检查与测试

类型按平台分别划分,因此在 AWS 代码中误用 Workers 全局对象(或反之亦然)属于类型错误。

npm run type-check   # both tsconfig.cloudflare.json and tsconfig.aws.json
npm test             # runs all suites below

命令

覆盖范围

npm run test:aws-oauth

OAuth 授权服务器逻辑(DCR、PKCE、一次性令牌、作用域、撤销)

npm run test:aws:consent

同意界面(HTML 转义、签名 Cookie、CSRF、批准网关)

npm run test:aws:store

DynamoDB 存储中的客户端注册 TTL 与续期

它们都不会访问外部服务——DynamoDB 和上游 IdP 均被替换为桩实现。

配置文件

文件

用途

Git

.dev.vars

本地开发 + Cloudflare 部署

已忽略

.dev.vars.example

上述文件的模板

已提交

infra/aws/params.yaml

AWS 部署

已忽略

infra/aws/params.example.yaml

上述文件的模板

已提交

有关如何填写这些文件,请参阅部署指南。

许可证

MIT

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/midnight480/backlog-remote-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server