@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.
- package/dist/chunk-C0xms8kb.cjs +34 -0
- package/dist/cli/parse-EvLqDjN2.d.cts +11 -0
- package/dist/cli/parse-EvLqDjN2.d.cts.map +1 -0
- package/dist/cli/parse-M8aGwIO5.d.ts +11 -0
- package/dist/cli/parse-M8aGwIO5.d.ts.map +1 -0
- package/dist/cli/parse.cjs +107 -0
- package/dist/cli/parse.cjs.map +1 -0
- package/dist/cli/parse.js +103 -0
- package/dist/cli/parse.js.map +1 -0
- package/dist/cli/resolve-C3hwH129.d.cts +10 -0
- package/dist/cli/resolve-C3hwH129.d.cts.map +1 -0
- package/dist/cli/resolve-kNjr_UaF.d.ts +10 -0
- package/dist/cli/resolve-kNjr_UaF.d.ts.map +1 -0
- package/dist/cli/resolve.cjs +57 -0
- package/dist/cli/resolve.cjs.map +1 -0
- package/dist/cli/resolve.js +54 -0
- package/dist/cli/resolve.js.map +1 -0
- package/dist/cli/types-B2hDXVnQ.d.ts +73 -0
- package/dist/cli/types-B2hDXVnQ.d.ts.map +1 -0
- package/dist/cli/types-VWgo1wm6.d.cts +73 -0
- package/dist/cli/types-VWgo1wm6.d.cts.map +1 -0
- package/dist/cli/types.cjs +0 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/usage-B0gAPy4S.d.cts +9 -0
- package/dist/cli/usage-B0gAPy4S.d.cts.map +1 -0
- package/dist/cli/usage-BMxqEEQ3.d.ts +9 -0
- package/dist/cli/usage-BMxqEEQ3.d.ts.map +1 -0
- package/dist/cli/usage.cjs +47 -0
- package/dist/cli/usage.cjs.map +1 -0
- package/dist/cli/usage.js +45 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/index-16fTC-hT.d.cts +1 -0
- package/dist/index-DgNgxUxv.d.ts +1 -0
- package/dist/index.cjs +208 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/transports/stdio-DVcJU1wB.d.ts +37 -0
- package/dist/transports/stdio-DVcJU1wB.d.ts.map +1 -0
- package/dist/transports/stdio-DeWUp4RP.d.cts +37 -0
- package/dist/transports/stdio-DeWUp4RP.d.cts.map +1 -0
- package/dist/transports/stdio.cjs +74 -0
- package/dist/transports/stdio.cjs.map +1 -0
- package/dist/transports/stdio.js +71 -0
- package/dist/transports/stdio.js.map +1 -0
- 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"}
|