@cursor/july 0.1.9 → 0.1.11
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/AGENTS.md +1 -0
- package/dist/bin/agent-serve.js +26 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +2 -1
- package/dist/channels/github/types.d.ts +4 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +13 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +36 -11
- package/dist/channels/slack/eval-directive.d.ts +63 -0
- package/dist/channels/slack/eval-directive.d.ts.map +1 -0
- package/dist/channels/slack/eval-directive.js +283 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +4 -2
- package/dist/channels/slack/types.d.ts +7 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +10 -5
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +10 -5
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.Ciosf24M.js → app.BcXUGca7.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BIbvK8M1.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BcRDly7n.js → VPLocalSearchBox.CWur6XGZ.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CMpbjdfx.js → theme.BnvulOX2.js} +2 -2
- package/dist/docs/assets/{deployment.md.DC5-ImcM.js → deployment.md.TecHo0_2.js} +3 -3
- package/dist/docs/assets/{deployment.md.DC5-ImcM.lean.js → deployment.md.TecHo0_2.lean.js} +1 -1
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.js +29 -0
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.lean.js +1 -0
- package/dist/docs/assets/{index.md.COiu-1jL.js → index.md.t0TM2Qzz.js} +3 -3
- package/dist/docs/assets/{index.md.COiu-1jL.lean.js → index.md.t0TM2Qzz.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D189RBCH.js → reference_cli.md.B74NrVzb.js} +5 -4
- package/dist/docs/assets/{reference_cli.md.D189RBCH.lean.js → reference_cli.md.B74NrVzb.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.js → reference_connections.md.CsSr3rDz.js} +9 -4
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.lean.js → reference_connections.md.CsSr3rDz.lean.js} +1 -1
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.js +1 -0
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.lean.js +1 -0
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.js → reference_tools.md.BRSDnTbN.js} +16 -3
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.lean.js → reference_tools.md.BRSDnTbN.lean.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.js → troubleshooting.md.CmQkmnzC.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.lean.js → troubleshooting.md.CmQkmnzC.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/evals.html +4 -4
- package/dist/docs/example-agents/approval-buddy.html +4 -4
- package/dist/docs/example-agents/benny.html +4 -4
- package/dist/docs/example-agents/bugbot.html +4 -4
- package/dist/docs/example-agents/codebase-wiki.html +4 -4
- package/dist/docs/example-agents/codeowners-review.html +4 -4
- package/dist/docs/example-agents/concierge.html +4 -4
- package/dist/docs/example-agents/fsd.html +4 -4
- package/dist/docs/example-agents/index.html +4 -4
- package/dist/docs/example-agents/knowledge-base.html +4 -4
- package/dist/docs/example-agents/oncall.html +4 -4
- package/dist/docs/example-agents/security-reviewer.html +4 -4
- package/dist/docs/example-agents/slack-agent.html +4 -4
- package/dist/docs/example-agents/weather-agent.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +53 -0
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +8 -7
- package/dist/docs/reference/connections.html +13 -8
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +33 -0
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +20 -7
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/evals.d.ts +39 -0
- package/dist/evals.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +7 -4
- package/dist/internal/cli-mcp-oauth.d.ts +16 -0
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -0
- package/dist/internal/cli-mcp-oauth.js +194 -0
- package/dist/internal/cli-mcp.d.ts +4 -1
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +19 -1
- package/dist/internal/corp-ca.d.ts +9 -0
- package/dist/internal/corp-ca.d.ts.map +1 -0
- package/dist/internal/corp-ca.js +44 -0
- package/dist/internal/cursor/account-mcp.d.ts +17 -4
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +105 -17
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +64 -10
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +49 -26
- package/dist/internal/mcp-oauth.d.ts +88 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -0
- package/dist/internal/mcp-oauth.js +385 -0
- package/dist/internal/resolved-connections.d.ts +6 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +10 -3
- package/dist/internal/sdk-runner.d.ts +9 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +28 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +24 -6
- package/dist/internal/session-engine.d.ts +30 -10
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +166 -74
- package/dist/internal/sessions-client.d.ts +16 -2
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +30 -13
- package/dist/internal/storage-coordinator.d.ts +11 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +30 -0
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +8 -4
- package/dist/internal/turn-governor.d.ts +54 -0
- package/dist/internal/turn-governor.d.ts.map +1 -0
- package/dist/internal/turn-governor.js +111 -0
- package/dist/playground/assets/{index-C0-QEG4O.js → index-BIGLubwK.js} +46 -46
- package/dist/playground/assets/{index-z3JY9O2x.css → index-C17ZQKDG.css} +1 -1
- package/dist/playground/index.html +2 -2
- package/dist/prompt.d.ts +39 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +70 -0
- package/dist/storage-backends/cursor-hosted.d.ts +10 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +14 -0
- package/dist/types.d.ts +93 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/docs/README.md +4 -0
- package/docs/deployment.md +6 -1
- package/docs/guides/mcp-oauth.md +157 -0
- package/docs/reference/cli.md +30 -0
- package/docs/reference/connections.md +32 -2
- package/docs/reference/prompt.md +47 -0
- package/docs/reference/tools.md +21 -0
- package/docs/troubleshooting.md +11 -0
- package/package.json +9 -2
- package/skills/create-agent/SKILL.md +7 -3
- package/skills/framework-map/SKILL.md +1 -0
- package/skills/mcp-auth/SKILL.md +138 -0
- package/src/bin/agent-serve.ts +30 -3
- package/src/channels/github/github-channel.ts +2 -0
- package/src/channels/github/types.ts +4 -0
- package/src/channels/slack/cursor-account.ts +2 -0
- package/src/channels/slack/dispatch.ts +49 -0
- package/src/channels/slack/eval-directive.ts +348 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/types.ts +7 -0
- package/src/connections.ts +10 -5
- package/src/evals.ts +43 -0
- package/src/index.ts +3 -0
- package/src/internal/cli-ax.ts +10 -4
- package/src/internal/cli-mcp-oauth.ts +254 -0
- package/src/internal/cli-mcp.ts +25 -2
- package/src/internal/cursor/account-mcp.ts +153 -41
- package/src/internal/discovery.ts +70 -8
- package/src/internal/distribution.ts +1 -0
- package/src/internal/logs-client.ts +1 -1
- package/src/internal/mcp-host.ts +33 -9
- package/src/internal/mcp-oauth.ts +496 -0
- package/src/internal/resolved-connections.ts +20 -5
- package/src/internal/sdk-runner.ts +37 -1
- package/src/internal/server.ts +28 -6
- package/src/internal/session-engine.ts +192 -76
- package/src/internal/sessions-client.ts +51 -15
- package/src/internal/storage-coordinator.ts +36 -0
- package/src/internal/stream-progress.ts +8 -0
- package/src/internal/turn-governor.ts +145 -0
- package/src/prompt.ts +83 -0
- package/src/storage-backends/cursor-hosted.ts +21 -0
- package/src/types.ts +92 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.D154Detj.js +0 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agentkit mcp oauth <connection> [--store]` for `defineConnection({ url, oauth: true })`.
|
|
3
|
+
*/
|
|
4
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
7
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
8
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
14
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
15
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
16
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
17
|
+
import { resolveDeployAuth } from "./cli-deploy.js";
|
|
18
|
+
import { loadAgentProject } from "./discovery.js";
|
|
19
|
+
import { CLI_COMMAND_NAME as CLI, LOG_PREFIX } from "./distribution.js";
|
|
20
|
+
import { createHostMcpOAuthProvider, MCP_OAUTH_CALLBACK_URL, mcpOauthSecretNames, openBrowser, waitForMcpOAuthCallback, } from "./mcp-oauth.js";
|
|
21
|
+
import { resolveProdSlug } from "./resolve-prod-target.js";
|
|
22
|
+
function describe(error) {
|
|
23
|
+
if (!(error instanceof Error)) {
|
|
24
|
+
return String(error);
|
|
25
|
+
}
|
|
26
|
+
const cause = error.cause;
|
|
27
|
+
if (!(cause instanceof Error)) {
|
|
28
|
+
return error.message;
|
|
29
|
+
}
|
|
30
|
+
const code = "code" in cause && typeof cause.code === "string" ? cause.code : undefined;
|
|
31
|
+
const detail = code === undefined ? cause.message : `${cause.message} (${code})`;
|
|
32
|
+
return `${error.message}: ${detail}`;
|
|
33
|
+
}
|
|
34
|
+
export function cmdMcpOauth(options) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
var _a;
|
|
37
|
+
var _b, _c;
|
|
38
|
+
const err = (_b = options.err) !== null && _b !== void 0 ? _b : ((text) => process.stderr.write(text));
|
|
39
|
+
const out = (_c = options.out) !== null && _c !== void 0 ? _c : ((text) => process.stdout.write(text));
|
|
40
|
+
const project = yield loadAgentProject(options.dir);
|
|
41
|
+
const connection = project.agent.connections.find((entry) => entry.name === options.connection);
|
|
42
|
+
if (connection === undefined) {
|
|
43
|
+
const known = project.agent.connections.map((entry) => entry.name).join(", ") ||
|
|
44
|
+
"(none)";
|
|
45
|
+
err(`${LOG_PREFIX} Unknown MCP connection "${options.connection}". Authored: ${known}.\n`);
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
const transport = connection.transport;
|
|
49
|
+
if (!("url" in transport) || transport.oauth !== true) {
|
|
50
|
+
err(`${LOG_PREFIX} "${options.connection}" must be defineConnection({ url, oauth: true }).\n`);
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
out(`${LOG_PREFIX} Authorizing "${options.connection}" (${transport.url})…\n`);
|
|
54
|
+
let authorizationUrl;
|
|
55
|
+
const provider = yield createHostMcpOAuthProvider({
|
|
56
|
+
identifier: options.connection,
|
|
57
|
+
resourceUrl: transport.url,
|
|
58
|
+
onRedirect: (url) => {
|
|
59
|
+
authorizationUrl = url;
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
const client = new Client({ name: "agentkit-mcp-oauth", version: "0.1.0" });
|
|
63
|
+
const url = new URL(transport.url);
|
|
64
|
+
const requestInit = transport.headers === undefined
|
|
65
|
+
? undefined
|
|
66
|
+
: { headers: transport.headers };
|
|
67
|
+
const makeTransport = () => {
|
|
68
|
+
if (transport.type === "sse") {
|
|
69
|
+
return new SSEClientTransport(url, {
|
|
70
|
+
authProvider: provider,
|
|
71
|
+
requestInit,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return new StreamableHTTPClientTransport(url, {
|
|
75
|
+
authProvider: provider,
|
|
76
|
+
requestInit,
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
let mcpTransport = makeTransport();
|
|
80
|
+
let authorized = false;
|
|
81
|
+
try {
|
|
82
|
+
yield client.connect(mcpTransport);
|
|
83
|
+
out(`${LOG_PREFIX} "${options.connection}" already authorized.\n`);
|
|
84
|
+
yield client.close().catch(() => undefined);
|
|
85
|
+
authorized = true;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (!(error instanceof UnauthorizedError)) {
|
|
89
|
+
err(`${LOG_PREFIX} Failed to connect to "${options.connection}": ${describe(error)}\n`);
|
|
90
|
+
return 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!authorized) {
|
|
94
|
+
const redirect = authorizationUrl !== null && authorizationUrl !== void 0 ? authorizationUrl : provider.lastRedirectUrl;
|
|
95
|
+
if (redirect === undefined) {
|
|
96
|
+
err(`${LOG_PREFIX} Auth required but no authorization URL was provided.\n`);
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
out(`${LOG_PREFIX} Open if needed:\n ${redirect.toString()}\n`);
|
|
100
|
+
out(`${LOG_PREFIX} Waiting on ${MCP_OAUTH_CALLBACK_URL}…\n`);
|
|
101
|
+
openBrowser(redirect.toString());
|
|
102
|
+
let callback;
|
|
103
|
+
try {
|
|
104
|
+
callback = yield waitForMcpOAuthCallback();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
err(`${LOG_PREFIX} OAuth callback failed: ${describe(error)}\n`);
|
|
108
|
+
return 1;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
yield mcpTransport.finishAuth(callback.code);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
err(`${LOG_PREFIX} Token exchange failed: ${describe(error)}\n`);
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
mcpTransport = makeTransport();
|
|
118
|
+
try {
|
|
119
|
+
yield client.connect(mcpTransport);
|
|
120
|
+
const tools = yield client.listTools();
|
|
121
|
+
out(`${LOG_PREFIX} Authorized "${options.connection}" (${tools.tools.length} tools). Local tokens in the agent-serve config dir.\n`);
|
|
122
|
+
yield client.close().catch(() => undefined);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
err(`${LOG_PREFIX} Reconnect failed: ${describe(error)}. Re-run \`${CLI} mcp oauth ${options.connection}\`.\n`);
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (options.store !== true) {
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
return storeOauthSecrets({
|
|
133
|
+
connection: options.connection,
|
|
134
|
+
dir: options.dir,
|
|
135
|
+
slug: options.slug,
|
|
136
|
+
team: options.team,
|
|
137
|
+
apiKey: options.apiKey,
|
|
138
|
+
tokens: provider.tokens(),
|
|
139
|
+
clientId: (_a = provider.clientInformation()) === null || _a === void 0 ? void 0 : _a.client_id,
|
|
140
|
+
err,
|
|
141
|
+
out,
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function storeOauthSecrets(args) {
|
|
146
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
const tokens = args.tokens;
|
|
148
|
+
if (tokens === undefined || tokens.access_token.trim() === "") {
|
|
149
|
+
args.err(`${LOG_PREFIX} No access token to store for "${args.connection}".\n`);
|
|
150
|
+
return 1;
|
|
151
|
+
}
|
|
152
|
+
let slug;
|
|
153
|
+
try {
|
|
154
|
+
slug = resolveProdSlug({ dir: args.dir, slug: args.slug });
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
args.err(`${LOG_PREFIX} ${describe(error)}\n`);
|
|
158
|
+
return 1;
|
|
159
|
+
}
|
|
160
|
+
const auth = yield resolveDeployAuth({
|
|
161
|
+
team: args.team,
|
|
162
|
+
apiKey: args.apiKey,
|
|
163
|
+
err: args.err,
|
|
164
|
+
});
|
|
165
|
+
if (typeof auth === "number") {
|
|
166
|
+
return auth;
|
|
167
|
+
}
|
|
168
|
+
const names = mcpOauthSecretNames(args.connection);
|
|
169
|
+
const secrets = [
|
|
170
|
+
{ name: names.accessToken, value: tokens.access_token },
|
|
171
|
+
];
|
|
172
|
+
if (tokens.refresh_token !== undefined &&
|
|
173
|
+
tokens.refresh_token.trim() !== "") {
|
|
174
|
+
secrets.push({ name: names.refreshToken, value: tokens.refresh_token });
|
|
175
|
+
}
|
|
176
|
+
if (args.clientId !== undefined && args.clientId.trim() !== "") {
|
|
177
|
+
secrets.push({ name: names.clientId, value: args.clientId });
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const secretNames = yield auth.client.setSecrets({
|
|
181
|
+
teamId: auth.teamId,
|
|
182
|
+
slug,
|
|
183
|
+
secrets,
|
|
184
|
+
});
|
|
185
|
+
args.out(`${LOG_PREFIX} Stored on ${slug}: ${secrets.map((s) => s.name).join(", ")}.\n` +
|
|
186
|
+
`${LOG_PREFIX} Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`);
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
args.err(`${LOG_PREFIX} Failed to store secrets on ${slug}: ${describe(error)}\n`);
|
|
191
|
+
return 1;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
@@ -54,7 +54,10 @@ export interface McpCliOptions {
|
|
|
54
54
|
now?: () => number;
|
|
55
55
|
sleep?: (ms: number) => Promise<void>;
|
|
56
56
|
}
|
|
57
|
-
export declare function cmdMcp(subcommand: string | undefined, options: McpCliOptions
|
|
57
|
+
export declare function cmdMcp(subcommand: string | undefined, options: McpCliOptions & {
|
|
58
|
+
oauthConnection?: string;
|
|
59
|
+
store?: boolean;
|
|
60
|
+
}): Promise<number>;
|
|
58
61
|
export declare function cmdMcpServe(options: McpCliOptions): Promise<number>;
|
|
59
62
|
export declare function cmdMcpInstall(options: McpCliOptions): Promise<number>;
|
|
60
63
|
/** `~/.cursor/mcp.json` — the user-level Cursor MCP config. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-mcp.d.ts","sourceRoot":"","sources":["../../src/internal/cli-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,EAGL,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AA0BlC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC3C,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"cli-mcp.d.ts","sourceRoot":"","sources":["../../src/internal/cli-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,EAGL,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AA0BlC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC3C,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,aAAa,GAAG;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GACA,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAMD,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFzE;AAyRD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAqG3E;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAC/B,IAAI,GAAE,MAAsC,GAC3C,MAAM,CAGR;AAqED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQnD"}
|
package/dist/internal/cli-mcp.js
CHANGED
|
@@ -68,8 +68,26 @@ export function cmdMcp(subcommand, options) {
|
|
|
68
68
|
if (subcommand === "install") {
|
|
69
69
|
return cmdMcpInstall(options);
|
|
70
70
|
}
|
|
71
|
+
if (subcommand === "oauth") {
|
|
72
|
+
const connection = options.oauthConnection;
|
|
73
|
+
if (connection === undefined || connection.trim() === "") {
|
|
74
|
+
err(`Usage: ${CLI} mcp oauth <connection> [--dir .] [--store] [--slug <slug>] [--team <id>]\n` +
|
|
75
|
+
`Authorize defineConnection({ url, oauth: true }) (host PKCE).\n` +
|
|
76
|
+
`--store upserts MCP_OAUTH_<NAME>_* secrets on the hosted deployment.\n`);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
const { cmdMcpOauth } = yield import("./cli-mcp-oauth.js");
|
|
80
|
+
return cmdMcpOauth({
|
|
81
|
+
dir: options.dir,
|
|
82
|
+
connection,
|
|
83
|
+
store: options.store,
|
|
84
|
+
slug: options.slug,
|
|
85
|
+
team: options.team,
|
|
86
|
+
apiKey: options.apiKey,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
71
89
|
err(`Unknown mcp subcommand "${subcommand}".\n` +
|
|
72
|
-
`Usage: ${CLI} mcp [install] --prod [--slug <slug>] | --url <baseUrl>\n`);
|
|
90
|
+
`Usage: ${CLI} mcp [install|oauth <connection>] --prod [--slug <slug>] | --url <baseUrl>\n`);
|
|
73
91
|
return 1;
|
|
74
92
|
});
|
|
75
93
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monorepo dogfood: Node does not trust the corp.anysphere.co CA (curl/Keychain
|
|
3
|
+
* do). vault-run sets NODE_EXTRA_CA_CERTS to scripts/corp.anysphere.co.pem;
|
|
4
|
+
* re-exec once when that file is found above cwd.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findCorpCaPem(startDir?: string): string | undefined;
|
|
7
|
+
/** No-op when already set or no pem. Otherwise re-exec and exit. */
|
|
8
|
+
export declare function ensureCorpCaOrReexec(): void;
|
|
9
|
+
//# sourceMappingURL=corp-ca.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corp-ca.d.ts","sourceRoot":"","sources":["../../src/internal/corp-ca.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,wBAAgB,aAAa,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,SAAS,CAclF;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,IAAI,IAAI,CAmB3C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monorepo dogfood: Node does not trust the corp.anysphere.co CA (curl/Keychain
|
|
3
|
+
* do). vault-run sets NODE_EXTRA_CA_CERTS to scripts/corp.anysphere.co.pem;
|
|
4
|
+
* re-exec once when that file is found above cwd.
|
|
5
|
+
*/
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
const PEM = "corp.anysphere.co.pem";
|
|
10
|
+
export function findCorpCaPem(startDir = process.cwd()) {
|
|
11
|
+
let dir = startDir;
|
|
12
|
+
for (let i = 0; i < 10; i++) {
|
|
13
|
+
const pem = join(dir, "scripts", PEM);
|
|
14
|
+
if (existsSync(pem)) {
|
|
15
|
+
return pem;
|
|
16
|
+
}
|
|
17
|
+
const parent = dirname(dir);
|
|
18
|
+
if (parent === dir) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
dir = parent;
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/** No-op when already set or no pem. Otherwise re-exec and exit. */
|
|
26
|
+
export function ensureCorpCaOrReexec() {
|
|
27
|
+
var _a;
|
|
28
|
+
if (process.env.NODE_EXTRA_CA_CERTS !== undefined &&
|
|
29
|
+
process.env.NODE_EXTRA_CA_CERTS !== "") {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (process.env.AGENTKIT_SKIP_CORP_CA === "1") {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const pem = findCorpCaPem();
|
|
36
|
+
if (pem === undefined) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const result = spawnSync(process.execPath, process.argv.slice(1), {
|
|
40
|
+
stdio: "inherit",
|
|
41
|
+
env: Object.assign(Object.assign({}, process.env), { NODE_EXTRA_CA_CERTS: pem }),
|
|
42
|
+
});
|
|
43
|
+
process.exit((_a = result.status) !== null && _a !== void 0 ? _a : 1);
|
|
44
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { AgentProject, AuthPolicy } from "../../types.js";
|
|
17
17
|
import type { EngineResolvedConnection } from "../session-engine.js";
|
|
18
|
-
import type { CursorBackendClient } from "./backend-client.js";
|
|
18
|
+
import type { AccountMcpServer, CursorBackendClient } from "./backend-client.js";
|
|
19
19
|
export interface CursorAccountConnectionRef {
|
|
20
20
|
/** Connection (MCP server) name — the filename under `agent/mcp-connections/`. */
|
|
21
21
|
name: string;
|
|
@@ -78,10 +78,15 @@ export declare class CursorAccountMcpBridge {
|
|
|
78
78
|
handle(request: Request, ref: CursorAccountConnectionRef): Promise<Response>;
|
|
79
79
|
/**
|
|
80
80
|
* Startup DX: log the account's connector statuses for `refs` without
|
|
81
|
-
* blocking serve startup. Surfaces "needsAuth" connectors
|
|
82
|
-
*
|
|
81
|
+
* blocking serve startup. Surfaces "needsAuth" / "error" connectors with
|
|
82
|
+
* remediation hints (and a backend probe detail for `error`), and filters
|
|
83
|
+
* that matched nothing (typo'd connector names).
|
|
84
|
+
*
|
|
85
|
+
* Returns a promise that settles when every ref's log lines are written —
|
|
86
|
+
* callers may ignore it; tests can await it.
|
|
83
87
|
*/
|
|
84
|
-
logPreflight(refs: CursorAccountConnectionRef[]): void
|
|
88
|
+
logPreflight(refs: CursorAccountConnectionRef[]): Promise<void>;
|
|
89
|
+
private runPreflight;
|
|
85
90
|
private buildServer;
|
|
86
91
|
/** Resolve a tool by exposed name, refreshing once when it is unknown. */
|
|
87
92
|
private findTool;
|
|
@@ -92,4 +97,12 @@ export declare class CursorAccountMcpBridge {
|
|
|
92
97
|
*/
|
|
93
98
|
private getCatalog;
|
|
94
99
|
}
|
|
100
|
+
/** One-line status for the preflight summary (`name (12 tools)` / `name (error: …)`). */
|
|
101
|
+
export declare function formatServerStatusSummary(server: AccountMcpServer, errorDetail?: string): string;
|
|
102
|
+
/**
|
|
103
|
+
* Best-effort detail for an `error`-status connector. ListSandMcpTools only
|
|
104
|
+
* returns the status enum today, so probe ExecuteSandMcpTool (ping) and surface
|
|
105
|
+
* the backend failure text (e.g. `HTTP MCP tool execution failed: fetch failed`).
|
|
106
|
+
*/
|
|
107
|
+
export declare function diagnoseConnectorError(client: Pick<CursorBackendClient, "executeAccountMcpTool">, serverIdentifier: string): Promise<string | undefined>;
|
|
95
108
|
//# sourceMappingURL=account-mcp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-mcp.d.ts","sourceRoot":"","sources":["../../../src/internal/cursor/account-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"account-mcp.d.ts","sourceRoot":"","sources":["../../../src/internal/cursor/account-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAgB7B,MAAM,WAAW,0BAA0B;IACzC,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,GACrD,GAAG,CAAC,MAAM,EAAE,0BAA0B,EAAE,CAAC,CAoB3C;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACpD,IAAI,EAAE,0BAA0B,EAAE,CAAC;IACnC,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,wBAAwB,EAAE,CAkB7B;AAiCD,qBAAa,sBAAsB;IACjC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAE5D,YAAY,IAAI,EAAE;QAChB,MAAM,EAAE,mBAAmB,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAChC;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,EAKA;IAED;;;;OAIG;IACH,UAAU,IAAI,UAAU,CAgBvB;IAED;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,0BAA0B,GAAG,OAAO,CAAC,QAAQ,CAAC,CAO3E;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,IAAI,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D;YAEa,YAAY;IAyE1B,OAAO,CAAC,WAAW;IA2EnB,0EAA0E;YAC5D,QAAQ;IAatB;;;;OAIG;IACH,OAAO,CAAC,UAAU;CAwCnB;AAwFD,yFAAyF;AACzF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,gBAAgB,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAkBR;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,EAC1D,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA4B7B"}
|
|
@@ -129,32 +129,60 @@ export class CursorAccountMcpBridge {
|
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
131
|
* Startup DX: log the account's connector statuses for `refs` without
|
|
132
|
-
* blocking serve startup. Surfaces "needsAuth" connectors
|
|
133
|
-
*
|
|
132
|
+
* blocking serve startup. Surfaces "needsAuth" / "error" connectors with
|
|
133
|
+
* remediation hints (and a backend probe detail for `error`), and filters
|
|
134
|
+
* that matched nothing (typo'd connector names).
|
|
135
|
+
*
|
|
136
|
+
* Returns a promise that settles when every ref's log lines are written —
|
|
137
|
+
* callers may ignore it; tests can await it.
|
|
134
138
|
*/
|
|
135
139
|
logPreflight(refs) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
return Promise.all(refs.map((ref) => this.runPreflight(ref))).then(() => undefined);
|
|
141
|
+
}
|
|
142
|
+
runPreflight(ref) {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
try {
|
|
145
|
+
const catalog = yield this.getCatalog(ref);
|
|
146
|
+
if (catalog.servers.length === 0) {
|
|
147
|
+
this.logger(`[agentkit] Cursor account MCP connection "${ref.name}": no matching connectors on this account — connect servers in Cursor (dashboard → MCP) or fix the \`servers\` filter`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const errorDetails = new Map();
|
|
151
|
+
yield Promise.all(catalog.servers
|
|
152
|
+
.filter((server) => server.status === "error")
|
|
153
|
+
.map((server) => __awaiter(this, void 0, void 0, function* () {
|
|
154
|
+
const detail = yield diagnoseConnectorError(this.client, server.serverIdentifier);
|
|
155
|
+
if (detail !== undefined) {
|
|
156
|
+
errorDetails.set(server.serverIdentifier, detail);
|
|
157
|
+
}
|
|
158
|
+
})));
|
|
139
159
|
const summary = catalog.servers
|
|
140
|
-
.map((server) =>
|
|
141
|
-
? `${server.tools.length} tools`
|
|
142
|
-
: server.status})`)
|
|
160
|
+
.map((server) => formatServerStatusSummary(server, errorDetails.get(server.serverIdentifier)))
|
|
143
161
|
.join(", ");
|
|
144
|
-
this.logger(`[agentkit] Cursor account MCP connection "${ref.name}": ${
|
|
145
|
-
? "no matching connectors on this account — connect servers in Cursor (dashboard → MCP) or fix the `servers` filter"
|
|
146
|
-
: summary}`);
|
|
162
|
+
this.logger(`[agentkit] Cursor account MCP connection "${ref.name}": ${summary}`);
|
|
147
163
|
const needsAuth = catalog.servers.filter((server) => server.status === "needsAuth");
|
|
148
164
|
if (needsAuth.length > 0) {
|
|
149
165
|
this.logger(`[agentkit] Cursor account MCP connection "${ref.name}": ${needsAuth
|
|
150
166
|
.map((server) => server.serverIdentifier)
|
|
151
|
-
.join(", ")} need re-authorization in Cursor before their tools appear`);
|
|
167
|
+
.join(", ")} need re-authorization in Cursor (dashboard → MCP / Settings → MCP) before their tools appear`);
|
|
152
168
|
}
|
|
153
|
-
|
|
154
|
-
.
|
|
169
|
+
const errored = catalog.servers.filter((server) => server.status === "error");
|
|
170
|
+
if (errored.length > 0) {
|
|
171
|
+
const details = errored
|
|
172
|
+
.map((server) => {
|
|
173
|
+
const detail = errorDetails.get(server.serverIdentifier);
|
|
174
|
+
return detail === undefined
|
|
175
|
+
? server.serverIdentifier
|
|
176
|
+
: `${server.serverIdentifier} (${detail})`;
|
|
177
|
+
})
|
|
178
|
+
.join("; ");
|
|
179
|
+
this.logger(`[agentkit] Cursor account MCP connection "${ref.name}": ${details} — Cursor backend could not use this connector (not a missing agentkit login). Re-check the server in Cursor dashboard → MCP, confirm the URL is healthy, and retry after the backend can reach it`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
155
183
|
this.logger(`[agentkit] Cursor account MCP connection "${ref.name}" preflight failed: ${describeError(error)}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
184
|
+
}
|
|
185
|
+
});
|
|
158
186
|
}
|
|
159
187
|
buildServer(ref) {
|
|
160
188
|
const server = new Server({ name: `cursor-account:${ref.name}`, version: "0.1.0" }, {
|
|
@@ -176,11 +204,17 @@ export class CursorAccountMcpBridge {
|
|
|
176
204
|
const tool = yield this.findTool(ref, request.params.name);
|
|
177
205
|
if (tool === undefined) {
|
|
178
206
|
const catalog = yield this.getCatalog(ref);
|
|
207
|
+
const unhealthy = catalog.servers.filter((server) => server.status !== "connected");
|
|
208
|
+
const statusHint = unhealthy.length === 0
|
|
209
|
+
? ""
|
|
210
|
+
: ` Unhealthy connectors: ${unhealthy
|
|
211
|
+
.map((server) => `${server.serverIdentifier}=${server.status}`)
|
|
212
|
+
.join(", ")}.`;
|
|
179
213
|
return {
|
|
180
214
|
content: [
|
|
181
215
|
{
|
|
182
216
|
type: "text",
|
|
183
|
-
text: `Unknown tool "${request.params.name}". Available: ${catalog.tools.map((t) => t.exposedName).join(", ") || "(none)"}
|
|
217
|
+
text: `Unknown tool "${request.params.name}". Available: ${catalog.tools.map((t) => t.exposedName).join(", ") || "(none)"}.${statusHint}`,
|
|
184
218
|
},
|
|
185
219
|
],
|
|
186
220
|
isError: true,
|
|
@@ -340,3 +374,57 @@ function trimTrailingSlash(url) {
|
|
|
340
374
|
function describeError(error) {
|
|
341
375
|
return error instanceof Error ? error.message : String(error);
|
|
342
376
|
}
|
|
377
|
+
/** One-line status for the preflight summary (`name (12 tools)` / `name (error: …)`). */
|
|
378
|
+
export function formatServerStatusSummary(server, errorDetail) {
|
|
379
|
+
switch (server.status) {
|
|
380
|
+
case "connected":
|
|
381
|
+
return `${server.serverIdentifier} (${server.tools.length} tools)`;
|
|
382
|
+
case "needsAuth":
|
|
383
|
+
return `${server.serverIdentifier} (needsAuth — re-authorize in Cursor)`;
|
|
384
|
+
case "loading":
|
|
385
|
+
return `${server.serverIdentifier} (loading)`;
|
|
386
|
+
case "error": {
|
|
387
|
+
const detail = errorDetail === undefined || errorDetail.trim() === ""
|
|
388
|
+
? "backend could not reach connector"
|
|
389
|
+
: errorDetail.trim();
|
|
390
|
+
return `${server.serverIdentifier} (error: ${detail})`;
|
|
391
|
+
}
|
|
392
|
+
default:
|
|
393
|
+
return `${server.serverIdentifier} (${server.status})`;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Best-effort detail for an `error`-status connector. ListSandMcpTools only
|
|
398
|
+
* returns the status enum today, so probe ExecuteSandMcpTool (ping) and surface
|
|
399
|
+
* the backend failure text (e.g. `HTTP MCP tool execution failed: fetch failed`).
|
|
400
|
+
*/
|
|
401
|
+
export function diagnoseConnectorError(client, serverIdentifier) {
|
|
402
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
403
|
+
try {
|
|
404
|
+
const result = yield client.executeAccountMcpTool({
|
|
405
|
+
serverIdentifier,
|
|
406
|
+
// Conventional health tool; even a tool-not-found path usually still
|
|
407
|
+
// surfaces the same transport failure when the connector is down.
|
|
408
|
+
toolName: `${serverIdentifier}-ping`,
|
|
409
|
+
args: {},
|
|
410
|
+
});
|
|
411
|
+
const text = result.content
|
|
412
|
+
.filter((part) => part.type === "text")
|
|
413
|
+
.map((part) => part.text.trim())
|
|
414
|
+
.filter((part) => part.length > 0)
|
|
415
|
+
.join(" ");
|
|
416
|
+
if (result.isError) {
|
|
417
|
+
return text.length > 0
|
|
418
|
+
? text
|
|
419
|
+
: "backend reported an error with no detail";
|
|
420
|
+
}
|
|
421
|
+
// Listing said error but ping succeeded — surface that inconsistency.
|
|
422
|
+
return text.length > 0
|
|
423
|
+
? `listing reported error but probe succeeded: ${text}`
|
|
424
|
+
: "listing reported error but probe succeeded";
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
return describeError(error);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/internal/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,OAAO,
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/internal/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAKrB,KAAK,UAAU,EAoBhB,MAAM,aAAa,CAAC;AAqBrB,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC3E;AAmBD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASrE;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CA2B1B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAoBzD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAAuB,GAAG;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CACtB,GACL,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAgBzD;AAWD,iFAAiF;AACjF,eAAO,MAAM,cAAc,EAAE,GAAG,CAAC,MAAM,CAIrC,CAAC;AAEH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,YAAY,CAAC,CA8DvB;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAElE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAOnE;AAmnBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiB3E;AAmlBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CAoInE"}
|