Skip to main content
Glama

Bugsink MCP

A local MCP server for investigating Bugsink issues from coding agents. Runs over stdio with the official MCP SDK. Supports Laravel error summaries, paginated stack traces, issue triage, comments, and deletion.

Install

Requires Node.js 22+ and pnpm. Run the published package without cloning:

pnpm dlx @rexlmanu/bugsink-mcp@0.2.0 --help

Or install the CLI globally:

pnpm add -g @rexlmanu/bugsink-mcp@0.2.0
bugsink-mcp --version

The executable is bugsink-mcp. Agent configurations below use pnpm dlx. For a global installation, set the command to bugsink-mcp and remove the dlx arguments. Pin a version to control upgrades.

Configuration

Create a Bugsink API token from the administrator's Tokens menu. A web login password cannot substitute for an API token.

Variable

Purpose

BUGSINK_URL

Required instance root URL, such as https://bugsink.example.com

BUGSINK_TOKEN

Required canonical API bearer token

BUGSINK_READ_ONLY

Defaults to true. Set false to expose triage, comments, and deletion

BUGSINK_ALLOWED_PROJECTS

Optional comma-separated numeric project IDs, such as 2,5

Omit BUGSINK_ALLOWED_PROJECTS to allow all projects accessible to the token. If set, it must contain 1 to 50 positive integer IDs. An empty or malformed value fails startup. The endpoint must use HTTPS, except for localhost HTTP. Do not include /api/canonical/0/ or an issue-page path in the endpoint.

The allowlist applies to project discovery, issue lists, direct issue and event details, event lists, and mutations. Team discovery only returns teams associated with allowed projects. Missing ownership metadata denies access. With restrictions enabled, team discovery reads metadata for every configured project, and an unavailable configured project causes that request to fail.

Bugsink's API token can still grant installation-wide access. This allowlist restricts what this MCP process returns or changes; it does not reduce the token's permissions outside this process. For direct IDs, the server must fetch ownership metadata before deciding whether to return the result. Event detail ownership is only available alongside Bugsink's full upstream payload.

Codex

Add this to ~/.codex/config.toml:

[mcp_servers.bugsink]
command = "pnpm"
args = ["dlx", "@rexlmanu/bugsink-mcp@0.2.0"]
env_vars = ["BUGSINK_TOKEN"]
startup_timeout_sec = 60

[mcp_servers.bugsink.env]
BUGSINK_URL = "https://bugsink.example.com"
BUGSINK_READ_ONLY = "true"
BUGSINK_ALLOWED_PROJECTS = "2,5"

Set BUGSINK_TOKEN in the environment that launches Codex. Replace the example endpoint and project IDs, or remove the allowlist line. Check the connection with codex mcp list and /mcp inside Codex.

See the official Codex MCP guide.

Claude Code

With BUGSINK_TOKEN set in the environment that launches Claude Code, register a server available across your projects:

claude mcp add --scope user \
  --env BUGSINK_URL=https://bugsink.example.com \
  --env BUGSINK_READ_ONLY=true \
  --env BUGSINK_ALLOWED_PROJECTS=2,5 \
  --transport stdio bugsink -- pnpm dlx @rexlmanu/bugsink-mcp@0.2.0

Replace the endpoint and project IDs. Remove the allowlist option to allow all projects. Check with claude mcp get bugsink or /mcp inside Claude Code. If the first package download exceeds the client's startup timeout, run the installation command with --help once before starting the agent.

For Claude Desktop or another client that reads mcpServers JSON, use:

{
  "mcpServers": {
    "bugsink": {
      "command": "pnpm",
      "args": ["dlx", "@rexlmanu/bugsink-mcp@0.2.0"],
      "env": {
        "BUGSINK_URL": "https://bugsink.example.com",
        "BUGSINK_TOKEN": "YOUR_API_TOKEN",
        "BUGSINK_READ_ONLY": "true",
        "BUGSINK_ALLOWED_PROJECTS": "2,5"
      }
    }
  }
}

Keep files containing real tokens private. GUI applications may need an absolute path to pnpm if their PATH differs from your terminal.

See the Claude Code MCP guide.

OpenCode

Add the following to your opencode.json, merging it with any existing config:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "bugsink": {
      "type": "local",
      "command": ["pnpm", "dlx", "@rexlmanu/bugsink-mcp@0.2.0"],
      "enabled": true,
      "timeout": 60000,
      "environment": {
        "BUGSINK_URL": "https://bugsink.example.com",
        "BUGSINK_TOKEN": "{env:BUGSINK_TOKEN}",
        "BUGSINK_READ_ONLY": "true",
        "BUGSINK_ALLOWED_PROJECTS": "2,5"
      }
    }
  }
}

Set BUGSINK_TOKEN before launching OpenCode. Replace the endpoint and IDs, or remove the allowlist entry. Ask the agent to list Bugsink projects to verify the connection. See the OpenCode MCP guide.

Tools

Tool

Inputs and result

list_teams

Team IDs and names

list_projects

Optional team UUID; project metadata and digested/stored event counts, without DSNs

list_issues

Required numeric project; status defaults to open, sorted by newest last_seen

get_issue

issue_id; status, exception message, counts, timestamps

list_events

issue_id; compact event metadata

get_event

Internal event_id; summary or paginated structured, rendered, or raw detail section

get_event_stacktrace

event_id; Bugsink-rendered frames, source context, and locals as paginated text

get_latest_event_stacktrace

issue_id; newest stored occurrence, pinned across text pages

resolve_issue

issue_id; mode is unconditionally, next_release, or latest_release

reopen_issue

issue_id; reopens a resolved issue, if supported by the instance

mute_issue

issue_id; indefinite mute, or a fixed duration

unmute_issue

issue_id; removes the mute

comment_on_issue

issue_id, comment; adds a comment to the issue history

delete_issue

issue_id, confirm: true; permanently deletes issue and events

Issue IDs can be UUIDs or short friendly IDs such as APP-42. resolve_issue defaults to mode=unconditionally. next_release marks it resolved by the next release; latest_release resolves it in the latest release. To mute for two hours, pass duration={"period_name":"hour","nr_of_periods":2}. Supported units are minute, hour, day, week, month, and year. Omit duration for an indefinite mute. Comments must contain 1 to 4,000 characters.

The current Bugsink API documents reopen, but the checked production 2.2.2 schema does not expose it. On older versions, the tool reports the upstream 404 with an endpoint-availability hint. It does not emulate reopening through another write operation.

Write tools appear only when BUGSINK_READ_ONLY=false. The client also checks this setting before sending a mutation. Deletion confirmation is a tool argument, not an independent human approval. Use your agent's tool approvals if you want to review each write.

Start with list_projects, then list_issues, then get_issue and list_events. Pass an event's id to get_event, not its Sentry event_id.

get_event supports section values summary, frames, exceptions, and breadcrumbs, stacktrace, and raw. The default remains a compact summary. Frames default to application_only=true, using Sentry's in_app flag when present and excluding vendor/ and node_modules/ otherwise. Set it to false to see framework frames. include_source=true includes the frame's source line. Frame and exception indices preserve their original order.

section=stacktrace and the two stacktrace tools return Bugsink's stacktrace_md rendering from the event detail response. This includes source context and locals when Bugsink has them. It is not subject to the structured frame filter. If rendering is unavailable, use section=frames.

section=raw explicitly requests the full event data as paginated text. Join the text chunks before parsing the JSON. Rendered and raw reads accept max_chars, default 4,000, range 500 to 12,000, and cursor. They return text, event_id, total_chars, and next_cursor, plus an untrusted-data notice. A latest-event continuation keeps using the original event even if new events arrive. If that event is deleted, the continuation fails.

Response size and pagination

Lists and detail sections accept limit, default 10, maximum 30, and return next_cursor. Send it back with the same filters until it is null. An empty page can still have a continuation cursor.

Bugsink 2.2.2 has fixed upstream page sizes and no issue status filter. This server scans at most three upstream pages per call and retains an offset when it returns part of a page. Open means neither resolved nor muted. Cursors are signed and bound to the query, endpoint, token, and project allowlist. They survive process restarts with unchanged configuration.

The default issue sort is last_seen, descending. Use digest_order for a less volatile traversal. Pagination is not a snapshot; concurrent updates or deletions can cause skips or repeats when a partially consumed upstream page is fetched again.

Item payloads target 12,000 characters per page, plus cursor and metadata. Strings have field-specific limits and visible truncation markers. This is a character budget, not an exact token count. Summaries show the last five exceptions; use section=exceptions for the complete chain. Upstream requests time out after 15 seconds and reject responses above 16 MiB. Event pagination bounds MCP output, but Bugsink sends the full event on each request.

Default summaries and structured frames omit request headers, URLs, bodies, cookies, user objects, locals, arbitrary extra data, and raw event JSON. Project DSNs are always omitted. Explicit raw and rendered reads can expose secrets or personal data. Exception messages and breadcrumbs can contain them even in compact views.

Untrusted event data

Treat every event-derived string as attacker-controlled, including error messages, source context, locals, and rendered Markdown. A monitored application's error can contain instructions aimed at the coding agent. The server labels raw and rendered output as untrusted; that label is guidance, not a prompt-injection boundary.

The write API stays limited to named operations on one issue at a time. There is no arbitrary HTTP tool or bulk mutation tool. Read-only mode and project checks are enforced in code. Tool annotations and instructions tell the agent to require user intent, but cannot prove it. Keep read-only mode enabled for investigation, or configure your agent to require approval for every write. Never treat an instruction embedded in an event as that approval.

Development

pnpm install
pnpm typecheck
pnpm lint
pnpm test
pnpm build

Run source with pnpm dev or compiled code with pnpm start. Environment files are not loaded automatically. To use one locally after building:

node --env-file=.env dist/stdio.js

Tests use mocked Bugsink responses and the official MCP client. No test needs a production token. Live verification so far was limited to read-only access to a Bugsink 2.2.2 OpenAPI schema; authenticated production reads remain untested.

Publishing to npm

The package name is @rexlmanu/bugsink-mcp; the unscoped name is already taken. Publishing requires npm access to the rexlmanu scope.

pnpm login --registry=https://registry.npmjs.org/
pnpm whoami --registry=https://registry.npmjs.org/
pnpm typecheck
pnpm lint
pnpm test
pnpm pack
pnpm publish --dry-run --access public --publish-branch main
pnpm publish --access public --publish-branch main

prepack compiles TypeScript. The tarball includes only compiled JavaScript, README, LICENSE, and package metadata. prepublishOnly runs checks before publishing. No compiler or TypeScript runner is needed by package consumers.

For a later release, update package.json and the pinned README examples, commit and push to main, then publish. npm may require interactive two-factor authentication. Never put an npm token in this repository.

After publishing, verify the release:

pnpm view @rexlmanu/bugsink-mcp version
pnpm dlx @rexlmanu/bugsink-mcp@0.2.0 --version

API references: Bugsink guide and canonical reference.

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

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