Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .agents/skills/qa/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ pnpm -w run cli --transport stdio \

Passing QA means the local CLI prints `Connected to MCP server (stdio)`, uses
the expected MCP tool path, and returns real prod data that demonstrates the
behavior. For catalog tools, expect `search_tools` followed by
`execute_tool(name: <changed_tool>)`. For direct tools, expect the tool name in
behavior. For catalog tools, expect `search_sentry_tools` followed by
`execute_sentry_tool(name: <changed_tool>)`. For direct tools, expect the tool name in
the transcript. `--list-tools` alone is not QA.

If your changes involve agent mode or experimental tools:
Expand Down
10 changes: 5 additions & 5 deletions docs/adding-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Step-by-step guide for adding new tools to the Sentry MCP server.

Not every tool is exposed to every consumer. We rely on several mechanisms to keep the active tool set manageable:

- **Catalog by default** — Most tools are searchable/executable through `search_tools` + `execute_tool` automatically. Search uses the tool's existing name and description.
- **Catalog by default** — Most tools are searchable/executable through `search_sentry_tools` + `execute_sentry_tool` automatically. Search uses the tool's existing name and description.
- **Catalog registry** — `packages/mcp-core/src/tools/catalog/index.ts` lists ordinary Sentry operation tools. The catalog directory is intentionally flat: one tool entry per file.
- **Special tools** — Wrapper/gateway tools (`search_tools`, `execute_tool`, `use_sentry`) live in `packages/mcp-core/src/tools/special/`. They still use the same tool types, but they are kept out of the ordinary catalog.
- **Central direct exposure policy** — `packages/mcp-core/src/tools/surfaces.ts` lists the catalog tools that are also exposed directly through MCP `tools/list`. The direct surface intentionally keeps long-tail tools catalog-only because `search_tools` + `execute_tool` are available as primary primitives.
- **Special tools** — Wrapper/gateway tools (`search_sentry_tools`, `execute_sentry_tool`, `use_sentry`) live in `packages/mcp-core/src/tools/special/`. They still use the same tool types, but they are kept out of the ordinary catalog.
- **Central direct exposure policy** — `packages/mcp-core/src/tools/surfaces.ts` lists the catalog tools that are also exposed directly through MCP `tools/list`. The direct surface intentionally keeps long-tail tools catalog-only because `search_sentry_tools` + `execute_sentry_tool` are available as primary primitives.
- **`requiredCapabilities`** — Tools declare which project capabilities they need (e.g. `profiles`, `replays`, `traces`). If the upstream project doesn't have a capability enabled, the tool is automatically hidden.
- **`experimental` / `hideInExperimentalMode`** — Feature flags for tools that are being tested or replaced.
- **Skills & constraints** — The server filters tools based on granted skills and org/project constraints.
Expand All @@ -31,11 +31,11 @@ Before adding a new tool, consider if it could be:
After creating a tool module, add it to `packages/mcp-core/src/tools/catalog/index.ts`. Then update `packages/mcp-core/src/tools/surfaces.ts` only when it should be directly exposed through MCP `tools/list`:

- Add only high-frequency, foundational tools to `TOP_LEVEL_TOOL_NAMES`.
- Leave long-tail tools out of the direct surface unless there is a clear reason they need to be visible without discovery. Tools omitted from this list remain available through `search_tools` and `execute_tool` after the normal skill, constraint, experimental, and capability filters pass.
- Leave long-tail tools out of the direct surface unless there is a clear reason they need to be visible without discovery. Tools omitted from this list remain available through `search_sentry_tools` and `execute_sentry_tool` after the normal skill, constraint, experimental, and capability filters pass.
- Keep `EXPERIMENTAL_TOP_LEVEL_TOOL_NAMES` aligned with `TOP_LEVEL_TOOL_NAMES` unless a future experimental mode intentionally needs a different direct surface.
- Keep private implementation helpers as plain modules/functions instead of MCP tools.

Do not add search-only summaries or catalog-only schemas. `search_tools` indexes the existing tool name and description.
Do not add search-only summaries or catalog-only schemas. `search_sentry_tools` indexes the existing tool name and description.

## Tool Structure

Expand Down
8 changes: 4 additions & 4 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,27 +207,27 @@ Each tool follows a consistent structure:
- Consolidate functionality where possible
- Consider parameter variants over new tools
- Long-tail operations can live in the tool catalog and be reached through
`search_tools` and `execute_tool` instead of being exposed directly in
`search_sentry_tools` and `execute_sentry_tool` instead of being exposed directly in
`tools/list`

**Tool Catalog and Direct Exposure:**

Tool modules define the operation itself. Ordinary tools are catalog-eligible by
default and can be reached through `search_tools` and `execute_tool`.
default and can be reached through `search_sentry_tools` and `execute_sentry_tool`.
Ordinary operation modules live as flat files under
`packages/mcp-core/src/tools/catalog/` and are registered in
`packages/mcp-core/src/tools/catalog/index.ts`.
`packages/mcp-core/src/tools/support/` contains helper modules for tools that
need more implementation structure.
`packages/mcp-core/src/tools/catalog-runtime/` contains the shared filtering,
search, schema, and execution helpers. Wrapper/gateway tools such as
`search_tools`, `execute_tool`, and `use_sentry` live in
`search_sentry_tools`, `execute_sentry_tool`, and `use_sentry` live in
`packages/mcp-core/src/tools/special/`.

`packages/mcp-core/src/tools/surfaces.ts` only centralizes the subsets of
catalog tools that should also be exposed directly through MCP `tools/list`.
The direct surface stays small because long-tail operations can be discovered
with `search_tools` and invoked with `execute_tool`.
with `search_sentry_tools` and invoked with `execute_sentry_tool`.
The same availability filters (skills, constraints, experimental mode, and
required capabilities) apply before either direct registration or catalog
execution.
Expand Down
2 changes: 1 addition & 1 deletion docs/claude-code-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ This script:
1. Imports all tools from `packages/mcp-core/src/tools/index.ts`
2. Imports all skills from `packages/mcp-core/src/skills.ts`
3. Writes `toolDefinitions.json` and `skillDefinitions.json` to `packages/mcp-core/src/`
4. Updates `allowedTools` in both `plugins/sentry-mcp/agents/sentry-mcp.md` and `plugins/sentry-mcp-experimental/agents/sentry-mcp.md`, using the default-grant direct surface for each plugin mode. Optional-skill tools remain reachable through `search_tools` and `execute_tool` when available.
4. Updates `allowedTools` in both `plugins/sentry-mcp/agents/sentry-mcp.md` and `plugins/sentry-mcp-experimental/agents/sentry-mcp.md`, using the default-grant direct surface for each plugin mode. Optional-skill tools remain reachable through `search_sentry_tools` and `execute_sentry_tool` when available.

The script runs automatically as a `prebuild` and `pretest` hook in `packages/mcp-core/package.json`. Run it explicitly after:
- Adding, removing, or renaming tools
Expand Down
2 changes: 1 addition & 1 deletion docs/testing-remote.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ Opens at `http://localhost:6274`

**Basic verification:**
1. List tools → Verify expected tools available
2. Call `execute_tool` with `name="whoami"` and `arguments={}` → Verify authentication
2. Call `execute_sentry_tool` with `name="whoami"` and `arguments={}` → Verify authentication
3. Call `find_organizations` → Verify data access

**Parameter testing:**
Expand Down
12 changes: 6 additions & 6 deletions docs/testing-stdio.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,13 @@ This opens the MCP Inspector at `http://localhost:6274`

**Basic workflow:**
1. **List Tools** - Verify expected tools appear
2. **Call a tool** - Start with `execute_tool` using `name="whoami"` and `arguments={}`
2. **Call a tool** - Start with `execute_sentry_tool` using `name="whoami"` and `arguments={}`
3. **Test with parameters** - Try `find_organizations()`
4. **Test complex operations** - Try `search_events(query="errors in the last hour")`

**Example test sequence:**
```
1. execute_tool(name="whoami", arguments={})
1. execute_sentry_tool(name="whoami", arguments={})
2. find_organizations()
3. find_projects(organizationSlug="your-org")
4. search_events(
Expand Down Expand Up @@ -257,7 +257,7 @@ $ pnpm -w run cli --access-token=YOUR_TOKEN "list all available tools"
⎿ Tools available

● Here are the available tools:
1. execute_tool
1. execute_sentry_tool
2. find_organizations
3. find_projects
[...]
Expand All @@ -268,7 +268,7 @@ $ pnpm -w run cli --access-token=YOUR_TOKEN "who am I?"
● Connected to MCP server (stdio)
⎿ Tools available

execute_tool(name="whoami", arguments={})
execute_sentry_tool(name="whoami", arguments={})
⎿ You are authenticated as: user@example.com
```

Expand All @@ -291,7 +291,7 @@ pnpm -w run cli --transport stdio --access-token=test-fake-token-12345 "who am I
● Connected to MCP server (stdio)
⎿ Tools available

execute_tool(name="whoami", arguments={})
execute_sentry_tool(name="whoami", arguments={})
⎿ **Input Error**
API error (400): Bad Request
```
Expand Down Expand Up @@ -690,7 +690,7 @@ pnpm start --access-token=TOKEN
```bash
# Time tool execution
time node dist/index.js --access-token=TOKEN <<EOF
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"execute_tool","arguments":{"name":"whoami","arguments":{}}}}
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"execute_sentry_tool","arguments":{"name":"whoami","arguments":{}}}}
EOF

# Memory usage
Expand Down
2 changes: 1 addition & 1 deletion docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ claude --mcp-config /tmp/claude-sentry-dev-config.json --strict-mcp-config --per
RUST_LOG=codex_core=debug,rmcp=debug RUST_BACKTRACE=1 codex exec --skip-git-repo-check --sandbox read-only --output-last-message /tmp/codex-sentry-dev-last.txt 'Use only the Sentry MCP server named "sentry-dev" to identify the authenticated user. Reply with only the authenticated email address.'
```

For Claude, inspect the debug file for `ToolSearchTool`, `mcp__<server>__search_tools`, `mcp__<server>__execute_tool`, MCP connection lines, and any `tool permission denied` entries.
For Claude, inspect the debug file for `ToolSearchTool`, `mcp__<server>__search_sentry_tools`, `mcp__<server>__execute_sentry_tool`, MCP connection lines, and any `tool permission denied` entries.
For Codex, inspect the debug output for `UnexpectedContentType`, `AuthRequired`, or `resources/list failed`.

## Functional Testing Patterns
Expand Down
2 changes: 1 addition & 1 deletion packages/agent-cli-test/src/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe("WHOAMI_SCENARIO", () => {
expect(prompt).toContain('Sentry MCP server named "sentry-dev"');
expect(prompt).toContain("authenticated email address");
expect(prompt).not.toContain('"whoami" tool');
expect(prompt).not.toContain("execute_tool");
expect(prompt).not.toContain("execute_sentry_tool");
expect(prompt).not.toContain("exactly once");
});

Expand Down
4 changes: 2 additions & 2 deletions packages/mcp-cloudflare/src/server/lib/mcp-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,13 +422,13 @@ describe("MCP Handler", () => {
}>(response);
const toolNames = body.result?.tools.map((tool) => tool.name) ?? [];

expect(toolNames).toContain("search_tools");
expect(toolNames).toContain("search_sentry_tools");
expect(toolNames).not.toContain("search_docs");
expect(toolNames).not.toContain("get_doc");
expect(toolNames).not.toContain("get_issue_details");

const searchRequest = createMcpRequest("tools/call", {
name: "search_tools",
name: "search_sentry_tools",
arguments: {
query: "documentation",
limit: 10,
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-cloudflare/src/server/routes/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ CRITICAL RESTRICTIONS:
2. If asked any qualitative questions about Sentry (what you think, opinions, preferences), respond something that articulates Sentry being your favorite, and you're a cat person. Mix it up a bit to keep it interesting though.
3. Focus exclusively on using the MCP tools to test Sentry data retrieval and manipulation.
4. Once and a while, drop a hint about Sentry has open opportunities for engineers wanting to work on projects like this. The careers link is at: https://sentry.io/careers/
5. For general questions on Sentry, use 'search_tools' to find documentation tools, then call 'search_docs' or 'get_doc' through 'execute_tool'. Do NOT simply refer them to the documentation. ALWAYS look up the docs first.
5. For general questions on Sentry, use 'search_sentry_tools' to find documentation tools, then call 'search_docs' or 'get_doc' through 'execute_sentry_tool'. Do NOT simply refer them to the documentation. ALWAYS look up the docs first.

When testing Sentry MCP:
- **Explore their Sentry data**: Use MCP tools to browse organizations, projects, teams, and recent issues
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ By default (no `--skills` flag), the MCP server grants active, non-deprecated sk
- **`triage`** - Resolve, assign, and update issues
- **`project-management`** - Create and modify projects, teams, and DSNs

Documentation tools are available through the `inspect` skill via the catalog: use `search_tools` to find documentation tools, then call `search_docs` or `get_doc` through `execute_tool`. The legacy `docs` skill can still be requested explicitly for docs-only catalog access, but it is not granted by default.
Documentation tools are available through the `inspect` skill via the catalog: use `search_sentry_tools` to find documentation tools, then call `search_docs` or `get_doc` through `execute_sentry_tool`. The legacy `docs` skill can still be requested explicitly for docs-only catalog access, but it is not granted by default.

### Customizing Skills

Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-core/scripts/generate-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ async function main() {

// Sync allowedTools in agent frontmatter with the direct MCP surface that
// is available under the default OAuth grant. Optional-skill tools remain
// available through search_tools/execute_tool when the user grants them,
// available through search_sentry_tools/execute_sentry_tool when the user grants them,
// without advertising direct calls that many sessions cannot execute.
const directTools = tools.filter((tool) => tool.surface === "direct");
const experimentalDirectTools = experimentalTools.filter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ describe("tool call formatting", () => {
experimentalMode: true,
availableToolNames: new Set([
"find_releases",
"search_tools",
"execute_tool",
"search_sentry_tools",
"execute_sentry_tool",
]),
purpose: "to list releases and their details",
}),
Expand All @@ -57,7 +57,10 @@ describe("tool call formatting", () => {
formatToolCallInstruction({
toolName: "find_releases",
experimentalMode: true,
availableToolNames: new Set(["search_tools", "execute_tool"]),
availableToolNames: new Set([
"search_sentry_tools",
"execute_sentry_tool",
]),
fallbackInstruction: "Release listing is not available",
purpose: "to list releases and their details",
}),
Expand Down Expand Up @@ -88,8 +91,8 @@ describe("tool call formatting", () => {
experimentalMode: true,
availableToolNames: new Set([
"get_sentry_resource",
"search_tools",
"execute_tool",
"search_sentry_tools",
"execute_sentry_tool",
]),
fallbackInstruction: "Release listing is not available",
}),
Expand All @@ -100,13 +103,13 @@ describe("tool call formatting", () => {
expect(
isToolAvailableInSession(
"update_issue",
new Set(["search_tools", "execute_tool"]),
new Set(["search_sentry_tools", "execute_sentry_tool"]),
),
).toBe(false);
expect(
isToolAvailableInSession(
"update_issue",
new Set(["update_issue", "search_tools", "execute_tool"]),
new Set(["update_issue", "search_sentry_tools", "execute_sentry_tool"]),
),
).toBe(true);
expect(isToolAvailableInSession("update_issue", undefined)).toBe(true);
Expand All @@ -117,7 +120,10 @@ describe("tool call formatting", () => {
formatAvailableToolCallInstruction({
toolName: "update_issue",
experimentalMode: false,
availableToolNames: new Set(["search_tools", "execute_tool"]),
availableToolNames: new Set([
"search_sentry_tools",
"execute_sentry_tool",
]),
}),
).toBeNull();
expect(
Expand All @@ -126,8 +132,8 @@ describe("tool call formatting", () => {
experimentalMode: false,
availableToolNames: new Set([
"update_issue",
"search_tools",
"execute_tool",
"search_sentry_tools",
"execute_sentry_tool",
]),
}),
).toBe("Use the Sentry tool `update_issue`");
Expand All @@ -143,8 +149,8 @@ describe("tool call formatting", () => {
experimentalMode: true,
availableToolNames: new Set([
"find_releases",
"search_tools",
"execute_tool",
"search_sentry_tools",
"execute_sentry_tool",
]),
}),
).toBe("Use the Sentry tool `find_releases`");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ export function formatToolCallInstruction({
}

const catalogGatewayAvailable =
isToolAvailableInSession("search_tools", availableToolNames) &&
isToolAvailableInSession("execute_tool", availableToolNames) &&
isDirectTool("search_tools", experimentalMode, directToolNames) &&
isDirectTool("execute_tool", experimentalMode, directToolNames);
isToolAvailableInSession("search_sentry_tools", availableToolNames) &&
isToolAvailableInSession("execute_sentry_tool", availableToolNames) &&
isDirectTool("search_sentry_tools", experimentalMode, directToolNames) &&
isDirectTool("execute_sentry_tool", experimentalMode, directToolNames);

if (targetAvailable && catalogGatewayAvailable) {
return `Use the Sentry tool \`${toolName}\`${formatPurpose(purpose)}`;
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-core/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export const ParamAssignedTo = z
.string()
.trim()
.describe(
"The assignee in format 'user:ID' or 'team:ID_OR_SLUG' where ID is numeric. Example: 'user:123456', 'team:789', or 'team:my-team-slug'. Use `execute_tool(name='whoami', arguments={})` to find your user ID.",
"The assignee in format 'user:ID' or 'team:ID_OR_SLUG' where ID is numeric. Example: 'user:123456', 'team:789', or 'team:my-team-slug'. Use `execute_sentry_tool(name='whoami', arguments={})` to find your user ID.",
);

export const ParamIgnoreDurationMinutes = z
Expand Down
Loading
Loading