ducbachsong

Backlog MCP Server

Community ducbachsong
Updated

MCP server exposing Backlog project management tools for Claude Desktop

Backlog MCP Server

An MCP server that exposes Backlog project management as tools for Claude Desktop (or any MCP-compatible client). Search and manage issues, comments, wiki pages, milestones, custom fields, notifications, and more — directly from a conversation with Claude.

Features

  • 21 tools covering issues, comments, wiki, categories, issue types, milestones, custom fields, attachments, activity feeds, notifications, watchers, and stars. Tools are grouped by subject with a kind/action selector rather than split one-per-endpoint, so there is less schema for the model to scan.
  • Multi-space support — configure any number of Backlog spaces (e.g. separate client/company instances) and target them by name per tool call, without restarting or reconfiguring.
  • One request per changeupdate_issues and add_comment send every field change plus the comment plus the mention notification in a single PATCH, so Backlog's 課題の変更履歴 gets one entry instead of one per field.
  • Full ticket field coverage — 状態 / 担当者 / 優先度 / 種別 / マイルストーン / カテゴリー / 発生バージョン / 開始日 / 期限日 / 予定時間 / 実績時間 / 完了理由, each settable by display name or numeric id ('Closed', 'clos' and '4' all work), with a clear_fields argument to blank them out.
  • Real mentions — passing mention_user_ids posts a comment that renders as a highlighted @Name mention and triggers a real Backlog notification (bell + email), matching what you get from typing @ in the Backlog UI. Plain @Name text does neither.
  • Parallel fetching and updating for bulk operations (get_issue, get_comments, update_issues, delete_issue all accept a list of keys).
  • Read-only tools require no confirmation; every create/update/delete tool is marked in its docstring for the client to confirm with the user before calling.

Setup

1. Install dependencies

uv sync
# or
pip install -e .

Requires Python 3.11+.

2. Configure Backlog spaces

Copy .env.example to .env and fill in your space(s). Each space needs three variables sharing a common <NAME> suffix:

BACKLOG_API_KEY_<NAME>=...
BACKLOG_HOST_<NAME>=...
PROJECT_KEY_<NAME>=...

<NAME> (lowercased) becomes the source argument you pass to tools. Add as many spaces as you need by repeating the pattern with a different <NAME>. Optionally set DEFAULT_SOURCE=<name> to control which space is used when source is omitted — otherwise the first configured space is used.

Get your API key from Backlog under Personal Settings → API.

3. Register with Claude Desktop

Copy claude_desktop_config.example.json to your Claude Desktop config location, fill in the real command/args paths and credentials, and merge it into your existing mcpServers block if you already have other servers configured:

{
  "mcpServers": {
    "backlog": {
      "command": "/path/to/backlog-mcp/.venv/Scripts/python.exe",
      "args": ["/path/to/backlog-mcp/server.py"],
      "env": {
        "BACKLOG_API_KEY_SPACE1": "your_api_key_here",
        "BACKLOG_HOST_SPACE1": "your-space.backlog.com",
        "PROJECT_KEY_SPACE1": "YOUR_PROJECT_KEY"
      }
    }
  }
}

Your filled-in claude_desktop_config.json is machine-specific and contains live credentials — keep it out of version control (already covered by .gitignore).

Tools

Discovery & metadata

  • get_sources — list the configured Backlog spaces.
  • get_project_metadata — one call for every lookup list: project, statuses, users, issue_types, categories, milestones, versions, priorities, resolutions, custom_fields, plus space-level projects and myself. Cached per server run, so kinds='all' is cheap.

Issues

  • get_issues — search/filter; count_only=True returns just the match count.
  • get_issue — one or many keys, fetched in parallel; full=False for slim records.
  • get_related_issues — parent, children, or both.
  • get_recently_viewed — recently viewed issues or wikis.
  • create_issue — create with every field set at once.
  • update_issuesthe write tool. One or many keys; sets any combination of 状態 / 担当者 / 優先度 / 種別 / 完了理由 / マイルストーン / カテゴリー / 発生バージョン / 開始日 / 期限日 / 予定時間 / 実績時間, plus summary, description, parent_issue_id, a comment, mention_user_ids and clear_fields — all in a single request per issue.
  • delete_issue — one or many keys.

Comments

  • get_comments — one or many issues; last_n=0 for the full thread, last_n=N for the newest N (slimmed).
  • add_comment — comment + optional mention + optional field changes, all in one request.
  • manage_commentaction='update' or 'delete'.

Attachments

  • get_attachments — lists an issue's or wiki page's attachments; pass attachment_id to download one. Images come back inline, text files as text, other binaries as base64.

Project admin

  • manage_project_settingkind of category / issue_type / milestone / custom_field × action of add / update / delete. Clears the metadata cache on success.

Wiki

  • get_wikis — list, read one page (wiki_id), or count_only.
  • manage_wiki_pageaction='create' / 'update' / 'delete'.

Activity & notifications

  • get_activitiesscope='project' or 'space'.
  • get_notifications — list, or count_only.
  • mark_notifications_read — one notification, or all when notification_id=0.

Watchers & stars

  • manage_watchersaction='list' / 'add' / 'delete'.
  • add_star — star an issue, comment, or wiki page.

Project layout

server.py               entry point — Claude Desktop configs point here
backlog_mcp/
  config.py             builds the multi-space source registry from env vars
  app.py                the FastMCP object and process entry point
  common.py             sentinels shared by tools (default source, "unchanged")
  fields.py             ticket-field value -> Backlog form body; mention rewriting
  api/                  everything below the tool definitions
    secrets.py          API-key redaction (security-critical — read this first)
    sources.py          source name -> configured Backlog space
    http.py             the retrying request path all traffic goes through
    meta.py             project lookup lists, caching, name -> id resolution
    slim.py             payload trimming
    issues.py           paginated issue / comment fetching
    parallel.py         fan-out for multi-key tools
  tools/                the MCP tools, one module per subject
    metadata.py         get_sources, get_project_metadata
    issues.py           get_issues, get_issue, get_related_issues,
                        create_issue, update_issues, delete_issue
    comments.py         get_comments, add_comment, manage_comment
    attachments.py      get_attachments
    project_settings.py manage_project_setting
    wiki.py             get_wikis, manage_wiki_page
    activity.py         get_activities, get_recently_viewed,
                        get_notifications, mark_notifications_read
    social.py           manage_watchers, add_star

Each layer only imports the ones above it: configapi/common/fieldsapptools/. Importing backlog_mcp registers every tool, because each toolmodule applies @mcp.tool() at import time.

Adding a tool: put it in the matching tools/ module (or add a new module andlist it in tools/__init__.py). Reach Backlog through api.get / api.post /api.patch / api.delete rather than requests directly — that request path iswhat keeps the API key out of error messages.

Security note

Backlog authenticates with a ?apiKey= query parameter, so the key is part ofevery request URL, and requests puts the full URL into its exception messages.Those messages reach the MCP client. api/secrets.py scrubs the key out of everyerror leaving the HTTP layer — if you add a code path that talks to Backlogoutside api/http.py, scrub it there too.

License

No license specified — all rights reserved by default.

MCP Server · Populars

MCP Server · New