Backlog Remote MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Backlog Remote MCP Servershow issues assigned to me in the dev project"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Backlog Remote MCP Server
A remote MCP (Model Context Protocol) server for Backlog. Deployable to either Cloudflare Workers or AWS.
English | 日本語
Features
Multi-space — serve several Backlog spaces from one server
Read-only guard — mark a shared space
readOnlyto reject every write API callOAuth 2.1 + PKCE — supports Dynamic Client Registration (DCR), so MCP clients connect directly
Email allowlist — restrict who can use the server
Two runtimes — the same business logic runs on Cloudflare or AWS
Related MCP server: backlog-mcp-server
Choosing a deployment
Cloudflare Workers | AWS | |
Runtime | Workers (edge) | Lambda + API Gateway HTTP API |
MCP session | Durable Objects | Stateless |
OAuth authorization server |
| MCP SDK |
Upstream IdP | Cloudflare Access | Amazon Cognito |
State storage | Workers KV | DynamoDB (TTL) |
Secrets | Workers Secrets | Secrets Manager |
IaC | wrangler | AWS SAM |
Config file |
|
|
The tools and their behavior are identical on both.
Estimated Cost
Note These are reference figures only. Actual charges vary by region, usage, and pricing changes. Use the official calculators for real estimates.
Assumptions
Personal use or a small team.
Item | Assumption |
Users | 1–5 |
MCP requests | ~3,000 / month |
Backlog spaces | 3 |
Log retention | 30 days |
Fixed costs (charged even when idle)
Cloudflare | AWS | |
Runtime | $0 (Free plan works) | $0 |
Auth platform | $0 (Zero Trust free up to 50 users) | $0 (within Cognito free tier) |
Secrets | $0 (Workers Secrets are free) | ~$0.80 (2 Secrets Manager secrets) |
Certificates | $0 | $0 (public ACM certificates are free) |
Total | $0 | ~$1/month |
On AWS the fixed cost is essentially just Secrets Manager, which bills per secret per month whether or not it is used. Cloudflare has no fixed cost because Workers Secrets are free.
What is metered
Cloudflare | AWS | |
Requests | Workers | Lambda + API Gateway |
State storage | Durable Objects + KV | DynamoDB |
Logs | Workers Logs | CloudWatch Logs |
At the assumed volume (~3,000 requests/month) both stay within the free allowances. API Gateway HTTP API has no perpetual free tier, so AWS accrues a small charge proportional to request count (roughly $1 per million requests).
Thresholds worth knowing
Cloudflare — the 50-user line for Zero Trust
Zero Trust (Access) is free for up to 50 users. Beyond that you move to a paid plan billed per user per month. This is the cost that scales with headcount.
Cloudflare — Workers Free plan limits
This project uses SQLite-backed Durable Objects, which are available on the Workers Free plan. The Free plan does cap daily requests and other usage, and exceeding a cap returns errors. For sustained use consider Workers Paid (from $5/month).
AWS — the Lambda free tier is perpetual
Lambda includes a perpetual free tier of 1M requests and 400,000 GB-seconds per month. API Gateway and Secrets Manager have no perpetual free tier.
AWS — CloudWatch Logs
Logs are billed on ingestion volume. This template manages retention explicitly via
LogRetentionDays (default 30), so logs do not accumulate indefinitely.
Summary
Scale | Cloudflare | AWS |
Personal | roughly $0 | ~$1/month |
Tens of users (≤50) | roughly $0–$5 | $1 to a few dollars/month |
51+ users | Zero Trust switches to per-user billing | depends on the Cognito MAU free tier |
For small teams Cloudflare is cheaper and has no fixed cost. AWS carries the Secrets Manager fixed cost but is worth it if you want to consolidate into an existing AWS footprint or govern access through IAM.
Setup
0. Prerequisites
Node.js 20 or later.
git clone <this-repo>
cd backlog-remote-mcp-server
npm installAdditional tools depend on the deployment target:
Target | Requirements |
Cloudflare Workers | Cloudflare account with Workers enabled, custom domain (optional) |
AWS | AWS account, AWS CLI v2, AWS SAM CLI |
Order to follow
Backlog API keys and space configuration — shared by both platforms
Pick an identity provider
Pick a deployment target
If something goes wrong
Troubleshooting sections live at the end of each deployment guide.
Architecture
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 ...Directory layout
Business logic is separated from runtime wiring.
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 parameterssrc/core depends only on @modelcontextprotocol/sdk and zod and references no
runtime-specific API. Adding a platform means adding an adapter under
src/platforms/ while sharing the same tool implementations.
Connecting from MCP Clients
Claude Desktop / Kiro / Cursor (via mcp-remote proxy)
{
"mcpServers": {
"backlog": {
"command": "npx",
"args": [
"mcp-remote",
"https://<MCP_HOSTNAME>/mcp"
]
}
}
}On first connection, a browser window opens for authentication.
MCP Inspector (for testing)
npx @modelcontextprotocol/inspector@latestEnter https://<MCP_HOSTNAME>/mcp in the inspector and complete the OAuth flow via OAuth Settings.
Usage
Specifying a Space
All tools accept an optional space parameter:
# Use default space
"Show me the issues for PROJECT-KEY"
# Specify a particular space
"List projects in the PERSONAL space"
→ space: "PERSONAL"Examples
# 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(...)Available Tools
Category | Tools |
Space | list_spaces, get_space, get_users, get_myself |
Project | get_project_list, get_project, add_project, update_project, delete_project, get_project_users |
Issue | 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_pages, 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 |
Notification | get_notifications, get_notifications_count, reset_unread_notification_count, mark_notification_as_read |
add_*, update_*, and delete_* are write operations. Calling them against a space configured with readOnly: true is rejected before any request reaches the Backlog API. Use list_spaces to see the readOnly status of each space.
Security
Authentication: Cloudflare Access → Google / Microsoft Entra ID. The entire OAuth flow is managed by Cloudflare
Authorization:
ALLOWED_EMAILSprovides an application-level email allowlistDouble-check: Access Policy (Cloudflare side) + in-app allowlist (Worker side)
API Key Protection: Backlog API keys are stored in Cloudflare Secrets and never exposed to clients
PKCE + CSRF: OAuth flow is protected with PKCE (S256) and CSRF tokens
Client consent: Dynamic Client Registration is open to anyone, so authorization is gated behind a consent screen that names the client and its redirect target and requires a CSRF-protected approval. Approvals are keyed on
client_id+redirect_uri, so re-registering with a different redirect target cannot inherit a prior approvalWrite guard: Spaces marked
readOnly: truereject every non-GET call. The check lives in the API-call layer ofsrc/core/backlog-client.ts, so it does not depend on individual tool implementationsConfiguration isolation: All environment-specific values live in
.dev.vars(untracked). The repository contains placeholders only
Operational notes
ALLOWED_EMAILSis the effective authorization boundary for this server. There is no zone-level Access application in front of the Workernpm run deployoverwrites production secrets with the values in.dev.vars. If you need different values locally and in production, usedeploy:no-secretsfor routine deploys and push secrets explicitly withsecrets:pushA Backlog API key carries the full permissions of its owner. For spaces that need no writes, issue a read-only key and set
readOnly: true
Local Development
Local runs use the Cloudflare Workers build (wrangler dev). Because the business logic
lives in src/core, whatever you verify here holds for the AWS deployment too.
cp .dev.vars.example .dev.vars # fill in your values
npm run dev
# Server starts at http://localhost:8788/mcpwrangler dev emulates KV and Durable Objects locally, so it never touches real
Cloudflare resources.
Verifying the setup
Run the full OAuth-to-tool-call check in one command:
npm run check:localIt performs the following, opening a browser partway through so you can log in:
Fetch the Authorization Server metadata
Dynamic client registration
Approve in the browser → IdP login
Token exchange with PKCE
initialize/tools/listCall
get_spaceand show the real response from Backlog
If tools/list returns only access_denied, the email you logged in with is not in the
allowlist.
It also works against a deployed endpoint:
npm run check:local -- --base https://your-deployed-hostRunning over HTTPS
Use this when the IdP will not accept an http:// redirect URL.
npm run dev:https
# Server starts at https://localhost:8788/mcp (self-signed certificate)Type checking and tests
Types are split per platform, so misusing a Workers global in AWS code (or vice versa) is a type error.
npm run type-check # both tsconfig.cloudflare.json and tsconfig.aws.json
npm test # runs all suites belowCommand | Covers |
| OAuth authorization server logic (DCR, PKCE, single-use tokens, scopes, revocation) |
| Consent screen (HTML escaping, signed cookies, CSRF, approval gate) |
| DynamoDB store client-registration TTL and renewal |
None of them reach external services — DynamoDB and the upstream IdP are stubbed.
Configuration files
File | Purpose | Git |
| Local development + Cloudflare deploy | ignored |
| Template for the above | committed |
| AWS deploy | ignored |
| Template for the above | committed |
See the deployment guides for how to fill them in.
License
MIT
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to interact with Bitbucket Cloud repositories, allowing users to manage pull requests, comments, tasks, and branches through natural language commands.4,1381MIT
- AlicenseBqualityDmaintenanceEnables interaction with Backlog project management tools, allowing users to manage projects, issues, and wikis through natural language.1233,209MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to interact with Atlassian Cloud APIs for Confluence and Jira, supporting document management, search, issue tracking, and sprint operations through natural language.2MIT
- AlicenseAqualityBmaintenanceEnables AI assistants to interact with Atlassian Cloud (Jira, Confluence, Bitbucket) through natural language, providing CRUD operations for issues, pages, pull requests, and more.8620MIT
Related MCP Connectors
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Connect AI assistants to Stellary projects, boards, documents, and governed agent workflows.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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