Read-only Sentry tools: project listing, issue search at organization or project scope, single issue detail, and the latest or a specific event with a trimmed stacktrace. Local variables, request headers and bodies, query strings, packages and secret-looking tags are removed before the event reaches the model, and oversized events degrade through source context, breadcrumbs and frames rather than failing.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-sentry
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:maxmilian/dsh-sentry
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
dsh-sentry is a free, open-source, read-only DeepSeek Harness plugin for the Sentry Web API.
Every tool is an HTTP GET; the plugin never resolves, assigns, archives, or otherwise changes
Sentry state.
Its main job is not proxying the API — it is trimming responses so an agent's context survives a
real stacktrace. A raw events/latest/ payload is routinely 200KB–2MB. This plugin reduces it to
the frames, source lines, and metadata that actually help debugging, and tells you in meta.trimmed
what it had to leave out.
Tools
| Tool | Purpose |
|---|---|
sentry_list_projects |
List up to 100 projects in the configured organization. |
sentry_search_issues |
Search issues with Sentry search syntax, in one project or the whole organization. |
sentry_get_issue |
Read one issue by numeric id or short id, without event bodies. |
sentry_get_latest_event |
Read an issue's latest event with a trimmed stacktrace. |
sentry_get_event |
Read one event by id within a project, with the same trimming. |
All tools are read-only. Version 0.1 does not modify issues, create releases, or send events.
Requirements
- DeepSeek Harness with compatible
@deepseek-ai/dsh-toolsAPIs - Node.js 22.19 or newer in the 22.x line, or Node.js 24 or newer
- Bun 1.3.5 or newer when installing from GitHub source or developing locally
- A Sentry User Auth Token (
sntryu_) with read access to the requested organization
Token scopes
| Scope | Unlocks |
|---|---|
org:read |
/organizations/{org}/projects/, /organizations/{org}/issues/, /organizations/{org}/shortids/{short_id}/ |
project:read |
/projects/{org}/{project}/issues/ |
event:read |
/issues/{id}/, /issues/{id}/events/latest/, /projects/{org}/{project}/events/{event_id}/ |
Use a User Auth Token (sntryu_) with event:read, org:read, and project:read. The
simplest safe one comes from sentry auth login --read-only, which requests exactly
project:read, org:read, event:read, member:read, and team:read.
An Organization Auth Token (sntrys_) does not work: Sentry fixes its scope set to org:ci
(Source Map Upload, Release Creation, Code Mappings) with no way to add read scopes, so every read
path here returns HTTP 403. Verified against sentry.io on 2026-08-27 — see
docs/live-verification.md.
Configuration
| Field | Environment variable | Default | Notes |
|---|---|---|---|
baseUrl |
SENTRY_URL |
https://sentry.io/ |
Site root URL. Use https://de.sentry.io/ for the EU region. A trailing /api/0 is stripped automatically. |
token |
SENTRY_AUTH_TOKEN |
required | User auth token (sntryu_). Organization auth tokens are org:ci-only and are rejected with 403. Never returned or logged. |
org |
SENTRY_ORG |
required | Organization slug. Fixed for the whole plugin instance. |
locale |
— | en |
en, zh-TW, zh-CN, or ja. Selects the language of tool and parameter descriptions. |
includeFrameVars |
SENTRY_INCLUDE_FRAME_VARS |
false |
Keep stack frame local variables. Only the literal string true enables it. Agents cannot override this. |
requestTimeoutMs |
— | 30000 |
Deadline for one whole tool call, including the extra request a short id costs. Range 1–300000. |
maxResponseBytes |
— | 5242880 |
Hard cap on a single HTTP response body. Range 1–52428800. |
Plugin configuration always wins over environment variables.
export SENTRY_AUTH_TOKEN='your-token'
export SENTRY_ORG='your-org'
# self-hosted or EU region only:
export SENTRY_URL='https://sentry.example.com'
Self-hosted and regions
- Self-hosted: point
baseUrlat the site root, including a sub-path install such ashttps://example.com/sentry/. - Sentry SaaS EU region:
baseUrlmust behttps://de.sentry.io/. Usinghttps://sentry.io/for an EU organization surfaces as a 401 or 404, so both of those error messages repeat the region hint. - Older self-hosted versions simply return fewer fields. The plugin treats every response field as
optional and never fails because one is missing. Two known behavior differences:
sort=recommendedcan be rejected (reported asUNSUPPORTED_BY_INSTANCE), andstats_periodis limited to24hand14d.
What gets trimmed
Removed from every event, unconditionally:
- Request headers, cookies, environment, and body. The request URL keeps only origin and path — the query string is dropped whole, because OAuth callbacks and signed URLs carry secrets there.
- Stack frame local variables, unless
includeFrameVarsis on. mechanism.data,contexts.state,packages,modules, and_meta.user.email,user.ip_address, anduser.username. Onlyuser.idsurvives.- Any tag whose key looks like a secret or direct PII (
token,secret,password,passwd,api_key,auth,cookie,session,credential, private/access keys, JWT, DSN, signature, email, IP address, or username), plus everysentry:-prefixed internal tag. - Frame fields that leak build paths, such as
absPath.
Reduced rather than removed:
- Frames. Frames run outermost to innermost. When there are more than
max_frames, the plugin prioritizes in-app frames, always includes the two innermost frames, fills from the tail when room remains, and never exceeds the cap. Output preserves the original order. - Source context. Kept only for the three innermost in-app frames, at most 11 lines each, each line capped at 200 characters.
- Chained exceptions. At most the two innermost
exception.values;max_framesapplies to each stacktrace separately. - Breadcrumbs. The last 20, messages capped at 200 characters.
- Strings. Exception values cap at 2000 characters; titles, messages, and culprits at 500.
If the result still exceeds the 200KB tool-result budget, the plugin degrades in fixed steps —
source context, then breadcrumbs, then frames down to at most 10 without raising a lower caller cap. If administrator-enabled frame variables
still make the result too large, they are removed as a final fallback. The last step is reported in
meta.trimmed.degraded. Counters such as omittedFrames are always "original total minus what you
received", never a running tally.
Localization
Tool and parameter descriptions follow locale. Tool names are always English and never change,
because they are the agent's calling identifiers. Error messages are always English as well: they
are stable diagnostic strings that tests and reviews compare against.
Security and error behavior
- Uses
Authorization: Bearer ...and never returns or logs the token. - Honors the DSH tool
AbortSignaland a per-call deadline; a short id costs a second HTTP request but shares the same deadline. - Converts HTTP 401, 403, 404, 429, and 5xx into safe structured errors that never carry a response body.
- One deliberate exception: on HTTP 400 from an issue search, the plugin reads at most 64KB of
the body, takes only the structured
detailorerrorstring, drops it entirely if it contains the token or looks like it carries a secret, caps it at 200 characters, and appends it asSentry said: .... Without that, an agent can only guess at a search-syntax error. When the body is HTML, unparseable, or filtered out, the message falls back to the static form — soINVALID_QUERYmessages come in two shapes. - Does not support disabling TLS verification or self-signed certificate bypass in v0.1.
Limitations (v0.1)
- No writes of any kind: no resolve, unresolve, archive, assign, merge, delete, release creation, or event ingestion.
- One organization per plugin instance; tools do not accept an organization parameter.
- No Seer AI, Performance, Discover, Metrics, Dashboards, Replay, Trace, or Span endpoints.
- No release, deploy, or issue-tag-distribution queries.
stats_periodis limited to24hand14d; customstart/endranges are not supported.- No automatic pagination.
sentry_search_issuesreturns one page plusmeta.nextCursor;sentry_list_projectsaccepts no cursor at all and reportsmeta.truncatedinstead. - No local caching, no attachment or source map downloads, and no raw passthrough mode.
Development
This project uses Bun as its package manager and script runner; the published plugin runtime targets the Node.js versions listed above:
bun install --frozen-lockfile
bun run lint
bun run typecheck
bun run test --coverage
bun run build
bun pm pack
Tests use Vitest with mocked fetch and do not require a live Sentry instance. Coverage gates for
lines, statements, functions, and branches are all set to at least 80%.
Live compatibility against Sentry SaaS and a self-hosted instance has not been recorded for this
release yet. The checklist required before tagging v0.1.0 lives in
docs/live-verification.md; run it against your own instance with:
bun run build
SENTRY_TOKEN=... SENTRY_ORG=... node scripts/live-verify.mjs
The script is read-only and exits 1 when credentials are missing.
License
MIT
Links
More in this category
yjh051108/dsh-routing-suite★ 7014
One repository, three parts: a runtime injector for DSH plugin packages (inject, hot-reload, unload, promote a dev staging tool to the front, route self-heal, plus a settings-page plugin manager that lists, unloads and drags folders in to internalize), a task-aware reasoning-mode router agent preset (router-standard / router-spec / router-react), and a graded two-level task protocol whose six tools (commit_star, lock_stage, revise_do, edit_plan, mark_task, redteam_verdict) pin task state to disk. The injector implementation ships in-tree, so the install carries its own behaviour rather than a dependency list.
strukto-ai/mirage#dsh★ 3682
Swaps the filesystem and bash providers for a mirage virtual workspace: file tools and shell commands run over mounted resources (RAM, S3, Redis, Slack, Gmail, Notion, Postgres) instead of the host disk, with per-mount read/write/exec modes, per-command sandbox routing (monty, pyodide, quickjs in process; docker, e2b, daytona remote), and installed CLIs (git, gh, slack, linear, ntn, gws, or one you register) as head words in the virtual terminal.
hust-open-atom-club/oh-dsh★ 322
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
weijiafu14/pi2dsh★ 212
Pi Host ABI compatibility engine: after one install, unmodified Pi extensions from npm mount as native DSH plugins with `dsh plugin add <pi-package>`. Verified end to end on stock DSH with pi-mcp-adapter (full MCP manager: OAuth, resources, prompts, MCP Apps, elicitation, sampling), @tintinweb/pi-subagents, pi-code, pi-hermes-memory and pi-background-tasks; `pi2dsh inspect` reports a package's compatibility before installing.
Fishquito7/dsh-skill-mcp-panel★ 193
Manages DSH skills and MCP servers from the web settings: skill cards with hot enable/disable, workspace scopes, groups, batch migration and drag-and-drop import, plus stdio/HTTP MCP CRUD with connection tests, secret redaction and the unified dsh-panel CLI.
lire1131/dsh-undo-savepoint★ 179
Undo/redo & rollback system for DSH: every config change is auto-snapshotted; undo/redo/restore to any version from the WebUI or the offline CLI/GUI tools (works even when DSH fails to boot).
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.