@tokamohsen/sentry-mcp 0.29.4 → 0.29.6

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 (57) hide show
  1. package/dist/{chunk-C0xms8kb.cjs → chunk-rXqPaSPc.cjs} +26 -0
  2. package/dist/cli/{parse-M8aGwIO5.d.ts → parse-CX7Bcldr.d.ts} +2 -2
  3. package/dist/cli/{parse-M8aGwIO5.d.ts.map → parse-CX7Bcldr.d.ts.map} +1 -1
  4. package/dist/cli/parse.cjs +1 -1
  5. package/dist/cli/{resolve-kNjr_UaF.d.ts → resolve-BVtyZcQM.d.ts} +2 -2
  6. package/dist/cli/resolve-BVtyZcQM.d.ts.map +1 -0
  7. package/dist/cli/resolve.cjs +9 -10
  8. package/dist/cli/resolve.cjs.map +1 -1
  9. package/dist/cli/resolve.js +2 -2
  10. package/dist/cli/{types-B2hDXVnQ.d.ts → types-CnTkIHzd.d.ts} +1 -1
  11. package/dist/cli/{types-B2hDXVnQ.d.ts.map → types-CnTkIHzd.d.ts.map} +1 -1
  12. package/dist/cli/{usage-BMxqEEQ3.d.ts → usage-BhCVaC5j.d.ts} +1 -1
  13. package/dist/cli/usage-BhCVaC5j.d.ts.map +1 -0
  14. package/dist/config-CzqCJmB9.js +613 -0
  15. package/dist/config-CzqCJmB9.js.map +1 -0
  16. package/dist/config-DMt6phB6.cjs +630 -0
  17. package/dist/config-DMt6phB6.cjs.map +1 -0
  18. package/dist/constants-BrEVt86y.js +194 -0
  19. package/dist/constants-BrEVt86y.js.map +1 -0
  20. package/dist/constants-C14tQf_s.cjs +217 -0
  21. package/dist/constants-C14tQf_s.cjs.map +1 -0
  22. package/dist/index.cjs +163 -14
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.js +191 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/server-DduxvXpe.js +32499 -0
  27. package/dist/server-DduxvXpe.js.map +1 -0
  28. package/dist/server-lur5iSHk.cjs +32530 -0
  29. package/dist/server-lur5iSHk.cjs.map +1 -0
  30. package/dist/skills-DOgs9MAy.cjs +96 -0
  31. package/dist/skills-DOgs9MAy.cjs.map +1 -0
  32. package/dist/skills-DfqlqYXj.js +72 -0
  33. package/dist/skills-DfqlqYXj.js.map +1 -0
  34. package/dist/token-CO5Bq1Ct.js +50 -0
  35. package/dist/token-CO5Bq1Ct.js.map +1 -0
  36. package/dist/token-GX19_oyM.cjs +54 -0
  37. package/dist/token-GX19_oyM.cjs.map +1 -0
  38. package/dist/token-util-1O_mwf8r.js +358 -0
  39. package/dist/token-util-1O_mwf8r.js.map +1 -0
  40. package/dist/token-util-Cw83HNFN.cjs +362 -0
  41. package/dist/token-util-Cw83HNFN.cjs.map +1 -0
  42. package/dist/transports/{stdio-DVcJU1wB.d.ts → stdio-DKQR8J7l.d.ts} +1 -1
  43. package/dist/transports/{stdio-DVcJU1wB.d.ts.map → stdio-DKQR8J7l.d.ts.map} +1 -1
  44. package/dist/transports/stdio.cjs +3 -3
  45. package/dist/transports/stdio.js +1 -1
  46. package/dist/url-utils-BHhxlntO.js +119 -0
  47. package/dist/url-utils-BHhxlntO.js.map +1 -0
  48. package/dist/url-utils-N2ExJl9F.cjs +161 -0
  49. package/dist/url-utils-N2ExJl9F.cjs.map +1 -0
  50. package/dist/version-4iOZzjiD.js +7 -0
  51. package/dist/version-4iOZzjiD.js.map +1 -0
  52. package/dist/version-BD4r13ze.cjs +19 -0
  53. package/dist/version-BD4r13ze.cjs.map +1 -0
  54. package/package.json +1 -1
  55. package/dist/cli/resolve-kNjr_UaF.d.ts.map +0 -1
  56. package/dist/cli/usage-BMxqEEQ3.d.ts.map +0 -1
  57. /package/dist/{index-DgNgxUxv.d.ts → index-UKPmYT-S.d.ts} +0 -0
package/dist/index.cjs CHANGED
@@ -1,17 +1,160 @@
1
1
  #!/usr/bin/env node
2
- const require_chunk = require('./chunk-C0xms8kb.cjs');
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
+ const require_chunk = require('./chunk-rXqPaSPc.cjs');
4
+ const require_skills = require('./skills-DOgs9MAy.cjs');
5
+ require('./constants-C14tQf_s.cjs');
6
+ const require_server = require('./server-lur5iSHk.cjs');
7
+ const require_version = require('./version-BD4r13ze.cjs');
3
8
  const require_transports_stdio = require('./transports/stdio.cjs');
4
9
  const require_cli_usage = require('./cli/usage.cjs');
5
10
  const require_cli_parse = require('./cli/parse.cjs');
6
11
  const require_cli_resolve = require('./cli/resolve.cjs');
7
- let _sentry_mcp_core_server = require("@sentry/mcp-core/server");
8
12
  let _sentry_node = require("@sentry/node");
9
13
  _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
14
 
15
+ //#region ../../node_modules/.pnpm/@vercel+oidc@3.1.0/node_modules/@vercel/oidc/dist/token-error.js
16
+ var require_token_error = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
17
+ var __defProp = Object.defineProperty;
18
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
19
+ var __getOwnPropNames = Object.getOwnPropertyNames;
20
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
21
+ var __export = (target, all) => {
22
+ for (var name in all) __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true
25
+ });
26
+ };
27
+ var __copyProps = (to, from, except, desc) => {
28
+ if (from && typeof from === "object" || typeof from === "function") {
29
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
30
+ get: () => from[key],
31
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
32
+ });
33
+ }
34
+ return to;
35
+ };
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var token_error_exports = {};
38
+ __export(token_error_exports, { VercelOidcTokenError: () => VercelOidcTokenError });
39
+ module.exports = __toCommonJS(token_error_exports);
40
+ var VercelOidcTokenError = class extends Error {
41
+ constructor(message, cause) {
42
+ super(message);
43
+ this.name = "VercelOidcTokenError";
44
+ this.cause = cause;
45
+ }
46
+ toString() {
47
+ if (this.cause) return `${this.name}: ${this.message}: ${this.cause}`;
48
+ return `${this.name}: ${this.message}`;
49
+ }
50
+ };
51
+ }));
52
+
53
+ //#endregion
54
+ //#region ../mcp-core/dist/telem/sentry.js
55
+ const SCRUB_PATTERNS = [
56
+ {
57
+ pattern: /\bsk-[a-zA-Z0-9]{48}\b/g,
58
+ replacement: "[REDACTED_OPENAI_KEY]",
59
+ description: "OpenAI API key"
60
+ },
61
+ {
62
+ pattern: /\bBearer\s+[a-zA-Z0-9\-._~+/]+={0,}/g,
63
+ replacement: "Bearer [REDACTED_TOKEN]",
64
+ description: "Bearer token"
65
+ },
66
+ {
67
+ pattern: /\bsntrys_[a-zA-Z0-9_]+\b/g,
68
+ replacement: "[REDACTED_SENTRY_TOKEN]",
69
+ description: "Sentry access token"
70
+ }
71
+ ];
72
+ const MAX_SCRUB_DEPTH = 20;
73
+ /**
74
+ * Recursively scrub sensitive data from any value.
75
+ * Returns tuple of [scrubbedValue, didScrub, descriptionsOfMatchedPatterns]
76
+ */
77
+ function scrubValue(value, depth = 0) {
78
+ if (depth >= MAX_SCRUB_DEPTH) return [
79
+ "[MAX_DEPTH_EXCEEDED]",
80
+ false,
81
+ []
82
+ ];
83
+ if (typeof value === "string") {
84
+ let scrubbed = value;
85
+ let didScrub = false;
86
+ const matchedDescriptions = [];
87
+ for (const { pattern, replacement, description } of SCRUB_PATTERNS) {
88
+ pattern.lastIndex = 0;
89
+ if (pattern.test(scrubbed)) {
90
+ didScrub = true;
91
+ matchedDescriptions.push(description);
92
+ pattern.lastIndex = 0;
93
+ scrubbed = scrubbed.replace(pattern, replacement);
94
+ }
95
+ }
96
+ return [
97
+ scrubbed,
98
+ didScrub,
99
+ matchedDescriptions
100
+ ];
101
+ }
102
+ if (Array.isArray(value)) {
103
+ let arrayDidScrub = false;
104
+ const arrayDescriptions = [];
105
+ return [
106
+ value.map((item) => {
107
+ const [scrubbed, didScrub, descriptions] = scrubValue(item, depth + 1);
108
+ if (didScrub) {
109
+ arrayDidScrub = true;
110
+ arrayDescriptions.push(...descriptions);
111
+ }
112
+ return scrubbed;
113
+ }),
114
+ arrayDidScrub,
115
+ arrayDescriptions
116
+ ];
117
+ }
118
+ if (value && typeof value === "object") {
119
+ let objectDidScrub = false;
120
+ const objectDescriptions = [];
121
+ const scrubbed = {};
122
+ for (const [key, val] of Object.entries(value)) {
123
+ const [scrubbedVal, didScrub, descriptions] = scrubValue(val, depth + 1);
124
+ if (didScrub) {
125
+ objectDidScrub = true;
126
+ objectDescriptions.push(...descriptions);
127
+ }
128
+ scrubbed[key] = scrubbedVal;
129
+ }
130
+ return [
131
+ scrubbed,
132
+ objectDidScrub,
133
+ objectDescriptions
134
+ ];
135
+ }
136
+ return [
137
+ value,
138
+ false,
139
+ []
140
+ ];
141
+ }
142
+ /**
143
+ * Sentry beforeSend hook that scrubs sensitive data from events
144
+ * and applies custom fingerprinting for specific error types.
145
+ */
146
+ function sentryBeforeSend(event, hint) {
147
+ const firstException = event?.exception?.values?.[0];
148
+ if (firstException?.type === "AI_APICallError" && firstException.value) event.fingerprint = ["AI_APICallError", firstException.value];
149
+ const [scrubbedEvent, didScrub, descriptions] = scrubValue(event);
150
+ if (didScrub) {
151
+ const uniqueDescriptions = [...new Set(descriptions)];
152
+ console.warn(`[Sentry] Event contained sensitive data: ${uniqueDescriptions.join(", ")}`);
153
+ }
154
+ return scrubbedEvent;
155
+ }
156
+
157
+ //#endregion
15
158
  //#region src/index.ts
16
159
  /**
17
160
  * Main CLI entry point for the Sentry MCP server.
@@ -27,7 +170,7 @@ let _sentry_mcp_core_internal_agents_provider_factory = require("@sentry/mcp-cor
27
170
  * ```
28
171
  */
29
172
  const packageName = "@tokamohsen/sentry-mcp";
30
- const usageText = require_cli_usage.buildUsage(packageName, Object.keys(_sentry_mcp_core_skills.SKILLS));
173
+ const usageText = require_cli_usage.buildUsage(packageName, Object.keys(require_skills.SKILLS));
31
174
  function die(message) {
32
175
  console.error(message);
33
176
  console.error(usageText);
@@ -39,7 +182,7 @@ if (cli.help) {
39
182
  process.exit(0);
40
183
  }
41
184
  if (cli.version) {
42
- console.log(`${packageName} ${_sentry_mcp_core_version.LIB_VERSION}`);
185
+ console.log(`${packageName} ${require_version.LIB_VERSION}`);
43
186
  process.exit(0);
44
187
  }
45
188
  if (cli.unknownArgs.length > 0) {
@@ -55,8 +198,8 @@ const cfg = (() => {
55
198
  die(err instanceof Error ? err.message : String(err));
56
199
  }
57
200
  })();
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)({
201
+ if (cfg.agentProvider) require_server.setAgentProvider(cfg.agentProvider);
202
+ require_server.setProviderBaseUrls({
60
203
  openaiBaseUrl: cfg.openaiBaseUrl,
61
204
  anthropicBaseUrl: cfg.anthropicBaseUrl
62
205
  });
@@ -93,7 +236,7 @@ function getProviderSource() {
93
236
  if (process.env.EMBEDDED_AGENT_PROVIDER) return "from EMBEDDED_AGENT_PROVIDER";
94
237
  return "auto-detected";
95
238
  }
96
- const resolvedProvider = (0, _sentry_mcp_core_internal_agents_provider_factory.getResolvedProviderType)();
239
+ const resolvedProvider = require_server.getResolvedProviderType();
97
240
  if (!resolvedProvider) {
98
241
  const mismatchInfo = hasProviderMismatch();
99
242
  if (hasProviderConflict()) {
@@ -131,9 +274,9 @@ _sentry_node.init({
131
274
  dsn: cfg.sentryDsn,
132
275
  sendDefaultPii: true,
133
276
  tracesSampleRate: 1,
134
- beforeSend: _sentry_mcp_core_telem_sentry.sentryBeforeSend,
277
+ beforeSend: sentryBeforeSend,
135
278
  initialScope: { tags: {
136
- "mcp.server_version": _sentry_mcp_core_version.LIB_VERSION,
279
+ "mcp.server_version": require_version.LIB_VERSION,
137
280
  "mcp.transport": "stdio",
138
281
  "mcp.agent_mode": cli.agent ? "true" : "false",
139
282
  "mcp.experimental_mode": cli.experimental ? "true" : "false",
@@ -193,7 +336,7 @@ const context = {
193
336
  agentMode: cli.agent,
194
337
  experimentalMode: cli.experimental
195
338
  };
196
- require_transports_stdio.startStdio((0, _sentry_mcp_core_server.buildServer)({
339
+ require_transports_stdio.startStdio(require_server.buildServer({
197
340
  context,
198
341
  agentMode: cli.agent,
199
342
  experimentalMode: cli.experimental
@@ -205,4 +348,10 @@ require_transports_stdio.startStdio((0, _sentry_mcp_core_server.buildServer)({
205
348
  });
206
349
 
207
350
  //#endregion
351
+ Object.defineProperty(exports, 'require_token_error', {
352
+ enumerable: true,
353
+ get: function () {
354
+ return require_token_error;
355
+ }
356
+ });
208
357
  //# sourceMappingURL=index.cjs.map
@@ -1 +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 @tokamohsen/sentry-mcp --access-token=TOKEN --host=sentry.io\n * npx @tokamohsen/sentry-mcp --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 = \"@tokamohsen/sentry-mcp\";\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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"}
1
+ {"version":3,"file":"index.cjs","names":["buildUsage","SKILLS","parseArgv","LIB_VERSION","parseEnv","finalize","merge","setProviderBaseUrls","getResolvedProviderType","Sentry","startStdio","buildServer"],"sources":["../../../node_modules/.pnpm/@vercel+oidc@3.1.0/node_modules/@vercel/oidc/dist/token-error.js","../../mcp-core/dist/telem/sentry.js","../src/index.ts"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar token_error_exports = {};\n__export(token_error_exports, {\n VercelOidcTokenError: () => VercelOidcTokenError\n});\nmodule.exports = __toCommonJS(token_error_exports);\nclass VercelOidcTokenError extends Error {\n constructor(message, cause) {\n super(message);\n this.name = \"VercelOidcTokenError\";\n this.cause = cause;\n }\n toString() {\n if (this.cause) {\n return `${this.name}: ${this.message}: ${this.cause}`;\n }\n return `${this.name}: ${this.message}`;\n }\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n VercelOidcTokenError\n});\n","//#region src/telem/sentry.ts\nconst SCRUB_PATTERNS = [\n\t{\n\t\tpattern: /\\bsk-[a-zA-Z0-9]{48}\\b/g,\n\t\treplacement: \"[REDACTED_OPENAI_KEY]\",\n\t\tdescription: \"OpenAI API key\"\n\t},\n\t{\n\t\tpattern: /\\bBearer\\s+[a-zA-Z0-9\\-._~+/]+={0,}/g,\n\t\treplacement: \"Bearer [REDACTED_TOKEN]\",\n\t\tdescription: \"Bearer token\"\n\t},\n\t{\n\t\tpattern: /\\bsntrys_[a-zA-Z0-9_]+\\b/g,\n\t\treplacement: \"[REDACTED_SENTRY_TOKEN]\",\n\t\tdescription: \"Sentry access token\"\n\t}\n];\nconst MAX_SCRUB_DEPTH = 20;\n/**\n* Recursively scrub sensitive data from any value.\n* Returns tuple of [scrubbedValue, didScrub, descriptionsOfMatchedPatterns]\n*/\nfunction scrubValue(value, depth = 0) {\n\tif (depth >= MAX_SCRUB_DEPTH) return [\n\t\t\"[MAX_DEPTH_EXCEEDED]\",\n\t\tfalse,\n\t\t[]\n\t];\n\tif (typeof value === \"string\") {\n\t\tlet scrubbed = value;\n\t\tlet didScrub = false;\n\t\tconst matchedDescriptions = [];\n\t\tfor (const { pattern, replacement, description } of SCRUB_PATTERNS) {\n\t\t\tpattern.lastIndex = 0;\n\t\t\tif (pattern.test(scrubbed)) {\n\t\t\t\tdidScrub = true;\n\t\t\t\tmatchedDescriptions.push(description);\n\t\t\t\tpattern.lastIndex = 0;\n\t\t\t\tscrubbed = scrubbed.replace(pattern, replacement);\n\t\t\t}\n\t\t}\n\t\treturn [\n\t\t\tscrubbed,\n\t\t\tdidScrub,\n\t\t\tmatchedDescriptions\n\t\t];\n\t}\n\tif (Array.isArray(value)) {\n\t\tlet arrayDidScrub = false;\n\t\tconst arrayDescriptions = [];\n\t\treturn [\n\t\t\tvalue.map((item) => {\n\t\t\t\tconst [scrubbed, didScrub, descriptions] = scrubValue(item, depth + 1);\n\t\t\t\tif (didScrub) {\n\t\t\t\t\tarrayDidScrub = true;\n\t\t\t\t\tarrayDescriptions.push(...descriptions);\n\t\t\t\t}\n\t\t\t\treturn scrubbed;\n\t\t\t}),\n\t\t\tarrayDidScrub,\n\t\t\tarrayDescriptions\n\t\t];\n\t}\n\tif (value && typeof value === \"object\") {\n\t\tlet objectDidScrub = false;\n\t\tconst objectDescriptions = [];\n\t\tconst scrubbed = {};\n\t\tfor (const [key, val] of Object.entries(value)) {\n\t\t\tconst [scrubbedVal, didScrub, descriptions] = scrubValue(val, depth + 1);\n\t\t\tif (didScrub) {\n\t\t\t\tobjectDidScrub = true;\n\t\t\t\tobjectDescriptions.push(...descriptions);\n\t\t\t}\n\t\t\tscrubbed[key] = scrubbedVal;\n\t\t}\n\t\treturn [\n\t\t\tscrubbed,\n\t\t\tobjectDidScrub,\n\t\t\tobjectDescriptions\n\t\t];\n\t}\n\treturn [\n\t\tvalue,\n\t\tfalse,\n\t\t[]\n\t];\n}\n/**\n* Sentry beforeSend hook that scrubs sensitive data from events\n* and applies custom fingerprinting for specific error types.\n*/\nfunction sentryBeforeSend(event, hint) {\n\tconst firstException = event?.exception?.values?.[0];\n\tif (firstException?.type === \"AI_APICallError\" && firstException.value) event.fingerprint = [\"AI_APICallError\", firstException.value];\n\tconst [scrubbedEvent, didScrub, descriptions] = scrubValue(event);\n\tif (didScrub) {\n\t\tconst uniqueDescriptions = [...new Set(descriptions)];\n\t\tconsole.warn(`[Sentry] Event contained sensitive data: ${uniqueDescriptions.join(\", \")}`);\n\t}\n\treturn scrubbedEvent;\n}\n\n//#endregion\nexport { sentryBeforeSend };\n//# sourceMappingURL=sentry.js.map","#!/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 @tokamohsen/sentry-mcp --access-token=TOKEN --host=sentry.io\n * npx @tokamohsen/sentry-mcp --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 = \"@tokamohsen/sentry-mcp\";\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"],"x_google_ignoreList":[0],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,15 +1,200 @@
1
1
  #!/usr/bin/env node
2
+ import { n as SKILLS } from "./skills-DfqlqYXj.js";
3
+ import "./constants-BrEVt86y.js";
4
+ import { a as setProviderBaseUrls, i as setAgentProvider, r as getResolvedProviderType, t as buildServer } from "./server-DduxvXpe.js";
5
+ import { t as LIB_VERSION } from "./version-4iOZzjiD.js";
2
6
  import { startStdio } from "./transports/stdio.js";
3
7
  import { buildUsage } from "./cli/usage.js";
4
8
  import { merge, parseArgv, parseEnv } from "./cli/parse.js";
5
9
  import { finalize } from "./cli/resolve.js";
6
- import { buildServer } from "@sentry/mcp-core/server";
10
+ import { createRequire } from "node:module";
7
11
  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
12
 
13
+ //#region \0rolldown/runtime.js
14
+ var __create = Object.create;
15
+ var __defProp = Object.defineProperty;
16
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
17
+ var __getOwnPropNames = Object.getOwnPropertyNames;
18
+ var __getProtoOf = Object.getPrototypeOf;
19
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
20
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
21
+ var __exportAll = (all, no_symbols) => {
22
+ let target = {};
23
+ for (var name in all) {
24
+ __defProp(target, name, {
25
+ get: all[name],
26
+ enumerable: true
27
+ });
28
+ }
29
+ if (!no_symbols) {
30
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
31
+ }
32
+ return target;
33
+ };
34
+ var __copyProps = (to, from, except, desc) => {
35
+ if (from && typeof from === "object" || typeof from === "function") {
36
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
37
+ key = keys[i];
38
+ if (!__hasOwnProp.call(to, key) && key !== except) {
39
+ __defProp(to, key, {
40
+ get: ((k) => from[k]).bind(null, key),
41
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
42
+ });
43
+ }
44
+ }
45
+ }
46
+ return to;
47
+ };
48
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
49
+ value: mod,
50
+ enumerable: true
51
+ }) : target, mod));
52
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
53
+
54
+ //#endregion
55
+ //#region ../../node_modules/.pnpm/@vercel+oidc@3.1.0/node_modules/@vercel/oidc/dist/token-error.js
56
+ var require_token_error = /* @__PURE__ */ __commonJSMin(((exports, module) => {
57
+ var __defProp = Object.defineProperty;
58
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
59
+ var __getOwnPropNames = Object.getOwnPropertyNames;
60
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
61
+ var __export = (target, all) => {
62
+ for (var name in all) __defProp(target, name, {
63
+ get: all[name],
64
+ enumerable: true
65
+ });
66
+ };
67
+ var __copyProps = (to, from, except, desc) => {
68
+ if (from && typeof from === "object" || typeof from === "function") {
69
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
70
+ get: () => from[key],
71
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
72
+ });
73
+ }
74
+ return to;
75
+ };
76
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
77
+ var token_error_exports = {};
78
+ __export(token_error_exports, { VercelOidcTokenError: () => VercelOidcTokenError });
79
+ module.exports = __toCommonJS(token_error_exports);
80
+ var VercelOidcTokenError = class extends Error {
81
+ constructor(message, cause) {
82
+ super(message);
83
+ this.name = "VercelOidcTokenError";
84
+ this.cause = cause;
85
+ }
86
+ toString() {
87
+ if (this.cause) return `${this.name}: ${this.message}: ${this.cause}`;
88
+ return `${this.name}: ${this.message}`;
89
+ }
90
+ };
91
+ }));
92
+
93
+ //#endregion
94
+ //#region ../mcp-core/dist/telem/sentry.js
95
+ const SCRUB_PATTERNS = [
96
+ {
97
+ pattern: /\bsk-[a-zA-Z0-9]{48}\b/g,
98
+ replacement: "[REDACTED_OPENAI_KEY]",
99
+ description: "OpenAI API key"
100
+ },
101
+ {
102
+ pattern: /\bBearer\s+[a-zA-Z0-9\-._~+/]+={0,}/g,
103
+ replacement: "Bearer [REDACTED_TOKEN]",
104
+ description: "Bearer token"
105
+ },
106
+ {
107
+ pattern: /\bsntrys_[a-zA-Z0-9_]+\b/g,
108
+ replacement: "[REDACTED_SENTRY_TOKEN]",
109
+ description: "Sentry access token"
110
+ }
111
+ ];
112
+ const MAX_SCRUB_DEPTH = 20;
113
+ /**
114
+ * Recursively scrub sensitive data from any value.
115
+ * Returns tuple of [scrubbedValue, didScrub, descriptionsOfMatchedPatterns]
116
+ */
117
+ function scrubValue(value, depth = 0) {
118
+ if (depth >= MAX_SCRUB_DEPTH) return [
119
+ "[MAX_DEPTH_EXCEEDED]",
120
+ false,
121
+ []
122
+ ];
123
+ if (typeof value === "string") {
124
+ let scrubbed = value;
125
+ let didScrub = false;
126
+ const matchedDescriptions = [];
127
+ for (const { pattern, replacement, description } of SCRUB_PATTERNS) {
128
+ pattern.lastIndex = 0;
129
+ if (pattern.test(scrubbed)) {
130
+ didScrub = true;
131
+ matchedDescriptions.push(description);
132
+ pattern.lastIndex = 0;
133
+ scrubbed = scrubbed.replace(pattern, replacement);
134
+ }
135
+ }
136
+ return [
137
+ scrubbed,
138
+ didScrub,
139
+ matchedDescriptions
140
+ ];
141
+ }
142
+ if (Array.isArray(value)) {
143
+ let arrayDidScrub = false;
144
+ const arrayDescriptions = [];
145
+ return [
146
+ value.map((item) => {
147
+ const [scrubbed, didScrub, descriptions] = scrubValue(item, depth + 1);
148
+ if (didScrub) {
149
+ arrayDidScrub = true;
150
+ arrayDescriptions.push(...descriptions);
151
+ }
152
+ return scrubbed;
153
+ }),
154
+ arrayDidScrub,
155
+ arrayDescriptions
156
+ ];
157
+ }
158
+ if (value && typeof value === "object") {
159
+ let objectDidScrub = false;
160
+ const objectDescriptions = [];
161
+ const scrubbed = {};
162
+ for (const [key, val] of Object.entries(value)) {
163
+ const [scrubbedVal, didScrub, descriptions] = scrubValue(val, depth + 1);
164
+ if (didScrub) {
165
+ objectDidScrub = true;
166
+ objectDescriptions.push(...descriptions);
167
+ }
168
+ scrubbed[key] = scrubbedVal;
169
+ }
170
+ return [
171
+ scrubbed,
172
+ objectDidScrub,
173
+ objectDescriptions
174
+ ];
175
+ }
176
+ return [
177
+ value,
178
+ false,
179
+ []
180
+ ];
181
+ }
182
+ /**
183
+ * Sentry beforeSend hook that scrubs sensitive data from events
184
+ * and applies custom fingerprinting for specific error types.
185
+ */
186
+ function sentryBeforeSend(event, hint) {
187
+ const firstException = event?.exception?.values?.[0];
188
+ if (firstException?.type === "AI_APICallError" && firstException.value) event.fingerprint = ["AI_APICallError", firstException.value];
189
+ const [scrubbedEvent, didScrub, descriptions] = scrubValue(event);
190
+ if (didScrub) {
191
+ const uniqueDescriptions = [...new Set(descriptions)];
192
+ console.warn(`[Sentry] Event contained sensitive data: ${uniqueDescriptions.join(", ")}`);
193
+ }
194
+ return scrubbedEvent;
195
+ }
196
+
197
+ //#endregion
13
198
  //#region src/index.ts
14
199
  /**
15
200
  * Main CLI entry point for the Sentry MCP server.
@@ -203,5 +388,5 @@ startStdio(buildServer({
203
388
  });
204
389
 
205
390
  //#endregion
206
- export { };
391
+ export { __toESM as a, __require as i, __commonJSMin as n, __exportAll as r, require_token_error as t };
207
392
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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 @tokamohsen/sentry-mcp --access-token=TOKEN --host=sentry.io\n * npx @tokamohsen/sentry-mcp --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 = \"@tokamohsen/sentry-mcp\";\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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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../node_modules/.pnpm/@vercel+oidc@3.1.0/node_modules/@vercel/oidc/dist/token-error.js","../../mcp-core/dist/telem/sentry.js","../src/index.ts"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar token_error_exports = {};\n__export(token_error_exports, {\n VercelOidcTokenError: () => VercelOidcTokenError\n});\nmodule.exports = __toCommonJS(token_error_exports);\nclass VercelOidcTokenError extends Error {\n constructor(message, cause) {\n super(message);\n this.name = \"VercelOidcTokenError\";\n this.cause = cause;\n }\n toString() {\n if (this.cause) {\n return `${this.name}: ${this.message}: ${this.cause}`;\n }\n return `${this.name}: ${this.message}`;\n }\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n VercelOidcTokenError\n});\n","//#region src/telem/sentry.ts\nconst SCRUB_PATTERNS = [\n\t{\n\t\tpattern: /\\bsk-[a-zA-Z0-9]{48}\\b/g,\n\t\treplacement: \"[REDACTED_OPENAI_KEY]\",\n\t\tdescription: \"OpenAI API key\"\n\t},\n\t{\n\t\tpattern: /\\bBearer\\s+[a-zA-Z0-9\\-._~+/]+={0,}/g,\n\t\treplacement: \"Bearer [REDACTED_TOKEN]\",\n\t\tdescription: \"Bearer token\"\n\t},\n\t{\n\t\tpattern: /\\bsntrys_[a-zA-Z0-9_]+\\b/g,\n\t\treplacement: \"[REDACTED_SENTRY_TOKEN]\",\n\t\tdescription: \"Sentry access token\"\n\t}\n];\nconst MAX_SCRUB_DEPTH = 20;\n/**\n* Recursively scrub sensitive data from any value.\n* Returns tuple of [scrubbedValue, didScrub, descriptionsOfMatchedPatterns]\n*/\nfunction scrubValue(value, depth = 0) {\n\tif (depth >= MAX_SCRUB_DEPTH) return [\n\t\t\"[MAX_DEPTH_EXCEEDED]\",\n\t\tfalse,\n\t\t[]\n\t];\n\tif (typeof value === \"string\") {\n\t\tlet scrubbed = value;\n\t\tlet didScrub = false;\n\t\tconst matchedDescriptions = [];\n\t\tfor (const { pattern, replacement, description } of SCRUB_PATTERNS) {\n\t\t\tpattern.lastIndex = 0;\n\t\t\tif (pattern.test(scrubbed)) {\n\t\t\t\tdidScrub = true;\n\t\t\t\tmatchedDescriptions.push(description);\n\t\t\t\tpattern.lastIndex = 0;\n\t\t\t\tscrubbed = scrubbed.replace(pattern, replacement);\n\t\t\t}\n\t\t}\n\t\treturn [\n\t\t\tscrubbed,\n\t\t\tdidScrub,\n\t\t\tmatchedDescriptions\n\t\t];\n\t}\n\tif (Array.isArray(value)) {\n\t\tlet arrayDidScrub = false;\n\t\tconst arrayDescriptions = [];\n\t\treturn [\n\t\t\tvalue.map((item) => {\n\t\t\t\tconst [scrubbed, didScrub, descriptions] = scrubValue(item, depth + 1);\n\t\t\t\tif (didScrub) {\n\t\t\t\t\tarrayDidScrub = true;\n\t\t\t\t\tarrayDescriptions.push(...descriptions);\n\t\t\t\t}\n\t\t\t\treturn scrubbed;\n\t\t\t}),\n\t\t\tarrayDidScrub,\n\t\t\tarrayDescriptions\n\t\t];\n\t}\n\tif (value && typeof value === \"object\") {\n\t\tlet objectDidScrub = false;\n\t\tconst objectDescriptions = [];\n\t\tconst scrubbed = {};\n\t\tfor (const [key, val] of Object.entries(value)) {\n\t\t\tconst [scrubbedVal, didScrub, descriptions] = scrubValue(val, depth + 1);\n\t\t\tif (didScrub) {\n\t\t\t\tobjectDidScrub = true;\n\t\t\t\tobjectDescriptions.push(...descriptions);\n\t\t\t}\n\t\t\tscrubbed[key] = scrubbedVal;\n\t\t}\n\t\treturn [\n\t\t\tscrubbed,\n\t\t\tobjectDidScrub,\n\t\t\tobjectDescriptions\n\t\t];\n\t}\n\treturn [\n\t\tvalue,\n\t\tfalse,\n\t\t[]\n\t];\n}\n/**\n* Sentry beforeSend hook that scrubs sensitive data from events\n* and applies custom fingerprinting for specific error types.\n*/\nfunction sentryBeforeSend(event, hint) {\n\tconst firstException = event?.exception?.values?.[0];\n\tif (firstException?.type === \"AI_APICallError\" && firstException.value) event.fingerprint = [\"AI_APICallError\", firstException.value];\n\tconst [scrubbedEvent, didScrub, descriptions] = scrubValue(event);\n\tif (didScrub) {\n\t\tconst uniqueDescriptions = [...new Set(descriptions)];\n\t\tconsole.warn(`[Sentry] Event contained sensitive data: ${uniqueDescriptions.join(\", \")}`);\n\t}\n\treturn scrubbedEvent;\n}\n\n//#endregion\nexport { sentryBeforeSend };\n//# sourceMappingURL=sentry.js.map","#!/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 @tokamohsen/sentry-mcp --access-token=TOKEN --host=sentry.io\n * npx @tokamohsen/sentry-mcp --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 = \"@tokamohsen/sentry-mcp\";\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"],"x_google_ignoreList":[0],"mappings":"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"}