@tokamohsen/sentry-mcp 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/chunk-C0xms8kb.cjs +34 -0
  2. package/dist/cli/parse-EvLqDjN2.d.cts +11 -0
  3. package/dist/cli/parse-EvLqDjN2.d.cts.map +1 -0
  4. package/dist/cli/parse-M8aGwIO5.d.ts +11 -0
  5. package/dist/cli/parse-M8aGwIO5.d.ts.map +1 -0
  6. package/dist/cli/parse.cjs +107 -0
  7. package/dist/cli/parse.cjs.map +1 -0
  8. package/dist/cli/parse.js +103 -0
  9. package/dist/cli/parse.js.map +1 -0
  10. package/dist/cli/resolve-C3hwH129.d.cts +10 -0
  11. package/dist/cli/resolve-C3hwH129.d.cts.map +1 -0
  12. package/dist/cli/resolve-kNjr_UaF.d.ts +10 -0
  13. package/dist/cli/resolve-kNjr_UaF.d.ts.map +1 -0
  14. package/dist/cli/resolve.cjs +57 -0
  15. package/dist/cli/resolve.cjs.map +1 -0
  16. package/dist/cli/resolve.js +54 -0
  17. package/dist/cli/resolve.js.map +1 -0
  18. package/dist/cli/types-B2hDXVnQ.d.ts +73 -0
  19. package/dist/cli/types-B2hDXVnQ.d.ts.map +1 -0
  20. package/dist/cli/types-VWgo1wm6.d.cts +73 -0
  21. package/dist/cli/types-VWgo1wm6.d.cts.map +1 -0
  22. package/dist/cli/types.cjs +0 -0
  23. package/dist/cli/types.js +1 -0
  24. package/dist/cli/usage-B0gAPy4S.d.cts +9 -0
  25. package/dist/cli/usage-B0gAPy4S.d.cts.map +1 -0
  26. package/dist/cli/usage-BMxqEEQ3.d.ts +9 -0
  27. package/dist/cli/usage-BMxqEEQ3.d.ts.map +1 -0
  28. package/dist/cli/usage.cjs +47 -0
  29. package/dist/cli/usage.cjs.map +1 -0
  30. package/dist/cli/usage.js +45 -0
  31. package/dist/cli/usage.js.map +1 -0
  32. package/dist/index-16fTC-hT.d.cts +1 -0
  33. package/dist/index-DgNgxUxv.d.ts +1 -0
  34. package/dist/index.cjs +208 -0
  35. package/dist/index.cjs.map +1 -0
  36. package/dist/index.js +207 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/transports/stdio-DVcJU1wB.d.ts +37 -0
  39. package/dist/transports/stdio-DVcJU1wB.d.ts.map +1 -0
  40. package/dist/transports/stdio-DeWUp4RP.d.cts +37 -0
  41. package/dist/transports/stdio-DeWUp4RP.d.cts.map +1 -0
  42. package/dist/transports/stdio.cjs +74 -0
  43. package/dist/transports/stdio.cjs.map +1 -0
  44. package/dist/transports/stdio.js +71 -0
  45. package/dist/transports/stdio.js.map +1 -0
  46. package/package.json +69 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-B0gAPy4S.d.cts","names":[],"sources":["../../src/cli/usage.ts"],"sourcesContent":[],"mappings":";;;iBAEgB,UAAA,iCAEH,cAAc"}
@@ -0,0 +1,9 @@
1
+ import { Skill } from "@sentry/mcp-core/skills";
2
+
3
+ //#region src/cli/usage.d.ts
4
+ declare function buildUsage(packageName: string, allSkills: ReadonlyArray<Skill>): string;
5
+ //# sourceMappingURL=usage.d.ts.map
6
+
7
+ //#endregion
8
+ export { buildUsage };
9
+ //# sourceMappingURL=usage-BMxqEEQ3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-BMxqEEQ3.d.ts","names":[],"sources":["../../src/cli/usage.ts"],"sourcesContent":[],"mappings":";;;iBAEgB,UAAA,iCAEH,cAAc"}
@@ -0,0 +1,47 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/cli/usage.ts
4
+ function buildUsage(packageName, allSkills) {
5
+ return `Usage: ${packageName} --access-token=<token> [--host=<host>]
6
+
7
+ Required:
8
+ --access-token <token> Sentry User Auth Token with API access
9
+
10
+ Common optional flags:
11
+ --host <host> Change Sentry host (self-hosted)
12
+ --sentry-dsn <dsn> Override DSN used for telemetry reporting
13
+ --agent Agent mode: only expose use_sentry tool (for AI agents)
14
+ --experimental Enable experimental tools (hidden by default)
15
+
16
+ Embedded agent configuration:
17
+ --agent-provider <provider> LLM provider: openai or anthropic (auto-detects from API keys)
18
+ --openai-base-url <url> Override OpenAI API base URL
19
+ --openai-model <model> Override OpenAI model (default: gpt-5)
20
+ --anthropic-base-url <url> Override Anthropic API base URL
21
+ --anthropic-model <model> Override Anthropic model (default: claude-sonnet-4-5)
22
+
23
+ Session constraints:
24
+ --organization-slug <slug> Force all calls to an organization
25
+ --project-slug <slug> Optional project constraint
26
+
27
+ Skill controls:
28
+ --skills <list> Specify which skills to grant (default: all skills)
29
+
30
+ All skills: ${allSkills.join(", ")}
31
+
32
+ Environment variables:
33
+ SENTRY_ACCESS_TOKEN Sentry auth token (alternative to --access-token)
34
+ OPENAI_API_KEY OpenAI API key for AI-powered search tools
35
+ ANTHROPIC_API_KEY Anthropic API key for AI-powered search tools
36
+ EMBEDDED_AGENT_PROVIDER Provider override: openai or anthropic
37
+
38
+ Examples:
39
+ ${packageName} --access-token=TOKEN
40
+ ${packageName} --access-token=TOKEN --skills=inspect,triage
41
+ ${packageName} --access-token=TOKEN --host=sentry.example.com
42
+ ${packageName} --access-token=TOKEN --agent-provider=anthropic`;
43
+ }
44
+
45
+ //#endregion
46
+ exports.buildUsage = buildUsage;
47
+ //# sourceMappingURL=usage.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.cjs","names":[],"sources":["../../src/cli/usage.ts"],"sourcesContent":["import type { Skill } from \"@sentry/mcp-core/skills\";\n\nexport function buildUsage(\n packageName: string,\n allSkills: ReadonlyArray<Skill>,\n): string {\n return `Usage: ${packageName} --access-token=<token> [--host=<host>]\n\nRequired:\n --access-token <token> Sentry User Auth Token with API access\n\nCommon optional flags:\n --host <host> Change Sentry host (self-hosted)\n --sentry-dsn <dsn> Override DSN used for telemetry reporting\n --agent Agent mode: only expose use_sentry tool (for AI agents)\n --experimental Enable experimental tools (hidden by default)\n\nEmbedded agent configuration:\n --agent-provider <provider> LLM provider: openai or anthropic (auto-detects from API keys)\n --openai-base-url <url> Override OpenAI API base URL\n --openai-model <model> Override OpenAI model (default: gpt-5)\n --anthropic-base-url <url> Override Anthropic API base URL\n --anthropic-model <model> Override Anthropic model (default: claude-sonnet-4-5)\n\nSession constraints:\n --organization-slug <slug> Force all calls to an organization\n --project-slug <slug> Optional project constraint\n\nSkill controls:\n --skills <list> Specify which skills to grant (default: all skills)\n\nAll skills: ${allSkills.join(\", \")}\n\nEnvironment variables:\n SENTRY_ACCESS_TOKEN Sentry auth token (alternative to --access-token)\n OPENAI_API_KEY OpenAI API key for AI-powered search tools\n ANTHROPIC_API_KEY Anthropic API key for AI-powered search tools\n EMBEDDED_AGENT_PROVIDER Provider override: openai or anthropic\n\nExamples:\n ${packageName} --access-token=TOKEN\n ${packageName} --access-token=TOKEN --skills=inspect,triage\n ${packageName} --access-token=TOKEN --host=sentry.example.com\n ${packageName} --access-token=TOKEN --agent-provider=anthropic`;\n}\n"],"mappings":";;;AAEA,SAAgB,WACd,aACA,WACQ;AACR,QAAO,UAAU,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;cAyBjB,UAAU,KAAK,KAAK,CAAC;;;;;;;;;IAS/B,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY"}
@@ -0,0 +1,45 @@
1
+ //#region src/cli/usage.ts
2
+ function buildUsage(packageName, allSkills) {
3
+ return `Usage: ${packageName} --access-token=<token> [--host=<host>]
4
+
5
+ Required:
6
+ --access-token <token> Sentry User Auth Token with API access
7
+
8
+ Common optional flags:
9
+ --host <host> Change Sentry host (self-hosted)
10
+ --sentry-dsn <dsn> Override DSN used for telemetry reporting
11
+ --agent Agent mode: only expose use_sentry tool (for AI agents)
12
+ --experimental Enable experimental tools (hidden by default)
13
+
14
+ Embedded agent configuration:
15
+ --agent-provider <provider> LLM provider: openai or anthropic (auto-detects from API keys)
16
+ --openai-base-url <url> Override OpenAI API base URL
17
+ --openai-model <model> Override OpenAI model (default: gpt-5)
18
+ --anthropic-base-url <url> Override Anthropic API base URL
19
+ --anthropic-model <model> Override Anthropic model (default: claude-sonnet-4-5)
20
+
21
+ Session constraints:
22
+ --organization-slug <slug> Force all calls to an organization
23
+ --project-slug <slug> Optional project constraint
24
+
25
+ Skill controls:
26
+ --skills <list> Specify which skills to grant (default: all skills)
27
+
28
+ All skills: ${allSkills.join(", ")}
29
+
30
+ Environment variables:
31
+ SENTRY_ACCESS_TOKEN Sentry auth token (alternative to --access-token)
32
+ OPENAI_API_KEY OpenAI API key for AI-powered search tools
33
+ ANTHROPIC_API_KEY Anthropic API key for AI-powered search tools
34
+ EMBEDDED_AGENT_PROVIDER Provider override: openai or anthropic
35
+
36
+ Examples:
37
+ ${packageName} --access-token=TOKEN
38
+ ${packageName} --access-token=TOKEN --skills=inspect,triage
39
+ ${packageName} --access-token=TOKEN --host=sentry.example.com
40
+ ${packageName} --access-token=TOKEN --agent-provider=anthropic`;
41
+ }
42
+
43
+ //#endregion
44
+ export { buildUsage };
45
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","names":[],"sources":["../../src/cli/usage.ts"],"sourcesContent":["import type { Skill } from \"@sentry/mcp-core/skills\";\n\nexport function buildUsage(\n packageName: string,\n allSkills: ReadonlyArray<Skill>,\n): string {\n return `Usage: ${packageName} --access-token=<token> [--host=<host>]\n\nRequired:\n --access-token <token> Sentry User Auth Token with API access\n\nCommon optional flags:\n --host <host> Change Sentry host (self-hosted)\n --sentry-dsn <dsn> Override DSN used for telemetry reporting\n --agent Agent mode: only expose use_sentry tool (for AI agents)\n --experimental Enable experimental tools (hidden by default)\n\nEmbedded agent configuration:\n --agent-provider <provider> LLM provider: openai or anthropic (auto-detects from API keys)\n --openai-base-url <url> Override OpenAI API base URL\n --openai-model <model> Override OpenAI model (default: gpt-5)\n --anthropic-base-url <url> Override Anthropic API base URL\n --anthropic-model <model> Override Anthropic model (default: claude-sonnet-4-5)\n\nSession constraints:\n --organization-slug <slug> Force all calls to an organization\n --project-slug <slug> Optional project constraint\n\nSkill controls:\n --skills <list> Specify which skills to grant (default: all skills)\n\nAll skills: ${allSkills.join(\", \")}\n\nEnvironment variables:\n SENTRY_ACCESS_TOKEN Sentry auth token (alternative to --access-token)\n OPENAI_API_KEY OpenAI API key for AI-powered search tools\n ANTHROPIC_API_KEY Anthropic API key for AI-powered search tools\n EMBEDDED_AGENT_PROVIDER Provider override: openai or anthropic\n\nExamples:\n ${packageName} --access-token=TOKEN\n ${packageName} --access-token=TOKEN --skills=inspect,triage\n ${packageName} --access-token=TOKEN --host=sentry.example.com\n ${packageName} --access-token=TOKEN --agent-provider=anthropic`;\n}\n"],"mappings":";AAEA,SAAgB,WACd,aACA,WACQ;AACR,QAAO,UAAU,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;cAyBjB,UAAU,KAAK,KAAK,CAAC;;;;;;;;;IAS/B,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.cjs ADDED
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ const require_chunk = require('./chunk-C0xms8kb.cjs');
3
+ const require_transports_stdio = require('./transports/stdio.cjs');
4
+ const require_cli_usage = require('./cli/usage.cjs');
5
+ const require_cli_parse = require('./cli/parse.cjs');
6
+ const require_cli_resolve = require('./cli/resolve.cjs');
7
+ let _sentry_mcp_core_server = require("@sentry/mcp-core/server");
8
+ let _sentry_node = require("@sentry/node");
9
+ _sentry_node = require_chunk.__toESM(_sentry_node);
10
+ let _sentry_mcp_core_version = require("@sentry/mcp-core/version");
11
+ let _sentry_mcp_core_skills = require("@sentry/mcp-core/skills");
12
+ let _sentry_mcp_core_telem_sentry = require("@sentry/mcp-core/telem/sentry");
13
+ let _sentry_mcp_core_internal_agents_provider_factory = require("@sentry/mcp-core/internal/agents/provider-factory");
14
+
15
+ //#region src/index.ts
16
+ /**
17
+ * Main CLI entry point for the Sentry MCP server.
18
+ *
19
+ * Handles command-line argument parsing, environment configuration, Sentry
20
+ * initialization, and starts the MCP server with stdio transport. Requires
21
+ * a Sentry access token and optionally accepts host and DSN configuration.
22
+ *
23
+ * @example CLI Usage
24
+ * ```bash
25
+ * npx @sentry/mcp-server --access-token=TOKEN --host=sentry.io
26
+ * npx @sentry/mcp-server --access-token=TOKEN --url=https://sentry.example.com
27
+ * ```
28
+ */
29
+ const packageName = "@sentry/mcp-server";
30
+ const usageText = require_cli_usage.buildUsage(packageName, Object.keys(_sentry_mcp_core_skills.SKILLS));
31
+ function die(message) {
32
+ console.error(message);
33
+ console.error(usageText);
34
+ process.exit(1);
35
+ }
36
+ const cli = require_cli_parse.parseArgv(process.argv.slice(2));
37
+ if (cli.help) {
38
+ console.log(usageText);
39
+ process.exit(0);
40
+ }
41
+ if (cli.version) {
42
+ console.log(`${packageName} ${_sentry_mcp_core_version.LIB_VERSION}`);
43
+ process.exit(0);
44
+ }
45
+ if (cli.unknownArgs.length > 0) {
46
+ console.error("Error: Invalid argument(s):", cli.unknownArgs.join(", "));
47
+ console.error(usageText);
48
+ process.exit(1);
49
+ }
50
+ const env = require_cli_parse.parseEnv(process.env);
51
+ const cfg = (() => {
52
+ try {
53
+ return require_cli_resolve.finalize(require_cli_parse.merge(cli, env));
54
+ } catch (err) {
55
+ die(err instanceof Error ? err.message : String(err));
56
+ }
57
+ })();
58
+ if (cfg.agentProvider) (0, _sentry_mcp_core_internal_agents_provider_factory.setAgentProvider)(cfg.agentProvider);
59
+ (0, _sentry_mcp_core_internal_agents_provider_factory.setProviderBaseUrls)({
60
+ openaiBaseUrl: cfg.openaiBaseUrl,
61
+ anthropicBaseUrl: cfg.anthropicBaseUrl
62
+ });
63
+ if (cfg.openaiModel) process.env.OPENAI_MODEL = cfg.openaiModel;
64
+ if (cfg.anthropicModel) process.env.ANTHROPIC_MODEL = cfg.anthropicModel;
65
+ function hasProviderConflict() {
66
+ const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);
67
+ const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);
68
+ const hasExplicitProvider = cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER;
69
+ return hasAnthropic && hasOpenAI && !hasExplicitProvider;
70
+ }
71
+ function getConfiguredProvider() {
72
+ return cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER?.toLowerCase();
73
+ }
74
+ function hasProviderMismatch() {
75
+ const configured = getConfiguredProvider();
76
+ if (!configured) return { mismatch: false };
77
+ const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);
78
+ const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);
79
+ if (configured === "openai" && !hasOpenAI && hasAnthropic) return {
80
+ mismatch: true,
81
+ configured: "openai",
82
+ availableKey: "ANTHROPIC_API_KEY"
83
+ };
84
+ if (configured === "anthropic" && !hasAnthropic && hasOpenAI) return {
85
+ mismatch: true,
86
+ configured: "anthropic",
87
+ availableKey: "OPENAI_API_KEY"
88
+ };
89
+ return { mismatch: false };
90
+ }
91
+ function getProviderSource() {
92
+ if (cli.agentProvider) return "explicitly configured";
93
+ if (process.env.EMBEDDED_AGENT_PROVIDER) return "from EMBEDDED_AGENT_PROVIDER";
94
+ return "auto-detected";
95
+ }
96
+ const resolvedProvider = (0, _sentry_mcp_core_internal_agents_provider_factory.getResolvedProviderType)();
97
+ if (!resolvedProvider) {
98
+ const mismatchInfo = hasProviderMismatch();
99
+ if (hasProviderConflict()) {
100
+ console.warn("Warning: Both ANTHROPIC_API_KEY and OPENAI_API_KEY are set, but no provider is explicitly configured.");
101
+ console.warn("Please set EMBEDDED_AGENT_PROVIDER='openai' or 'anthropic' to specify which provider to use.");
102
+ console.warn("AI-powered search tools will be unavailable until a provider is selected.");
103
+ } else if (mismatchInfo.mismatch) {
104
+ const expectedKey = mismatchInfo.configured === "openai" ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
105
+ const configuredViaCliFlag = Boolean(cli.agentProvider);
106
+ const providerSetting = configuredViaCliFlag ? `--agent-provider=${mismatchInfo.configured}` : `EMBEDDED_AGENT_PROVIDER='${mismatchInfo.configured}'`;
107
+ const changeProviderHint = configuredViaCliFlag ? "Change --agent-provider to match your available API key" : "Change EMBEDDED_AGENT_PROVIDER to match your available API key";
108
+ console.warn(`Warning: ${providerSetting} but ${expectedKey} is not set.`);
109
+ console.warn(`Found ${mismatchInfo.availableKey} instead. Either:`);
110
+ console.warn(` - Set ${expectedKey} to use the ${mismatchInfo.configured} provider, or`);
111
+ console.warn(` - ${changeProviderHint}`);
112
+ console.warn("AI-powered search tools will be unavailable until this is resolved.");
113
+ } else {
114
+ console.warn("Warning: No LLM API key found (OPENAI_API_KEY or ANTHROPIC_API_KEY).");
115
+ console.warn("The following AI-powered search tools will be unavailable:");
116
+ console.warn(" - search_events, search_issues, search_issue_events, use_sentry");
117
+ console.warn("Use list_issues and list_events for direct Sentry query syntax instead.");
118
+ }
119
+ console.warn("");
120
+ } else {
121
+ const providerSource = getProviderSource();
122
+ console.warn(`Using ${resolvedProvider} for AI-powered search tools (${providerSource}).`);
123
+ if (providerSource === "auto-detected") {
124
+ console.warn("Deprecation warning: Auto-detection of LLM provider is deprecated.");
125
+ console.warn(`Please set EMBEDDED_AGENT_PROVIDER='${resolvedProvider}' explicitly.`);
126
+ console.warn("Auto-detection will be removed in a future release.");
127
+ }
128
+ console.warn("");
129
+ }
130
+ _sentry_node.init({
131
+ dsn: cfg.sentryDsn,
132
+ sendDefaultPii: true,
133
+ tracesSampleRate: 1,
134
+ beforeSend: _sentry_mcp_core_telem_sentry.sentryBeforeSend,
135
+ initialScope: { tags: {
136
+ "mcp.server_version": _sentry_mcp_core_version.LIB_VERSION,
137
+ "mcp.transport": "stdio",
138
+ "mcp.agent_mode": cli.agent ? "true" : "false",
139
+ "mcp.experimental_mode": cli.experimental ? "true" : "false",
140
+ "sentry.host": cfg.sentryHost,
141
+ "mcp.mcp-url": cfg.mcpUrl
142
+ } },
143
+ release: process.env.SENTRY_RELEASE,
144
+ integrations: [
145
+ _sentry_node.consoleLoggingIntegration(),
146
+ _sentry_node.zodErrorsIntegration(),
147
+ _sentry_node.vercelAIIntegration({
148
+ recordInputs: true,
149
+ recordOutputs: true
150
+ })
151
+ ],
152
+ environment: process.env.SENTRY_ENVIRONMENT ?? (process.env.NODE_ENV !== "production" ? "development" : "production")
153
+ });
154
+ if (cli.agent) {
155
+ console.warn("Agent mode enabled: Only use_sentry tool is available.");
156
+ console.warn("The use_sentry tool provides access to all Sentry operations through natural language.");
157
+ console.warn("");
158
+ }
159
+ if (cli.experimental) {
160
+ console.warn("Experimental mode enabled: Experimental tools are available.");
161
+ console.warn("");
162
+ }
163
+ const SENTRY_TIMEOUT = 5e3;
164
+ async function shutdown(signal) {
165
+ console.error(`${signal} received, shutting down...`);
166
+ await _sentry_node.flush(SENTRY_TIMEOUT);
167
+ process.exit(0);
168
+ }
169
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
170
+ process.on("SIGINT", () => shutdown("SIGINT"));
171
+ process.on("uncaughtException", async (error) => {
172
+ console.error("Uncaught exception:", error);
173
+ _sentry_node.captureException(error);
174
+ await _sentry_node.flush(SENTRY_TIMEOUT);
175
+ process.exit(1);
176
+ });
177
+ process.on("unhandledRejection", async (reason) => {
178
+ console.error("Unhandled rejection:", reason);
179
+ _sentry_node.captureException(reason);
180
+ await _sentry_node.flush(SENTRY_TIMEOUT);
181
+ process.exit(1);
182
+ });
183
+ const context = {
184
+ accessToken: cfg.accessToken,
185
+ grantedSkills: cfg.finalSkills,
186
+ constraints: {
187
+ organizationSlug: cfg.organizationSlug ?? null,
188
+ projectSlug: cfg.projectSlug ?? null
189
+ },
190
+ sentryHost: cfg.sentryHost,
191
+ mcpUrl: cfg.mcpUrl,
192
+ openaiBaseUrl: cfg.openaiBaseUrl,
193
+ agentMode: cli.agent,
194
+ experimentalMode: cli.experimental
195
+ };
196
+ require_transports_stdio.startStdio((0, _sentry_mcp_core_server.buildServer)({
197
+ context,
198
+ agentMode: cli.agent,
199
+ experimentalMode: cli.experimental
200
+ }), context).catch(async (err) => {
201
+ console.error("Server error:", err);
202
+ _sentry_node.captureException(err);
203
+ await _sentry_node.flush(SENTRY_TIMEOUT);
204
+ process.exit(1);
205
+ });
206
+
207
+ //#endregion
208
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["buildUsage","SKILLS","parseArgv","LIB_VERSION","parseEnv","finalize","merge","Sentry","sentryBeforeSend","startStdio"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Main CLI entry point for the Sentry MCP server.\n *\n * Handles command-line argument parsing, environment configuration, Sentry\n * initialization, and starts the MCP server with stdio transport. Requires\n * a Sentry access token and optionally accepts host and DSN configuration.\n *\n * @example CLI Usage\n * ```bash\n * npx @sentry/mcp-server --access-token=TOKEN --host=sentry.io\n * npx @sentry/mcp-server --access-token=TOKEN --url=https://sentry.example.com\n * ```\n */\n\nimport { buildServer } from \"@sentry/mcp-core/server\";\nimport { startStdio } from \"./transports/stdio\";\nimport * as Sentry from \"@sentry/node\";\nimport { LIB_VERSION } from \"@sentry/mcp-core/version\";\nimport { buildUsage } from \"./cli/usage\";\nimport { parseArgv, parseEnv, merge } from \"./cli/parse\";\nimport { finalize } from \"./cli/resolve\";\nimport { sentryBeforeSend } from \"@sentry/mcp-core/telem/sentry\";\nimport { SKILLS } from \"@sentry/mcp-core/skills\";\nimport {\n setAgentProvider,\n setProviderBaseUrls,\n getResolvedProviderType,\n} from \"@sentry/mcp-core/internal/agents/provider-factory\";\n\nconst packageName = \"@sentry/mcp-server\";\nconst allSkills = Object.keys(SKILLS) as ReadonlyArray<\n (typeof SKILLS)[keyof typeof SKILLS][\"id\"]\n>;\nconst usageText = buildUsage(packageName, allSkills);\n\nfunction die(message: string): never {\n console.error(message);\n console.error(usageText);\n process.exit(1);\n}\nconst cli = parseArgv(process.argv.slice(2));\nif (cli.help) {\n console.log(usageText);\n process.exit(0);\n}\nif (cli.version) {\n console.log(`${packageName} ${LIB_VERSION}`);\n process.exit(0);\n}\nif (cli.unknownArgs.length > 0) {\n console.error(\"Error: Invalid argument(s):\", cli.unknownArgs.join(\", \"));\n console.error(usageText);\n process.exit(1);\n}\n\nconst env = parseEnv(process.env);\nconst cfg = (() => {\n try {\n return finalize(merge(cli, env));\n } catch (err) {\n die(err instanceof Error ? err.message : String(err));\n }\n})();\n\n// Configure embedded agent provider\nif (cfg.agentProvider) {\n setAgentProvider(cfg.agentProvider);\n}\nsetProviderBaseUrls({\n openaiBaseUrl: cfg.openaiBaseUrl,\n anthropicBaseUrl: cfg.anthropicBaseUrl,\n});\nif (cfg.openaiModel) {\n process.env.OPENAI_MODEL = cfg.openaiModel;\n}\nif (cfg.anthropicModel) {\n process.env.ANTHROPIC_MODEL = cfg.anthropicModel;\n}\n\n// Helper functions for provider status messages\nfunction hasProviderConflict(): boolean {\n const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);\n const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);\n const hasExplicitProvider =\n cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER;\n return hasAnthropic && hasOpenAI && !hasExplicitProvider;\n}\n\nfunction getConfiguredProvider(): string | undefined {\n return (\n cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER?.toLowerCase()\n );\n}\n\nfunction hasProviderMismatch(): {\n mismatch: boolean;\n configured?: string;\n availableKey?: string;\n} {\n const configured = getConfiguredProvider();\n if (!configured) return { mismatch: false };\n\n const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);\n const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);\n\n // Check if configured provider's key is missing but other key is present\n if (configured === \"openai\" && !hasOpenAI && hasAnthropic) {\n return {\n mismatch: true,\n configured: \"openai\",\n availableKey: \"ANTHROPIC_API_KEY\",\n };\n }\n if (configured === \"anthropic\" && !hasAnthropic && hasOpenAI) {\n return {\n mismatch: true,\n configured: \"anthropic\",\n availableKey: \"OPENAI_API_KEY\",\n };\n }\n\n return { mismatch: false };\n}\n\nfunction getProviderSource(): string {\n // Check CLI flag first (cli.agentProvider is only set by --agent-provider flag)\n if (cli.agentProvider) return \"explicitly configured\";\n // Then check env var (process.env takes precedence over cfg since cfg merges both)\n if (process.env.EMBEDDED_AGENT_PROVIDER)\n return \"from EMBEDDED_AGENT_PROVIDER\";\n return \"auto-detected\";\n}\n\n// Check for LLM API keys and warn if none available\nconst resolvedProvider = getResolvedProviderType();\n\nif (!resolvedProvider) {\n const mismatchInfo = hasProviderMismatch();\n if (hasProviderConflict()) {\n console.warn(\n \"Warning: Both ANTHROPIC_API_KEY and OPENAI_API_KEY are set, but no provider is explicitly configured.\",\n );\n console.warn(\n \"Please set EMBEDDED_AGENT_PROVIDER='openai' or 'anthropic' to specify which provider to use.\",\n );\n console.warn(\n \"AI-powered search tools will be unavailable until a provider is selected.\",\n );\n } else if (mismatchInfo.mismatch) {\n const expectedKey =\n mismatchInfo.configured === \"openai\"\n ? \"OPENAI_API_KEY\"\n : \"ANTHROPIC_API_KEY\";\n const configuredViaCliFlag = Boolean(cli.agentProvider);\n const providerSetting = configuredViaCliFlag\n ? `--agent-provider=${mismatchInfo.configured}`\n : `EMBEDDED_AGENT_PROVIDER='${mismatchInfo.configured}'`;\n const changeProviderHint = configuredViaCliFlag\n ? \"Change --agent-provider to match your available API key\"\n : \"Change EMBEDDED_AGENT_PROVIDER to match your available API key\";\n console.warn(`Warning: ${providerSetting} but ${expectedKey} is not set.`);\n console.warn(`Found ${mismatchInfo.availableKey} instead. Either:`);\n console.warn(\n ` - Set ${expectedKey} to use the ${mismatchInfo.configured} provider, or`,\n );\n console.warn(` - ${changeProviderHint}`);\n console.warn(\n \"AI-powered search tools will be unavailable until this is resolved.\",\n );\n } else {\n console.warn(\n \"Warning: No LLM API key found (OPENAI_API_KEY or ANTHROPIC_API_KEY).\",\n );\n console.warn(\"The following AI-powered search tools will be unavailable:\");\n console.warn(\n \" - search_events, search_issues, search_issue_events, use_sentry\",\n );\n console.warn(\n \"Use list_issues and list_events for direct Sentry query syntax instead.\",\n );\n }\n console.warn(\"\");\n} else {\n const providerSource = getProviderSource();\n console.warn(\n `Using ${resolvedProvider} for AI-powered search tools (${providerSource}).`,\n );\n // Warn about auto-detection deprecation\n if (providerSource === \"auto-detected\") {\n console.warn(\n \"Deprecation warning: Auto-detection of LLM provider is deprecated.\",\n );\n console.warn(\n `Please set EMBEDDED_AGENT_PROVIDER='${resolvedProvider}' explicitly.`,\n );\n console.warn(\"Auto-detection will be removed in a future release.\");\n }\n console.warn(\"\");\n}\n\nSentry.init({\n dsn: cfg.sentryDsn,\n sendDefaultPii: true,\n tracesSampleRate: 1,\n beforeSend: sentryBeforeSend,\n initialScope: {\n tags: {\n \"mcp.server_version\": LIB_VERSION,\n \"mcp.transport\": \"stdio\",\n \"mcp.agent_mode\": cli.agent ? \"true\" : \"false\",\n \"mcp.experimental_mode\": cli.experimental ? \"true\" : \"false\",\n \"sentry.host\": cfg.sentryHost,\n \"mcp.mcp-url\": cfg.mcpUrl,\n },\n },\n release: process.env.SENTRY_RELEASE,\n integrations: [\n Sentry.consoleLoggingIntegration(),\n Sentry.zodErrorsIntegration(),\n Sentry.vercelAIIntegration({\n recordInputs: true,\n recordOutputs: true,\n }),\n ],\n environment:\n process.env.SENTRY_ENVIRONMENT ??\n (process.env.NODE_ENV !== \"production\" ? \"development\" : \"production\"),\n});\n\n// Log agent mode status\nif (cli.agent) {\n console.warn(\"Agent mode enabled: Only use_sentry tool is available.\");\n console.warn(\n \"The use_sentry tool provides access to all Sentry operations through natural language.\",\n );\n console.warn(\"\");\n}\n\n// Log experimental mode status\nif (cli.experimental) {\n console.warn(\"Experimental mode enabled: Experimental tools are available.\");\n console.warn(\"\");\n}\n\nconst SENTRY_TIMEOUT = 5000; // 5 seconds\n\n// Graceful shutdown handlers\nasync function shutdown(signal: string) {\n console.error(`${signal} received, shutting down...`);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(0);\n}\n\nprocess.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\nprocess.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n\n// Uncaught error handlers\nprocess.on(\"uncaughtException\", async (error) => {\n console.error(\"Uncaught exception:\", error);\n Sentry.captureException(error);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(1);\n});\n\nprocess.on(\"unhandledRejection\", async (reason) => {\n console.error(\"Unhandled rejection:\", reason);\n Sentry.captureException(reason);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(1);\n});\n\n// Build context once for server configuration and runtime\nconst context = {\n accessToken: cfg.accessToken,\n grantedSkills: cfg.finalSkills,\n constraints: {\n organizationSlug: cfg.organizationSlug ?? null,\n projectSlug: cfg.projectSlug ?? null,\n },\n sentryHost: cfg.sentryHost,\n mcpUrl: cfg.mcpUrl,\n openaiBaseUrl: cfg.openaiBaseUrl,\n agentMode: cli.agent,\n experimentalMode: cli.experimental,\n};\n\n// Build server with context to filter tools based on granted skills\n// Use agentMode when --agent flag is set (only exposes use_sentry tool)\n// Use experimentalMode when --experimental flag is set (includes experimental tools)\nconst server = buildServer({\n context,\n agentMode: cli.agent,\n experimentalMode: cli.experimental,\n});\n\nstartStdio(server, context).catch(async (err) => {\n console.error(\"Server error:\", err);\n Sentry.captureException(err);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,MAAM,cAAc;AAIpB,MAAM,YAAYA,6BAAW,aAHX,OAAO,KAAKC,+BAAO,CAGe;AAEpD,SAAS,IAAI,SAAwB;AACnC,SAAQ,MAAM,QAAQ;AACtB,SAAQ,MAAM,UAAU;AACxB,SAAQ,KAAK,EAAE;;AAEjB,MAAM,MAAMC,4BAAU,QAAQ,KAAK,MAAM,EAAE,CAAC;AAC5C,IAAI,IAAI,MAAM;AACZ,SAAQ,IAAI,UAAU;AACtB,SAAQ,KAAK,EAAE;;AAEjB,IAAI,IAAI,SAAS;AACf,SAAQ,IAAI,GAAG,YAAY,GAAGC,uCAAc;AAC5C,SAAQ,KAAK,EAAE;;AAEjB,IAAI,IAAI,YAAY,SAAS,GAAG;AAC9B,SAAQ,MAAM,+BAA+B,IAAI,YAAY,KAAK,KAAK,CAAC;AACxE,SAAQ,MAAM,UAAU;AACxB,SAAQ,KAAK,EAAE;;AAGjB,MAAM,MAAMC,2BAAS,QAAQ,IAAI;AACjC,MAAM,aAAa;AACjB,KAAI;AACF,SAAOC,6BAASC,wBAAM,KAAK,IAAI,CAAC;UACzB,KAAK;AACZ,MAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;;IAErD;AAGJ,IAAI,IAAI,cACN,yEAAiB,IAAI,cAAc;2EAEjB;CAClB,eAAe,IAAI;CACnB,kBAAkB,IAAI;CACvB,CAAC;AACF,IAAI,IAAI,YACN,SAAQ,IAAI,eAAe,IAAI;AAEjC,IAAI,IAAI,eACN,SAAQ,IAAI,kBAAkB,IAAI;AAIpC,SAAS,sBAA+B;CACtC,MAAM,eAAe,QAAQ,QAAQ,IAAI,kBAAkB;CAC3D,MAAM,YAAY,QAAQ,QAAQ,IAAI,eAAe;CACrD,MAAM,sBACJ,IAAI,iBAAiB,QAAQ,IAAI;AACnC,QAAO,gBAAgB,aAAa,CAAC;;AAGvC,SAAS,wBAA4C;AACnD,QACE,IAAI,iBAAiB,QAAQ,IAAI,yBAAyB,aAAa;;AAI3E,SAAS,sBAIP;CACA,MAAM,aAAa,uBAAuB;AAC1C,KAAI,CAAC,WAAY,QAAO,EAAE,UAAU,OAAO;CAE3C,MAAM,eAAe,QAAQ,QAAQ,IAAI,kBAAkB;CAC3D,MAAM,YAAY,QAAQ,QAAQ,IAAI,eAAe;AAGrD,KAAI,eAAe,YAAY,CAAC,aAAa,aAC3C,QAAO;EACL,UAAU;EACV,YAAY;EACZ,cAAc;EACf;AAEH,KAAI,eAAe,eAAe,CAAC,gBAAgB,UACjD,QAAO;EACL,UAAU;EACV,YAAY;EACZ,cAAc;EACf;AAGH,QAAO,EAAE,UAAU,OAAO;;AAG5B,SAAS,oBAA4B;AAEnC,KAAI,IAAI,cAAe,QAAO;AAE9B,KAAI,QAAQ,IAAI,wBACd,QAAO;AACT,QAAO;;AAIT,MAAM,mGAA4C;AAElD,IAAI,CAAC,kBAAkB;CACrB,MAAM,eAAe,qBAAqB;AAC1C,KAAI,qBAAqB,EAAE;AACzB,UAAQ,KACN,wGACD;AACD,UAAQ,KACN,+FACD;AACD,UAAQ,KACN,4EACD;YACQ,aAAa,UAAU;EAChC,MAAM,cACJ,aAAa,eAAe,WACxB,mBACA;EACN,MAAM,uBAAuB,QAAQ,IAAI,cAAc;EACvD,MAAM,kBAAkB,uBACpB,oBAAoB,aAAa,eACjC,4BAA4B,aAAa,WAAW;EACxD,MAAM,qBAAqB,uBACvB,4DACA;AACJ,UAAQ,KAAK,YAAY,gBAAgB,OAAO,YAAY,cAAc;AAC1E,UAAQ,KAAK,SAAS,aAAa,aAAa,mBAAmB;AACnE,UAAQ,KACN,WAAW,YAAY,cAAc,aAAa,WAAW,eAC9D;AACD,UAAQ,KAAK,OAAO,qBAAqB;AACzC,UAAQ,KACN,sEACD;QACI;AACL,UAAQ,KACN,uEACD;AACD,UAAQ,KAAK,6DAA6D;AAC1E,UAAQ,KACN,oEACD;AACD,UAAQ,KACN,0EACD;;AAEH,SAAQ,KAAK,GAAG;OACX;CACL,MAAM,iBAAiB,mBAAmB;AAC1C,SAAQ,KACN,SAAS,iBAAiB,gCAAgC,eAAe,IAC1E;AAED,KAAI,mBAAmB,iBAAiB;AACtC,UAAQ,KACN,qEACD;AACD,UAAQ,KACN,uCAAuC,iBAAiB,eACzD;AACD,UAAQ,KAAK,sDAAsD;;AAErE,SAAQ,KAAK,GAAG;;AAGlBC,aAAO,KAAK;CACV,KAAK,IAAI;CACT,gBAAgB;CAChB,kBAAkB;CAClB,YAAYC;CACZ,cAAc,EACZ,MAAM;EACJ,sBAAsBL;EACtB,iBAAiB;EACjB,kBAAkB,IAAI,QAAQ,SAAS;EACvC,yBAAyB,IAAI,eAAe,SAAS;EACrD,eAAe,IAAI;EACnB,eAAe,IAAI;EACpB,EACF;CACD,SAAS,QAAQ,IAAI;CACrB,cAAc;EACZI,aAAO,2BAA2B;EAClCA,aAAO,sBAAsB;EAC7BA,aAAO,oBAAoB;GACzB,cAAc;GACd,eAAe;GAChB,CAAC;EACH;CACD,aACE,QAAQ,IAAI,uBACX,QAAQ,IAAI,aAAa,eAAe,gBAAgB;CAC5D,CAAC;AAGF,IAAI,IAAI,OAAO;AACb,SAAQ,KAAK,yDAAyD;AACtE,SAAQ,KACN,yFACD;AACD,SAAQ,KAAK,GAAG;;AAIlB,IAAI,IAAI,cAAc;AACpB,SAAQ,KAAK,+DAA+D;AAC5E,SAAQ,KAAK,GAAG;;AAGlB,MAAM,iBAAiB;AAGvB,eAAe,SAAS,QAAgB;AACtC,SAAQ,MAAM,GAAG,OAAO,6BAA6B;AACrD,OAAMA,aAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,EAAE;;AAGjB,QAAQ,GAAG,iBAAiB,SAAS,UAAU,CAAC;AAChD,QAAQ,GAAG,gBAAgB,SAAS,SAAS,CAAC;AAG9C,QAAQ,GAAG,qBAAqB,OAAO,UAAU;AAC/C,SAAQ,MAAM,uBAAuB,MAAM;AAC3C,cAAO,iBAAiB,MAAM;AAC9B,OAAMA,aAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,EAAE;EACf;AAEF,QAAQ,GAAG,sBAAsB,OAAO,WAAW;AACjD,SAAQ,MAAM,wBAAwB,OAAO;AAC7C,cAAO,iBAAiB,OAAO;AAC/B,OAAMA,aAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,EAAE;EACf;AAGF,MAAM,UAAU;CACd,aAAa,IAAI;CACjB,eAAe,IAAI;CACnB,aAAa;EACX,kBAAkB,IAAI,oBAAoB;EAC1C,aAAa,IAAI,eAAe;EACjC;CACD,YAAY,IAAI;CAChB,QAAQ,IAAI;CACZ,eAAe,IAAI;CACnB,WAAW,IAAI;CACf,kBAAkB,IAAI;CACvB;AAWDE,6EAN2B;CACzB;CACA,WAAW,IAAI;CACf,kBAAkB,IAAI;CACvB,CAAC,EAEiB,QAAQ,CAAC,MAAM,OAAO,QAAQ;AAC/C,SAAQ,MAAM,iBAAiB,IAAI;AACnC,cAAO,iBAAiB,IAAI;AAC5B,OAAMF,aAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,EAAE;EACf"}
package/dist/index.js ADDED
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ import { startStdio } from "./transports/stdio.js";
3
+ import { buildUsage } from "./cli/usage.js";
4
+ import { merge, parseArgv, parseEnv } from "./cli/parse.js";
5
+ import { finalize } from "./cli/resolve.js";
6
+ import { buildServer } from "@sentry/mcp-core/server";
7
+ import * as Sentry from "@sentry/node";
8
+ import { LIB_VERSION } from "@sentry/mcp-core/version";
9
+ import { SKILLS } from "@sentry/mcp-core/skills";
10
+ import { sentryBeforeSend } from "@sentry/mcp-core/telem/sentry";
11
+ import { getResolvedProviderType, setAgentProvider, setProviderBaseUrls } from "@sentry/mcp-core/internal/agents/provider-factory";
12
+
13
+ //#region src/index.ts
14
+ /**
15
+ * Main CLI entry point for the Sentry MCP server.
16
+ *
17
+ * Handles command-line argument parsing, environment configuration, Sentry
18
+ * initialization, and starts the MCP server with stdio transport. Requires
19
+ * a Sentry access token and optionally accepts host and DSN configuration.
20
+ *
21
+ * @example CLI Usage
22
+ * ```bash
23
+ * npx @sentry/mcp-server --access-token=TOKEN --host=sentry.io
24
+ * npx @sentry/mcp-server --access-token=TOKEN --url=https://sentry.example.com
25
+ * ```
26
+ */
27
+ const packageName = "@sentry/mcp-server";
28
+ const usageText = buildUsage(packageName, Object.keys(SKILLS));
29
+ function die(message) {
30
+ console.error(message);
31
+ console.error(usageText);
32
+ process.exit(1);
33
+ }
34
+ const cli = parseArgv(process.argv.slice(2));
35
+ if (cli.help) {
36
+ console.log(usageText);
37
+ process.exit(0);
38
+ }
39
+ if (cli.version) {
40
+ console.log(`${packageName} ${LIB_VERSION}`);
41
+ process.exit(0);
42
+ }
43
+ if (cli.unknownArgs.length > 0) {
44
+ console.error("Error: Invalid argument(s):", cli.unknownArgs.join(", "));
45
+ console.error(usageText);
46
+ process.exit(1);
47
+ }
48
+ const env = parseEnv(process.env);
49
+ const cfg = (() => {
50
+ try {
51
+ return finalize(merge(cli, env));
52
+ } catch (err) {
53
+ die(err instanceof Error ? err.message : String(err));
54
+ }
55
+ })();
56
+ if (cfg.agentProvider) setAgentProvider(cfg.agentProvider);
57
+ setProviderBaseUrls({
58
+ openaiBaseUrl: cfg.openaiBaseUrl,
59
+ anthropicBaseUrl: cfg.anthropicBaseUrl
60
+ });
61
+ if (cfg.openaiModel) process.env.OPENAI_MODEL = cfg.openaiModel;
62
+ if (cfg.anthropicModel) process.env.ANTHROPIC_MODEL = cfg.anthropicModel;
63
+ function hasProviderConflict() {
64
+ const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);
65
+ const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);
66
+ const hasExplicitProvider = cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER;
67
+ return hasAnthropic && hasOpenAI && !hasExplicitProvider;
68
+ }
69
+ function getConfiguredProvider() {
70
+ return cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER?.toLowerCase();
71
+ }
72
+ function hasProviderMismatch() {
73
+ const configured = getConfiguredProvider();
74
+ if (!configured) return { mismatch: false };
75
+ const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);
76
+ const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);
77
+ if (configured === "openai" && !hasOpenAI && hasAnthropic) return {
78
+ mismatch: true,
79
+ configured: "openai",
80
+ availableKey: "ANTHROPIC_API_KEY"
81
+ };
82
+ if (configured === "anthropic" && !hasAnthropic && hasOpenAI) return {
83
+ mismatch: true,
84
+ configured: "anthropic",
85
+ availableKey: "OPENAI_API_KEY"
86
+ };
87
+ return { mismatch: false };
88
+ }
89
+ function getProviderSource() {
90
+ if (cli.agentProvider) return "explicitly configured";
91
+ if (process.env.EMBEDDED_AGENT_PROVIDER) return "from EMBEDDED_AGENT_PROVIDER";
92
+ return "auto-detected";
93
+ }
94
+ const resolvedProvider = getResolvedProviderType();
95
+ if (!resolvedProvider) {
96
+ const mismatchInfo = hasProviderMismatch();
97
+ if (hasProviderConflict()) {
98
+ console.warn("Warning: Both ANTHROPIC_API_KEY and OPENAI_API_KEY are set, but no provider is explicitly configured.");
99
+ console.warn("Please set EMBEDDED_AGENT_PROVIDER='openai' or 'anthropic' to specify which provider to use.");
100
+ console.warn("AI-powered search tools will be unavailable until a provider is selected.");
101
+ } else if (mismatchInfo.mismatch) {
102
+ const expectedKey = mismatchInfo.configured === "openai" ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
103
+ const configuredViaCliFlag = Boolean(cli.agentProvider);
104
+ const providerSetting = configuredViaCliFlag ? `--agent-provider=${mismatchInfo.configured}` : `EMBEDDED_AGENT_PROVIDER='${mismatchInfo.configured}'`;
105
+ const changeProviderHint = configuredViaCliFlag ? "Change --agent-provider to match your available API key" : "Change EMBEDDED_AGENT_PROVIDER to match your available API key";
106
+ console.warn(`Warning: ${providerSetting} but ${expectedKey} is not set.`);
107
+ console.warn(`Found ${mismatchInfo.availableKey} instead. Either:`);
108
+ console.warn(` - Set ${expectedKey} to use the ${mismatchInfo.configured} provider, or`);
109
+ console.warn(` - ${changeProviderHint}`);
110
+ console.warn("AI-powered search tools will be unavailable until this is resolved.");
111
+ } else {
112
+ console.warn("Warning: No LLM API key found (OPENAI_API_KEY or ANTHROPIC_API_KEY).");
113
+ console.warn("The following AI-powered search tools will be unavailable:");
114
+ console.warn(" - search_events, search_issues, search_issue_events, use_sentry");
115
+ console.warn("Use list_issues and list_events for direct Sentry query syntax instead.");
116
+ }
117
+ console.warn("");
118
+ } else {
119
+ const providerSource = getProviderSource();
120
+ console.warn(`Using ${resolvedProvider} for AI-powered search tools (${providerSource}).`);
121
+ if (providerSource === "auto-detected") {
122
+ console.warn("Deprecation warning: Auto-detection of LLM provider is deprecated.");
123
+ console.warn(`Please set EMBEDDED_AGENT_PROVIDER='${resolvedProvider}' explicitly.`);
124
+ console.warn("Auto-detection will be removed in a future release.");
125
+ }
126
+ console.warn("");
127
+ }
128
+ Sentry.init({
129
+ dsn: cfg.sentryDsn,
130
+ sendDefaultPii: true,
131
+ tracesSampleRate: 1,
132
+ beforeSend: sentryBeforeSend,
133
+ initialScope: { tags: {
134
+ "mcp.server_version": LIB_VERSION,
135
+ "mcp.transport": "stdio",
136
+ "mcp.agent_mode": cli.agent ? "true" : "false",
137
+ "mcp.experimental_mode": cli.experimental ? "true" : "false",
138
+ "sentry.host": cfg.sentryHost,
139
+ "mcp.mcp-url": cfg.mcpUrl
140
+ } },
141
+ release: process.env.SENTRY_RELEASE,
142
+ integrations: [
143
+ Sentry.consoleLoggingIntegration(),
144
+ Sentry.zodErrorsIntegration(),
145
+ Sentry.vercelAIIntegration({
146
+ recordInputs: true,
147
+ recordOutputs: true
148
+ })
149
+ ],
150
+ environment: process.env.SENTRY_ENVIRONMENT ?? (process.env.NODE_ENV !== "production" ? "development" : "production")
151
+ });
152
+ if (cli.agent) {
153
+ console.warn("Agent mode enabled: Only use_sentry tool is available.");
154
+ console.warn("The use_sentry tool provides access to all Sentry operations through natural language.");
155
+ console.warn("");
156
+ }
157
+ if (cli.experimental) {
158
+ console.warn("Experimental mode enabled: Experimental tools are available.");
159
+ console.warn("");
160
+ }
161
+ const SENTRY_TIMEOUT = 5e3;
162
+ async function shutdown(signal) {
163
+ console.error(`${signal} received, shutting down...`);
164
+ await Sentry.flush(SENTRY_TIMEOUT);
165
+ process.exit(0);
166
+ }
167
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
168
+ process.on("SIGINT", () => shutdown("SIGINT"));
169
+ process.on("uncaughtException", async (error) => {
170
+ console.error("Uncaught exception:", error);
171
+ Sentry.captureException(error);
172
+ await Sentry.flush(SENTRY_TIMEOUT);
173
+ process.exit(1);
174
+ });
175
+ process.on("unhandledRejection", async (reason) => {
176
+ console.error("Unhandled rejection:", reason);
177
+ Sentry.captureException(reason);
178
+ await Sentry.flush(SENTRY_TIMEOUT);
179
+ process.exit(1);
180
+ });
181
+ const context = {
182
+ accessToken: cfg.accessToken,
183
+ grantedSkills: cfg.finalSkills,
184
+ constraints: {
185
+ organizationSlug: cfg.organizationSlug ?? null,
186
+ projectSlug: cfg.projectSlug ?? null
187
+ },
188
+ sentryHost: cfg.sentryHost,
189
+ mcpUrl: cfg.mcpUrl,
190
+ openaiBaseUrl: cfg.openaiBaseUrl,
191
+ agentMode: cli.agent,
192
+ experimentalMode: cli.experimental
193
+ };
194
+ startStdio(buildServer({
195
+ context,
196
+ agentMode: cli.agent,
197
+ experimentalMode: cli.experimental
198
+ }), context).catch(async (err) => {
199
+ console.error("Server error:", err);
200
+ Sentry.captureException(err);
201
+ await Sentry.flush(SENTRY_TIMEOUT);
202
+ process.exit(1);
203
+ });
204
+
205
+ //#endregion
206
+ export { };
207
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Main CLI entry point for the Sentry MCP server.\n *\n * Handles command-line argument parsing, environment configuration, Sentry\n * initialization, and starts the MCP server with stdio transport. Requires\n * a Sentry access token and optionally accepts host and DSN configuration.\n *\n * @example CLI Usage\n * ```bash\n * npx @sentry/mcp-server --access-token=TOKEN --host=sentry.io\n * npx @sentry/mcp-server --access-token=TOKEN --url=https://sentry.example.com\n * ```\n */\n\nimport { buildServer } from \"@sentry/mcp-core/server\";\nimport { startStdio } from \"./transports/stdio\";\nimport * as Sentry from \"@sentry/node\";\nimport { LIB_VERSION } from \"@sentry/mcp-core/version\";\nimport { buildUsage } from \"./cli/usage\";\nimport { parseArgv, parseEnv, merge } from \"./cli/parse\";\nimport { finalize } from \"./cli/resolve\";\nimport { sentryBeforeSend } from \"@sentry/mcp-core/telem/sentry\";\nimport { SKILLS } from \"@sentry/mcp-core/skills\";\nimport {\n setAgentProvider,\n setProviderBaseUrls,\n getResolvedProviderType,\n} from \"@sentry/mcp-core/internal/agents/provider-factory\";\n\nconst packageName = \"@sentry/mcp-server\";\nconst allSkills = Object.keys(SKILLS) as ReadonlyArray<\n (typeof SKILLS)[keyof typeof SKILLS][\"id\"]\n>;\nconst usageText = buildUsage(packageName, allSkills);\n\nfunction die(message: string): never {\n console.error(message);\n console.error(usageText);\n process.exit(1);\n}\nconst cli = parseArgv(process.argv.slice(2));\nif (cli.help) {\n console.log(usageText);\n process.exit(0);\n}\nif (cli.version) {\n console.log(`${packageName} ${LIB_VERSION}`);\n process.exit(0);\n}\nif (cli.unknownArgs.length > 0) {\n console.error(\"Error: Invalid argument(s):\", cli.unknownArgs.join(\", \"));\n console.error(usageText);\n process.exit(1);\n}\n\nconst env = parseEnv(process.env);\nconst cfg = (() => {\n try {\n return finalize(merge(cli, env));\n } catch (err) {\n die(err instanceof Error ? err.message : String(err));\n }\n})();\n\n// Configure embedded agent provider\nif (cfg.agentProvider) {\n setAgentProvider(cfg.agentProvider);\n}\nsetProviderBaseUrls({\n openaiBaseUrl: cfg.openaiBaseUrl,\n anthropicBaseUrl: cfg.anthropicBaseUrl,\n});\nif (cfg.openaiModel) {\n process.env.OPENAI_MODEL = cfg.openaiModel;\n}\nif (cfg.anthropicModel) {\n process.env.ANTHROPIC_MODEL = cfg.anthropicModel;\n}\n\n// Helper functions for provider status messages\nfunction hasProviderConflict(): boolean {\n const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);\n const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);\n const hasExplicitProvider =\n cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER;\n return hasAnthropic && hasOpenAI && !hasExplicitProvider;\n}\n\nfunction getConfiguredProvider(): string | undefined {\n return (\n cfg.agentProvider || process.env.EMBEDDED_AGENT_PROVIDER?.toLowerCase()\n );\n}\n\nfunction hasProviderMismatch(): {\n mismatch: boolean;\n configured?: string;\n availableKey?: string;\n} {\n const configured = getConfiguredProvider();\n if (!configured) return { mismatch: false };\n\n const hasAnthropic = Boolean(process.env.ANTHROPIC_API_KEY);\n const hasOpenAI = Boolean(process.env.OPENAI_API_KEY);\n\n // Check if configured provider's key is missing but other key is present\n if (configured === \"openai\" && !hasOpenAI && hasAnthropic) {\n return {\n mismatch: true,\n configured: \"openai\",\n availableKey: \"ANTHROPIC_API_KEY\",\n };\n }\n if (configured === \"anthropic\" && !hasAnthropic && hasOpenAI) {\n return {\n mismatch: true,\n configured: \"anthropic\",\n availableKey: \"OPENAI_API_KEY\",\n };\n }\n\n return { mismatch: false };\n}\n\nfunction getProviderSource(): string {\n // Check CLI flag first (cli.agentProvider is only set by --agent-provider flag)\n if (cli.agentProvider) return \"explicitly configured\";\n // Then check env var (process.env takes precedence over cfg since cfg merges both)\n if (process.env.EMBEDDED_AGENT_PROVIDER)\n return \"from EMBEDDED_AGENT_PROVIDER\";\n return \"auto-detected\";\n}\n\n// Check for LLM API keys and warn if none available\nconst resolvedProvider = getResolvedProviderType();\n\nif (!resolvedProvider) {\n const mismatchInfo = hasProviderMismatch();\n if (hasProviderConflict()) {\n console.warn(\n \"Warning: Both ANTHROPIC_API_KEY and OPENAI_API_KEY are set, but no provider is explicitly configured.\",\n );\n console.warn(\n \"Please set EMBEDDED_AGENT_PROVIDER='openai' or 'anthropic' to specify which provider to use.\",\n );\n console.warn(\n \"AI-powered search tools will be unavailable until a provider is selected.\",\n );\n } else if (mismatchInfo.mismatch) {\n const expectedKey =\n mismatchInfo.configured === \"openai\"\n ? \"OPENAI_API_KEY\"\n : \"ANTHROPIC_API_KEY\";\n const configuredViaCliFlag = Boolean(cli.agentProvider);\n const providerSetting = configuredViaCliFlag\n ? `--agent-provider=${mismatchInfo.configured}`\n : `EMBEDDED_AGENT_PROVIDER='${mismatchInfo.configured}'`;\n const changeProviderHint = configuredViaCliFlag\n ? \"Change --agent-provider to match your available API key\"\n : \"Change EMBEDDED_AGENT_PROVIDER to match your available API key\";\n console.warn(`Warning: ${providerSetting} but ${expectedKey} is not set.`);\n console.warn(`Found ${mismatchInfo.availableKey} instead. Either:`);\n console.warn(\n ` - Set ${expectedKey} to use the ${mismatchInfo.configured} provider, or`,\n );\n console.warn(` - ${changeProviderHint}`);\n console.warn(\n \"AI-powered search tools will be unavailable until this is resolved.\",\n );\n } else {\n console.warn(\n \"Warning: No LLM API key found (OPENAI_API_KEY or ANTHROPIC_API_KEY).\",\n );\n console.warn(\"The following AI-powered search tools will be unavailable:\");\n console.warn(\n \" - search_events, search_issues, search_issue_events, use_sentry\",\n );\n console.warn(\n \"Use list_issues and list_events for direct Sentry query syntax instead.\",\n );\n }\n console.warn(\"\");\n} else {\n const providerSource = getProviderSource();\n console.warn(\n `Using ${resolvedProvider} for AI-powered search tools (${providerSource}).`,\n );\n // Warn about auto-detection deprecation\n if (providerSource === \"auto-detected\") {\n console.warn(\n \"Deprecation warning: Auto-detection of LLM provider is deprecated.\",\n );\n console.warn(\n `Please set EMBEDDED_AGENT_PROVIDER='${resolvedProvider}' explicitly.`,\n );\n console.warn(\"Auto-detection will be removed in a future release.\");\n }\n console.warn(\"\");\n}\n\nSentry.init({\n dsn: cfg.sentryDsn,\n sendDefaultPii: true,\n tracesSampleRate: 1,\n beforeSend: sentryBeforeSend,\n initialScope: {\n tags: {\n \"mcp.server_version\": LIB_VERSION,\n \"mcp.transport\": \"stdio\",\n \"mcp.agent_mode\": cli.agent ? \"true\" : \"false\",\n \"mcp.experimental_mode\": cli.experimental ? \"true\" : \"false\",\n \"sentry.host\": cfg.sentryHost,\n \"mcp.mcp-url\": cfg.mcpUrl,\n },\n },\n release: process.env.SENTRY_RELEASE,\n integrations: [\n Sentry.consoleLoggingIntegration(),\n Sentry.zodErrorsIntegration(),\n Sentry.vercelAIIntegration({\n recordInputs: true,\n recordOutputs: true,\n }),\n ],\n environment:\n process.env.SENTRY_ENVIRONMENT ??\n (process.env.NODE_ENV !== \"production\" ? \"development\" : \"production\"),\n});\n\n// Log agent mode status\nif (cli.agent) {\n console.warn(\"Agent mode enabled: Only use_sentry tool is available.\");\n console.warn(\n \"The use_sentry tool provides access to all Sentry operations through natural language.\",\n );\n console.warn(\"\");\n}\n\n// Log experimental mode status\nif (cli.experimental) {\n console.warn(\"Experimental mode enabled: Experimental tools are available.\");\n console.warn(\"\");\n}\n\nconst SENTRY_TIMEOUT = 5000; // 5 seconds\n\n// Graceful shutdown handlers\nasync function shutdown(signal: string) {\n console.error(`${signal} received, shutting down...`);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(0);\n}\n\nprocess.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\nprocess.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n\n// Uncaught error handlers\nprocess.on(\"uncaughtException\", async (error) => {\n console.error(\"Uncaught exception:\", error);\n Sentry.captureException(error);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(1);\n});\n\nprocess.on(\"unhandledRejection\", async (reason) => {\n console.error(\"Unhandled rejection:\", reason);\n Sentry.captureException(reason);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(1);\n});\n\n// Build context once for server configuration and runtime\nconst context = {\n accessToken: cfg.accessToken,\n grantedSkills: cfg.finalSkills,\n constraints: {\n organizationSlug: cfg.organizationSlug ?? null,\n projectSlug: cfg.projectSlug ?? null,\n },\n sentryHost: cfg.sentryHost,\n mcpUrl: cfg.mcpUrl,\n openaiBaseUrl: cfg.openaiBaseUrl,\n agentMode: cli.agent,\n experimentalMode: cli.experimental,\n};\n\n// Build server with context to filter tools based on granted skills\n// Use agentMode when --agent flag is set (only exposes use_sentry tool)\n// Use experimentalMode when --experimental flag is set (includes experimental tools)\nconst server = buildServer({\n context,\n agentMode: cli.agent,\n experimentalMode: cli.experimental,\n});\n\nstartStdio(server, context).catch(async (err) => {\n console.error(\"Server error:\", err);\n Sentry.captureException(err);\n await Sentry.flush(SENTRY_TIMEOUT);\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ServerContext } from "@sentry/mcp-core/types";
3
+
4
+ //#region src/transports/stdio.d.ts
5
+
6
+ /**
7
+ * Starts the MCP server with stdio transport and telemetry.
8
+ *
9
+ * Connects the server using stdio transport for process-based communication.
10
+ * Context is already captured in tool handler closures during buildServer().
11
+ * All operations are wrapped in Sentry tracing for observability.
12
+ *
13
+ * @param server - Configured and instrumented MCP server instance (with context in closures)
14
+ * @param context - Server context with authentication and configuration (for telemetry attributes)
15
+ *
16
+ * @example CLI Integration
17
+ * ```typescript
18
+ * import { buildServer } from "./server.js";
19
+ * import { startStdio } from "./transports/stdio.js";
20
+ *
21
+ * const context = {
22
+ * accessToken: userToken,
23
+ * sentryHost: "sentry.io",
24
+ * userId: "user-123",
25
+ * clientId: "cursor-ide",
26
+ * constraints: {}
27
+ * };
28
+ *
29
+ * const server = buildServer({ context }); // Context captured in closures
30
+ * await startStdio(server, context);
31
+ * ```
32
+ */
33
+ declare function startStdio(server: McpServer, context: ServerContext): Promise<void>;
34
+ //# sourceMappingURL=stdio.d.ts.map
35
+ //#endregion
36
+ export { startStdio };
37
+ //# sourceMappingURL=stdio-DVcJU1wB.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio-DVcJU1wB.d.ts","names":[],"sources":["../../src/transports/stdio.ts"],"sourcesContent":[],"mappings":";;;;;;;AAqDA;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,UAAA,SAAmB,oBAAoB,gBAAa"}