Skip to main content
Glama
Nshuti7

bugsink-mcp

by Nshuti7

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.

Node TypeScript License: MIT PRs Welcome

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


Related MCP server: Telebugs MCP Server

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:

  1. stdio MCP server — Claude spawns the process locally per session. Works, but every machine needs the binary and env vars.

  2. hosted (Streamable HTTP) MCP server — same shape as mcp.vercel.com or mcp.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

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 build on PRs

  • Example client scripts (curl / Python / TS) that exercise the MCP endpoint end-to-end

  • Structured logging with request IDs

  • Rate limiting on /mcp as 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

A
license - permissive license
-
quality - not tested
C
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.

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/Nshuti7/bugsink-mcp'

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