bugsink-mcp
Hosted MCP server that exposes your self-hosted Bugsink error tracker as tools for LLMs, enabling issue management, release tracking, and stacktrace retrieval via chat prompts.
README
bugsink-mcp
A hosted Model Context Protocol server that exposes your self-hosted Bugsink error tracker as tools an LLM (Claude, or anything else speaking MCP) can call directly.
List issues, pull stacktraces, resolve or mute noise, tag releases — all from a chat prompt, without the LLM ever touching your Bugsink credentials directly.
Table of contents
- Why this exists
- What it covers
- Quick start
- Deploying
- Registering with Claude (or another MCP client)
- Security posture
- Configuration reference
- Contributing
- License
Why this exists
Bugsink is a self-hosted, single-tenant error tracker, so it isn't in Claude's public connector registry (there's no shared OAuth endpoint to register). That leaves two options:
- stdio MCP server — Claude spawns the process locally per session. Works, but every machine needs the binary and env vars.
- hosted (Streamable HTTP) MCP server — same shape as
mcp.vercel.comormcp.render.com, just deployed by you. Register once by URL and any Claude client can call it.
This project is option 2. You deploy it (Docker, VPS, one small container) and point Claude at https://mcp.yourdomain.tld/mcp. Claude never sees your Bugsink API token — this service holds it, translates MCP tool calls into REST calls, and streams the results back.
What it covers
Every read/write endpoint in Bugsink's public API (/api/canonical/0/*):
| Area | Tools |
|---|---|
| Teams & projects | list_teams, list_projects, get_project |
| Issues | list_issues, get_issue, add_issue_comment, resolve_issue (now / on latest release / on next release), mute_issue (indefinite / for a period / until an event threshold), unmute_issue, delete_issue |
| Events | list_events, get_event, get_event_stacktrace (the rendered readable version — usually more useful than the raw JSON) |
| Releases | list_releases, create_release, get_release |
Each tool's input schema is declared with zod, so the MCP SDK rejects malformed calls before your handler runs.
Quick start
Requirements: Node ≥ 18, pnpm ≥ 9, and an API token from your Bugsink instance (Account settings → API tokens).
git clone https://github.com/Nshuti7/bugsink-mcp.git
cd bugsink-mcp
pnpm install
pnpm run build
cp .env.example .env # fill in BUGSINK_BASE_URL and BUGSINK_TOKEN
node --env-file=.env dist/index.js
You should see bugsink-mcp listening on port 8787. Verify with:
curl http://localhost:8787/healthz # -> "ok"
For a live-rebuild dev loop:
pnpm run dev # tsc --watch in one terminal
node --env-file=.env --watch dist/index.js # in another
Deploying
Docker Compose (recommended)
The bundled docker-compose.yml assumes you already run Traefik on the same host with an external network called web. Adjust the labels to match your setup, then:
export BUGSINK_TOKEN=your-real-token
docker compose up -d --build
Docker without Traefik
Drop the labels and networks blocks and add a direct port mapping:
ports:
- "8787:8787"
Any other platform
It's a plain Node HTTP server on $PORT (default 8787). Anything that can run a container or a Node process will host it — Fly.io, Render, Railway, a bare VPS with pm2, etc. There's no persistent state, so you can scale it horizontally without coordination.
Registering with Claude (or another MCP client)
Once your instance is reachable over HTTPS, register it however your client prefers:
Claude CLI (uses the header form of the token):
claude mcp add --transport http bugsink https://mcp.yourdomain.tld/mcp \
--header "Authorization: Bearer $MCP_AUTH_TOKEN"
Cowork / Claude Desktop → "Add custom connector" — this UI only has a URL field, so use the query-string form:
- Name: anything you like, e.g.
Bugsink - URL:
https://mcp.yourdomain.tld/mcp?token=<your-MCP_AUTH_TOKEN> - Leave the OAuth Client ID / Client Secret fields blank — this server uses a static shared secret, not OAuth 2.0.
The endpoint speaks standard Streamable HTTP MCP, so any compliant client will work.
Security posture
Read this before deploying. Two layers matter:
1. Authentication on /mcp (opt-in shared secret)
Set MCP_AUTH_TOKEN to any random string (e.g. openssl rand -hex 32) and every /mcp request must present the token in one of two ways:
Header (preferred, RFC 6750-clean) — works with the Claude CLI and anything else that lets you attach custom headers:
claude mcp add --transport http bugsink https://mcp.yourdomain.tld/mcp \
--header "Authorization: Bearer $MCP_AUTH_TOKEN"
Query string — works with UIs that only take a URL (Cowork's "Add custom connector" dialog, Claude Desktop's connector-by-URL, etc.):
https://mcp.yourdomain.tld/mcp?token=<your-MCP_AUTH_TOKEN>
Both paths use the same timing-safe comparison; either satisfies the gate. Requests presenting neither (or a wrong value) get 401 Unauthorized.
Why offer the query-string form at all? RFC 6750 discourages tokens in URLs because they can leak via server access logs, referer headers, or browser history. None of those apply here: this URL is only ever POST'd by an MCP client (never navigated in a browser), and this process runs no request-logging middleware. The security model is the same as the header form — whoever has the URL can call the tools — just shifted into the URL itself. Prefer the header when your client supports it.
If MCP_AUTH_TOKEN is unset, the endpoint is open — fine for local dev, not fine for a public URL. The process logs a warning at startup in that case.
2. Defense in depth at the proxy layer
Even with a token, an IP allowlist at Traefik (or your reverse proxy) is a cheap extra layer — a commented example is in docker-compose.yml. Restrict to your MCP client's egress plus your own IPs.
On the Bugsink token
The Bugsink API token lives only in this service's environment. It's never sent to the LLM, never logged, never persisted to disk.
Configuration reference
| Env var | Required | Default | Purpose |
|---|---|---|---|
BUGSINK_BASE_URL |
✅ | — | Root URL of your Bugsink instance, e.g. https://bugsink.example.com |
BUGSINK_TOKEN |
✅ | — | Bugsink API token (Account settings → API tokens) |
MCP_AUTH_TOKEN |
recommended | — | Shared-secret bearer token for /mcp. Unset = open endpoint (dev only). See Security posture. |
PORT |
8787 |
HTTP port the MCP server binds to |
Missing BUGSINK_BASE_URL or BUGSINK_TOKEN fails fast on startup with a clear message. Missing MCP_AUTH_TOKEN starts fine but logs a warning.
Contributing
Contributions are welcome — issues, PRs, docs fixes, new tools, security hardening, all of it. Start with CONTRIBUTING.md for the ground rules and dev loop.
Good first PRs, if you're looking for ideas:
- Cover any Bugsink endpoints that get added upstream
- A GitHub Actions workflow that runs
pnpm run buildon PRs - Example client scripts (curl / Python / TS) that exercise the MCP endpoint end-to-end
- Structured logging with request IDs
- Rate limiting on
/mcpas an additional abuse-mitigation layer
Have an idea that's not on the list? Open an issue first so we can align on the shape before you write code.
License
MIT © contributors
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。