@cursor/july 0.1.12 → 0.1.15
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/bin/agent-serve.js +32 -9
- package/dist/channels/github/api.d.ts.map +1 -1
- package/dist/channels/github/api.js +11 -4
- package/dist/channels/github/cursor-account.d.ts +21 -1
- package/dist/channels/github/cursor-account.d.ts.map +1 -1
- package/dist/channels/github/cursor-account.js +29 -1
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +1 -1
- package/dist/channels/slack/api.d.ts +9 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +40 -7
- package/dist/channels/slack/eval-directive.d.ts +3 -0
- package/dist/channels/slack/eval-directive.d.ts.map +1 -1
- package/dist/channels/slack/eval-directive.js +20 -1
- package/dist/channels/slack/post-update-delivery.d.ts +85 -0
- package/dist/channels/slack/post-update-delivery.d.ts.map +1 -0
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.Dh_JkJjI.js → app.DpdGZTLe.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.D2d8CfFS.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.CptQNLkR.js → VPLocalSearchBox.IB-0QqIT.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DWflH-LQ.js → theme.-fYBoNtR.js} +2 -2
- package/dist/docs/assets/{evals.md.DAgEc_hL.js → evals.md.DYOjkRCX.js} +10 -4
- package/dist/docs/assets/{evals.md.DAgEc_hL.lean.js → evals.md.DYOjkRCX.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.B74NrVzb.js → reference_cli.md.DnYfr5V2.js} +4 -1
- package/dist/docs/assets/{reference_http-api.md.Dx_nmDG6.js → reference_http-api.md.BncLd3PZ.js} +2 -2
- package/dist/docs/assets/{reference_http-api.md.Dx_nmDG6.lean.js → reference_http-api.md.BncLd3PZ.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +13 -7
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +8 -5
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +5 -5
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/evals.d.ts +49 -2
- package/dist/evals.d.ts.map +1 -1
- package/dist/evals.js +53 -16
- package/dist/internal/cli-ax.d.ts +4 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +166 -33
- package/dist/internal/cli-deploy.d.ts +8 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +92 -12
- package/dist/internal/cli-mcp-oauth.d.ts +14 -2
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +95 -2
- package/dist/internal/cursor/backend-client.d.ts +34 -0
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +73 -9
- package/dist/internal/cursor/credentials.d.ts +7 -1
- package/dist/internal/cursor/credentials.d.ts.map +1 -1
- package/dist/internal/cursor/credentials.js +9 -3
- package/dist/internal/cursor-account-mcp-auth.d.ts +55 -0
- package/dist/internal/cursor-account-mcp-auth.d.ts.map +1 -0
- package/dist/internal/cursor-account-mcp-auth.js +175 -0
- package/dist/internal/deploy-client.d.ts +6 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +13 -0
- package/dist/internal/eval-run-store.d.ts +15 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +94 -8
- package/dist/internal/eval-runner.d.ts +14 -0
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +111 -22
- package/dist/internal/evals-client.d.ts +9 -1
- package/dist/internal/evals-client.d.ts.map +1 -1
- package/dist/internal/evals-client.js +44 -1
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +74 -7
- package/dist/internal/map-pool.d.ts +6 -1
- package/dist/internal/map-pool.d.ts.map +1 -1
- package/dist/internal/map-pool.js +8 -1
- package/dist/internal/mcp-host.d.ts +13 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +68 -13
- package/dist/internal/persistence-coordinator.d.ts +127 -0
- package/dist/internal/persistence-coordinator.d.ts.map +1 -0
- package/dist/internal/run-client.d.ts +5 -1
- package/dist/internal/run-client.d.ts.map +1 -1
- package/dist/internal/run-client.js +26 -5
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +57 -4
- package/dist/internal/session-engine.d.ts +13 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +49 -0
- package/dist/internal/storage-coordinator.d.ts +7 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +29 -4
- package/dist/persistence.d.ts +184 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/playground/assets/{index-1dzluIcW.js → index-BVMOoiek.js} +44 -44
- package/dist/playground/assets/index-DYmP4b--.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/evals.md +46 -11
- package/docs/reference/cli.md +3 -0
- package/docs/reference/http-api.md +2 -1
- package/package.json +1 -1
- package/skills/evals/SKILL.md +10 -0
- package/src/bin/agent-serve.ts +38 -8
- package/src/channels/github/api.ts +12 -1
- package/src/channels/github/cursor-account.ts +51 -1
- package/src/channels/github/github-channel.ts +4 -1
- package/src/channels/slack/api.ts +57 -8
- package/src/channels/slack/eval-directive.ts +24 -1
- package/src/evals.ts +112 -25
- package/src/internal/cli-ax.ts +195 -16
- package/src/internal/cli-deploy.ts +140 -13
- package/src/internal/cli-mcp-oauth.ts +122 -3
- package/src/internal/cursor/backend-client.ts +104 -1
- package/src/internal/cursor/credentials.ts +10 -2
- package/src/internal/cursor-account-mcp-auth.ts +241 -0
- package/src/internal/deploy-client.ts +16 -0
- package/src/internal/eval-run-store.ts +97 -6
- package/src/internal/eval-runner.ts +129 -18
- package/src/internal/evals-client.ts +82 -0
- package/src/internal/http-channel.ts +87 -6
- package/src/internal/map-pool.ts +8 -1
- package/src/internal/mcp-host.ts +74 -16
- package/src/internal/run-client.ts +32 -1
- package/src/internal/server.ts +69 -2
- package/src/internal/session-engine.ts +58 -0
- package/src/internal/storage-coordinator.ts +32 -6
- package/src/types.ts +10 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.Er_R50vY.js +0 -1
- package/dist/internal/json-dir-store.js +0 -100
- package/dist/playground/assets/index-kZjeJs1v.css +0 -1
- /package/dist/docs/assets/{reference_cli.md.B74NrVzb.lean.js → reference_cli.md.DnYfr5V2.lean.js} +0 -0
|
@@ -18,9 +18,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
18
18
|
});
|
|
19
19
|
};
|
|
20
20
|
import { basename, resolve } from "node:path";
|
|
21
|
+
import { isCursorAccountTransport, } from "../types.js";
|
|
21
22
|
import { CursorBackendClient } from "./cursor/backend-client.js";
|
|
22
23
|
import { cursorExternalApiUrl, resolveApiKey, SIGN_IN_HINT, } from "./cursor/credentials.js";
|
|
23
|
-
import {
|
|
24
|
+
import { authorizeCursorAccountConnectors } from "./cursor-account-mcp-auth.js";
|
|
25
|
+
import { AgentServeDeployClient, DeployApiError, deploymentServiceAccountId, slugFromDirectoryName, TERMINAL_DEPLOY_STATUSES, validateDeploymentSlug, } from "./deploy-client.js";
|
|
24
26
|
import { inferDeployGitSource } from "./deploy-source.js";
|
|
25
27
|
import { isAgentProjectDir, listChildAgentDirs, loadAgentProject, } from "./discovery.js";
|
|
26
28
|
import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
|
|
@@ -81,7 +83,12 @@ export function resolveDeployAuth(options) {
|
|
|
81
83
|
const dim = stderrPalette().dim;
|
|
82
84
|
err(`${dim(`Using team ${teamId}${identity.teamName === undefined ? "" : ` (${identity.teamName})`} — the account's team; pass --team to override.`)}\n`);
|
|
83
85
|
}
|
|
84
|
-
return {
|
|
86
|
+
return {
|
|
87
|
+
client,
|
|
88
|
+
teamId,
|
|
89
|
+
apiKey: resolved.apiKey,
|
|
90
|
+
backendUrl: resolved.backendUrl,
|
|
91
|
+
};
|
|
85
92
|
});
|
|
86
93
|
}
|
|
87
94
|
/**
|
|
@@ -105,6 +112,8 @@ function prepare(options) {
|
|
|
105
112
|
return {
|
|
106
113
|
client: auth.client,
|
|
107
114
|
teamId: auth.teamId,
|
|
115
|
+
apiKey: auth.apiKey,
|
|
116
|
+
backendUrl: auth.backendUrl,
|
|
108
117
|
json: options.json === true,
|
|
109
118
|
noWait: options.noWait === true,
|
|
110
119
|
pollIntervalMs: (_c = options.pollIntervalMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_INTERVAL_MS,
|
|
@@ -348,7 +357,7 @@ export function promptChooseDeployTargets(agents, options) {
|
|
|
348
357
|
}
|
|
349
358
|
function deployOne(ctx, options, target, extras) {
|
|
350
359
|
return __awaiter(this, void 0, void 0, function* () {
|
|
351
|
-
var _a, _b, _c, _d, _e, _f;
|
|
360
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
352
361
|
const { dir, slug } = target;
|
|
353
362
|
// Fill --repo/--ref/--path from the local git checkout when omitted so
|
|
354
363
|
// `agentkit deploy` inside an agent directory is enough. Only probe git
|
|
@@ -409,8 +418,10 @@ function deployOne(ctx, options, target, extras) {
|
|
|
409
418
|
// The package manifest (`defineAgent({ hosting })`) is the source of
|
|
410
419
|
// truth for egress domains and expected secret names; flags override or
|
|
411
420
|
// augment it. Directories without an agent project (static placeholder
|
|
412
|
-
// deploys) simply have no manifest.
|
|
413
|
-
|
|
421
|
+
// deploys) simply have no manifest. The same load supplies the
|
|
422
|
+
// cursorAccount connection refs for the post-deploy connector auth.
|
|
423
|
+
const manifest = isAgent ? yield readDeployManifest(dir) : undefined;
|
|
424
|
+
const hosting = manifest === null || manifest === void 0 ? void 0 : manifest.hosting;
|
|
414
425
|
const egressAllowedDomains = [
|
|
415
426
|
...new Set([
|
|
416
427
|
...((_e = hosting === null || hosting === void 0 ? void 0 : hosting.egressDomains) !== null && _e !== void 0 ? _e : []),
|
|
@@ -481,21 +492,90 @@ function deployOne(ctx, options, target, extras) {
|
|
|
481
492
|
` alias: ${aliasUrl}\n` +
|
|
482
493
|
` playground: ${aliasUrl}/playground (sign in with the alias token)\n` +
|
|
483
494
|
` open: ${CLI} playground --prod --slug ${slug} --team ${ctx.teamId}\n`);
|
|
495
|
+
yield runPostDeployConnectorAuth(ctx, options, {
|
|
496
|
+
slug,
|
|
497
|
+
connections: (_g = manifest === null || manifest === void 0 ? void 0 : manifest.cursorAccountConnections) !== null && _g !== void 0 ? _g : [],
|
|
498
|
+
serviceAccountId: deploymentServiceAccountId(detail),
|
|
499
|
+
});
|
|
484
500
|
return 0;
|
|
485
501
|
});
|
|
486
502
|
}
|
|
487
503
|
/**
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
504
|
+
* Post-deploy connector authorization for `cursorAccount` connections: the
|
|
505
|
+
* agent's connectors execute with tokens owned by the deployment's service
|
|
506
|
+
* account, which start out unauthorized. On a TTY this runs the dashboard's
|
|
507
|
+
* Authenticate flow inline (browser OAuth per connector, already-authorized
|
|
508
|
+
* ones skipped); otherwise it reports status only. Never affects the deploy
|
|
509
|
+
* outcome — anything left unauthorized just gets a playground-page pointer.
|
|
491
510
|
*/
|
|
492
|
-
function
|
|
511
|
+
function runPostDeployConnectorAuth(ctx, options, args) {
|
|
493
512
|
return __awaiter(this, void 0, void 0, function* () {
|
|
494
|
-
if (
|
|
495
|
-
return
|
|
513
|
+
if (args.connections.length === 0) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const { serviceAccountId } = args;
|
|
517
|
+
if (serviceAccountId === undefined) {
|
|
518
|
+
ctx.err(`warning: this agent uses Cursor account connectors, but the deployment has no service account; redeploy to mint one.\n`);
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const backendClient = new CursorBackendClient({
|
|
522
|
+
backendUrl: ctx.backendUrl,
|
|
523
|
+
apiKey: ctx.apiKey,
|
|
524
|
+
fetchImpl: options.fetchImpl,
|
|
525
|
+
});
|
|
526
|
+
const interactive = options.openBrowserImpl !== undefined ||
|
|
527
|
+
(process.stdout.isTTY === true && process.stdin.isTTY === true);
|
|
528
|
+
let anyUnauthorized = false;
|
|
529
|
+
for (const ref of args.connections) {
|
|
530
|
+
ctx.out(`\nThis agent uses Cursor account connectors (connection "${ref.name}"${ref.servers === undefined || ref.servers.length === 0
|
|
531
|
+
? ""
|
|
532
|
+
: `: ${ref.servers.join(", ")}`}).\n`);
|
|
533
|
+
try {
|
|
534
|
+
const result = yield authorizeCursorAccountConnectors({
|
|
535
|
+
backendClient,
|
|
536
|
+
teamId: ctx.teamId,
|
|
537
|
+
slug: args.slug,
|
|
538
|
+
serviceAccountId,
|
|
539
|
+
connectionName: ref.name,
|
|
540
|
+
servers: ref.servers,
|
|
541
|
+
interactive,
|
|
542
|
+
out: ctx.out,
|
|
543
|
+
err: ctx.err,
|
|
544
|
+
openBrowserImpl: options.openBrowserImpl,
|
|
545
|
+
sleep: options.sleepImpl,
|
|
546
|
+
pollIntervalMs: options.connectorPollIntervalMs,
|
|
547
|
+
pollTimeoutMs: options.connectorPollTimeoutMs,
|
|
548
|
+
});
|
|
549
|
+
if (result.pending.length > 0 || result.errored.length > 0) {
|
|
550
|
+
anyUnauthorized = true;
|
|
551
|
+
if (result.pending.length > 0) {
|
|
552
|
+
ctx.out(`Connectors not authorized yet: ${result.pending.join(", ")}.\n`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
catch (error) {
|
|
557
|
+
anyUnauthorized = true;
|
|
558
|
+
ctx.err(`warning: could not check connector authorization for "${ref.name}": ${describeError(error)}\n`);
|
|
559
|
+
}
|
|
496
560
|
}
|
|
561
|
+
if (anyUnauthorized) {
|
|
562
|
+
ctx.out(`You can authorize connectors at the playground page (cursor.com dashboard → Deployed Agents → ${args.slug}) or with \`${CLI} mcp oauth <connection>\`.\n`);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Read the deploy-relevant bits of the project manifest at `dir` in one
|
|
568
|
+
* load: the `hosting` block plus the agent's cursorAccount connections.
|
|
569
|
+
*/
|
|
570
|
+
function readDeployManifest(dir) {
|
|
571
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
497
572
|
const project = yield loadAgentProject(dir);
|
|
498
|
-
return
|
|
573
|
+
return {
|
|
574
|
+
hosting: project.agent.hosting,
|
|
575
|
+
cursorAccountConnections: project.agent.connections.flatMap((connection) => isCursorAccountTransport(connection.transport)
|
|
576
|
+
? [{ name: connection.name, servers: connection.transport.servers }]
|
|
577
|
+
: []),
|
|
578
|
+
};
|
|
499
579
|
});
|
|
500
580
|
}
|
|
501
581
|
/**
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agentkit mcp oauth <connection> [--store]
|
|
2
|
+
* `agentkit mcp oauth <connection> [--store]`.
|
|
3
|
+
*
|
|
4
|
+
* Host MCP OAuth for `defineConnection({ url, oauth: true })` (local tokens,
|
|
5
|
+
* optionally stored as deployment secrets), and service-account connector
|
|
6
|
+
* authorization for `defineConnection({ cursorAccount: true })` (tokens
|
|
7
|
+
* stored backend-side against the hosted deployment's service account — see
|
|
8
|
+
* `cursor-account-mcp-auth.ts`).
|
|
3
9
|
*/
|
|
4
10
|
export type McpOauthCliOptions = {
|
|
5
11
|
dir: string;
|
|
6
12
|
connection: string;
|
|
7
|
-
/** Upsert MCP_OAUTH_* on the hosted deployment. */
|
|
13
|
+
/** Upsert MCP_OAUTH_* on the hosted deployment (host-OAuth connections only). */
|
|
8
14
|
store?: boolean;
|
|
9
15
|
slug?: string;
|
|
10
16
|
team?: string;
|
|
11
17
|
apiKey?: string;
|
|
12
18
|
err?: (text: string) => void;
|
|
13
19
|
out?: (text: string) => void;
|
|
20
|
+
/** Test seams. */
|
|
21
|
+
fetchImpl?: typeof fetch;
|
|
22
|
+
openBrowserImpl?: (url: string) => void;
|
|
23
|
+
sleep?: (ms: number) => Promise<void>;
|
|
24
|
+
pollIntervalMs?: number;
|
|
25
|
+
pollTimeoutMs?: number;
|
|
14
26
|
};
|
|
15
27
|
export declare function cmdMcpOauth(options: McpOauthCliOptions): Promise<number>;
|
|
16
28
|
//# sourceMappingURL=cli-mcp-oauth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-mcp-oauth.d.ts","sourceRoot":"","sources":["../../src/internal/cli-mcp-oauth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cli-mcp-oauth.d.ts","sourceRoot":"","sources":["../../src/internal/cli-mcp-oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,kBAAkB;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAiBF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CA6IjB"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agentkit mcp oauth <connection> [--store]
|
|
2
|
+
* `agentkit mcp oauth <connection> [--store]`.
|
|
3
|
+
*
|
|
4
|
+
* Host MCP OAuth for `defineConnection({ url, oauth: true })` (local tokens,
|
|
5
|
+
* optionally stored as deployment secrets), and service-account connector
|
|
6
|
+
* authorization for `defineConnection({ cursorAccount: true })` (tokens
|
|
7
|
+
* stored backend-side against the hosted deployment's service account — see
|
|
8
|
+
* `cursor-account-mcp-auth.ts`).
|
|
3
9
|
*/
|
|
4
10
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
11
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -14,7 +20,11 @@ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
|
14
20
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
15
21
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
16
22
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
23
|
+
import { isCursorAccountTransport } from "../types.js";
|
|
17
24
|
import { resolveDeployAuth } from "./cli-deploy.js";
|
|
25
|
+
import { CursorBackendClient } from "./cursor/backend-client.js";
|
|
26
|
+
import { authorizeCursorAccountConnectors } from "./cursor-account-mcp-auth.js";
|
|
27
|
+
import { deploymentServiceAccountId } from "./deploy-client.js";
|
|
18
28
|
import { loadAgentProject } from "./discovery.js";
|
|
19
29
|
import { CLI_COMMAND_NAME as CLI, LOG_PREFIX } from "./distribution.js";
|
|
20
30
|
import { createHostMcpOAuthProvider, MCP_OAUTH_CALLBACK_URL, mcpOauthSecretNames, openBrowser, waitForMcpOAuthCallback, } from "./mcp-oauth.js";
|
|
@@ -46,8 +56,15 @@ export function cmdMcpOauth(options) {
|
|
|
46
56
|
return 1;
|
|
47
57
|
}
|
|
48
58
|
const transport = connection.transport;
|
|
59
|
+
if (isCursorAccountTransport(transport)) {
|
|
60
|
+
return cmdMcpOauthCursorAccount(options, {
|
|
61
|
+
servers: transport.servers,
|
|
62
|
+
out,
|
|
63
|
+
err,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
49
66
|
if (!("url" in transport) || transport.oauth !== true) {
|
|
50
|
-
err(`${LOG_PREFIX} "${options.connection}" must be defineConnection({ url, oauth: true }).\n`);
|
|
67
|
+
err(`${LOG_PREFIX} "${options.connection}" must be defineConnection({ url, oauth: true }) or defineConnection({ cursorAccount: true }).\n`);
|
|
51
68
|
return 1;
|
|
52
69
|
}
|
|
53
70
|
out(`${LOG_PREFIX} Authorizing "${options.connection}" (${transport.url})…\n`);
|
|
@@ -142,6 +159,82 @@ export function cmdMcpOauth(options) {
|
|
|
142
159
|
});
|
|
143
160
|
});
|
|
144
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* `mcp oauth` for a `cursorAccount` connection: authorize the hosted
|
|
164
|
+
* deployment's service account for the connection's connectors. Tokens are
|
|
165
|
+
* stored backend-side by the cursor.com OAuth callback, so `--store` (a
|
|
166
|
+
* deployment-secrets concept) is a no-op here.
|
|
167
|
+
*/
|
|
168
|
+
function cmdMcpOauthCursorAccount(options, args) {
|
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
const { out, err } = args;
|
|
171
|
+
let slug;
|
|
172
|
+
try {
|
|
173
|
+
slug = resolveProdSlug({ dir: options.dir, slug: options.slug });
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
err(`${LOG_PREFIX} ${describe(error)}\n`);
|
|
177
|
+
return 1;
|
|
178
|
+
}
|
|
179
|
+
const auth = yield resolveDeployAuth({
|
|
180
|
+
team: options.team,
|
|
181
|
+
apiKey: options.apiKey,
|
|
182
|
+
fetchImpl: options.fetchImpl,
|
|
183
|
+
err,
|
|
184
|
+
});
|
|
185
|
+
if (typeof auth === "number") {
|
|
186
|
+
return auth;
|
|
187
|
+
}
|
|
188
|
+
const backendClient = new CursorBackendClient({
|
|
189
|
+
backendUrl: auth.backendUrl,
|
|
190
|
+
apiKey: auth.apiKey,
|
|
191
|
+
fetchImpl: options.fetchImpl,
|
|
192
|
+
});
|
|
193
|
+
let serviceAccountId;
|
|
194
|
+
try {
|
|
195
|
+
const detail = yield auth.client.getDeployment({
|
|
196
|
+
teamId: auth.teamId,
|
|
197
|
+
slug,
|
|
198
|
+
});
|
|
199
|
+
serviceAccountId = deploymentServiceAccountId(detail);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
err(`${LOG_PREFIX} Could not load deployment "${slug}" (team ${auth.teamId}): ${describe(error)}\n` +
|
|
203
|
+
`${LOG_PREFIX} Deploy first with \`${CLI} deploy\`.\n`);
|
|
204
|
+
return 1;
|
|
205
|
+
}
|
|
206
|
+
if (serviceAccountId === undefined) {
|
|
207
|
+
err(`${LOG_PREFIX} Deployment "${slug}" has no service account yet (it predates service-account-backed deploys). Redeploy with \`${CLI} deploy\` and rerun.\n`);
|
|
208
|
+
return 1;
|
|
209
|
+
}
|
|
210
|
+
if (options.store === true) {
|
|
211
|
+
out(`${LOG_PREFIX} Note: --store is not needed for cursorAccount connections — tokens are stored on the Cursor backend against the deployment's service account.\n`);
|
|
212
|
+
}
|
|
213
|
+
out(`${LOG_PREFIX} Authorizing connection "${options.connection}" for ${slug}'s service account…\n`);
|
|
214
|
+
const result = yield authorizeCursorAccountConnectors({
|
|
215
|
+
backendClient,
|
|
216
|
+
teamId: auth.teamId,
|
|
217
|
+
slug,
|
|
218
|
+
serviceAccountId,
|
|
219
|
+
connectionName: options.connection,
|
|
220
|
+
servers: args.servers,
|
|
221
|
+
interactive: true,
|
|
222
|
+
out,
|
|
223
|
+
err,
|
|
224
|
+
openBrowserImpl: options.openBrowserImpl,
|
|
225
|
+
sleep: options.sleep,
|
|
226
|
+
pollIntervalMs: options.pollIntervalMs,
|
|
227
|
+
pollTimeoutMs: options.pollTimeoutMs,
|
|
228
|
+
});
|
|
229
|
+
if (result.pending.length > 0 || result.errored.length > 0) {
|
|
230
|
+
err(`${LOG_PREFIX} You can authorize connectors any time from the playground page ` +
|
|
231
|
+
`(cursor.com dashboard → Deployed Agents → ${slug}) or by rerunning ` +
|
|
232
|
+
`\`${CLI} mcp oauth ${options.connection}\`.\n`);
|
|
233
|
+
return 1;
|
|
234
|
+
}
|
|
235
|
+
return 0;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
145
238
|
function storeOauthSecrets(args) {
|
|
146
239
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
240
|
const tokens = args.tokens;
|
|
@@ -31,6 +31,20 @@ export interface CursorGithubToken {
|
|
|
31
31
|
token: string;
|
|
32
32
|
expiresAt: string;
|
|
33
33
|
}
|
|
34
|
+
/** One connector row from the account's dashboard MCP listing. */
|
|
35
|
+
export interface AvailableMcpServer {
|
|
36
|
+
id: number;
|
|
37
|
+
name: string;
|
|
38
|
+
isTeamServer: boolean;
|
|
39
|
+
serverIdentifier?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Per-connector OAuth status (SA-scoped when `serviceAccountId` was sent). */
|
|
42
|
+
export interface McpConnectorStatus {
|
|
43
|
+
id: number;
|
|
44
|
+
requiresAuth: boolean;
|
|
45
|
+
authUrl?: string;
|
|
46
|
+
error?: string;
|
|
47
|
+
}
|
|
34
48
|
export interface AccountMcpTool {
|
|
35
49
|
/** Fully-qualified tool name (`<server>-<tool>`), the execution key. */
|
|
36
50
|
name: string;
|
|
@@ -89,6 +103,26 @@ export declare class CursorBackendClient {
|
|
|
89
103
|
toolName: string;
|
|
90
104
|
args: Record<string, unknown>;
|
|
91
105
|
}): Promise<AccountMcpCallResult>;
|
|
106
|
+
/**
|
|
107
|
+
* The account's dashboard MCP connector listing (id + name per server).
|
|
108
|
+
* `teamId` pins the ambient team so team-scoped connectors resolve for
|
|
109
|
+
* multi-team accounts.
|
|
110
|
+
*/
|
|
111
|
+
getAvailableMcpServers(options?: {
|
|
112
|
+
teamId?: number;
|
|
113
|
+
}): Promise<AvailableMcpServer[]>;
|
|
114
|
+
/**
|
|
115
|
+
* Probe connectors for a service account and mint OAuth `authUrl`s where
|
|
116
|
+
* authorization is needed. This is the dashboard's Authenticate flow: the
|
|
117
|
+
* caller (a team member) opens the returned URL, the cursor.com callback
|
|
118
|
+
* stores the token backend-side against the service account, and repeat
|
|
119
|
+
* probes flip `requiresAuth` off.
|
|
120
|
+
*/
|
|
121
|
+
checkHttpMcpStatus(args: {
|
|
122
|
+
serverIds: number[];
|
|
123
|
+
oauthRedirectUri: string;
|
|
124
|
+
serviceAccountId: string;
|
|
125
|
+
}): Promise<McpConnectorStatus[]>;
|
|
92
126
|
/** Mint a short-lived GitHub token scoped to the requested repositories. */
|
|
93
127
|
getGithubToken(repos: readonly string[], options?: {
|
|
94
128
|
permissions?: "read" | "pr-write" | "contents-write";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-client.d.ts","sourceRoot":"","sources":["../../../src/internal/cursor/backend-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM;IAHhC,YACE,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,YAAY,CAAC,EAAE,MAAM,YAAA,EAI/B;CACF;AAMD,QAAA,MAAM,mBAAmB,EAAE,CAAC,CAAC,SAAS,CACpC;IACE,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClC,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CACtC,EACD,OAAO,CAQP,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMjE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AA6BD,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAgDD,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CACV;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC9B;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CACrD,CAAC;IACF,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;
|
|
1
|
+
{"version":3,"file":"backend-client.d.ts","sourceRoot":"","sources":["../../../src/internal/cursor/backend-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,26 @@ const mcpToolSchema = z.object({
|
|
|
67
67
|
/** `google.protobuf.Value` — an arbitrary JSON Schema object. */
|
|
68
68
|
inputSchema: z.unknown().optional(),
|
|
69
69
|
});
|
|
70
|
+
const getAvailableMcpServersResponseSchema = z.object({
|
|
71
|
+
servers: z
|
|
72
|
+
.array(z.object({
|
|
73
|
+
id: z.number().optional(),
|
|
74
|
+
name: z.string().optional(),
|
|
75
|
+
isTeamServer: z.boolean().optional(),
|
|
76
|
+
serverIdentifier: z.string().optional(),
|
|
77
|
+
}))
|
|
78
|
+
.optional(),
|
|
79
|
+
});
|
|
80
|
+
const checkHttpMcpStatusResponseSchema = z.object({
|
|
81
|
+
statuses: z
|
|
82
|
+
.array(z.object({
|
|
83
|
+
id: z.number().optional(),
|
|
84
|
+
requiresAuth: z.boolean().optional(),
|
|
85
|
+
authUrl: z.string().optional(),
|
|
86
|
+
error: z.string().optional(),
|
|
87
|
+
}))
|
|
88
|
+
.optional(),
|
|
89
|
+
});
|
|
70
90
|
const listSandMcpToolsResponseSchema = z.object({
|
|
71
91
|
servers: z
|
|
72
92
|
.array(z.object({
|
|
@@ -129,14 +149,7 @@ function dashboardRpc(args) {
|
|
|
129
149
|
try {
|
|
130
150
|
return yield args.fetchImpl(`${args.backendUrl}${SERVICE_PREFIX}/${args.method}`, {
|
|
131
151
|
method: "POST",
|
|
132
|
-
headers: {
|
|
133
|
-
"content-type": "application/json",
|
|
134
|
-
authorization: `Bearer ${args.bearer}`,
|
|
135
|
-
"x-ghost-mode": "true",
|
|
136
|
-
"x-cursor-client-version": CLIENT_VERSION,
|
|
137
|
-
"x-cursor-client-type": "agent-serve",
|
|
138
|
-
"x-request-id": randomUUID(),
|
|
139
|
-
},
|
|
152
|
+
headers: Object.assign({ "content-type": "application/json", authorization: `Bearer ${args.bearer}`, "x-ghost-mode": "true", "x-cursor-client-version": CLIENT_VERSION, "x-cursor-client-type": "agent-serve", "x-request-id": randomUUID() }, args.extraHeaders),
|
|
140
153
|
body: JSON.stringify((_a = args.body) !== null && _a !== void 0 ? _a : {}),
|
|
141
154
|
signal: AbortSignal.timeout(args.timeoutMs),
|
|
142
155
|
});
|
|
@@ -216,6 +229,52 @@ export class CursorBackendClient {
|
|
|
216
229
|
return toCallResult((_a = parsed.result) !== null && _a !== void 0 ? _a : {});
|
|
217
230
|
});
|
|
218
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* The account's dashboard MCP connector listing (id + name per server).
|
|
234
|
+
* `teamId` pins the ambient team so team-scoped connectors resolve for
|
|
235
|
+
* multi-team accounts.
|
|
236
|
+
*/
|
|
237
|
+
getAvailableMcpServers(options) {
|
|
238
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
239
|
+
var _a;
|
|
240
|
+
const raw = yield this.rpc("GetAvailableMcpServers", {}, LIST_TIMEOUT_MS, {
|
|
241
|
+
teamId: options === null || options === void 0 ? void 0 : options.teamId,
|
|
242
|
+
});
|
|
243
|
+
const parsed = getAvailableMcpServersResponseSchema.parse(raw);
|
|
244
|
+
return ((_a = parsed.servers) !== null && _a !== void 0 ? _a : [])
|
|
245
|
+
.filter((server) => server.id !== undefined && server.id > 0)
|
|
246
|
+
.map((server) => { var _a; return ({
|
|
247
|
+
id: server.id,
|
|
248
|
+
name: (_a = server.name) !== null && _a !== void 0 ? _a : "",
|
|
249
|
+
isTeamServer: server.isTeamServer === true,
|
|
250
|
+
serverIdentifier: server.serverIdentifier,
|
|
251
|
+
}); });
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Probe connectors for a service account and mint OAuth `authUrl`s where
|
|
256
|
+
* authorization is needed. This is the dashboard's Authenticate flow: the
|
|
257
|
+
* caller (a team member) opens the returned URL, the cursor.com callback
|
|
258
|
+
* stores the token backend-side against the service account, and repeat
|
|
259
|
+
* probes flip `requiresAuth` off.
|
|
260
|
+
*/
|
|
261
|
+
checkHttpMcpStatus(args) {
|
|
262
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
var _a;
|
|
264
|
+
const raw = yield this.rpc("CheckHttpMcpStatus", {
|
|
265
|
+
serverIds: args.serverIds,
|
|
266
|
+
oauthRedirectUri: args.oauthRedirectUri,
|
|
267
|
+
serviceAccountId: args.serviceAccountId,
|
|
268
|
+
}, LIST_TIMEOUT_MS);
|
|
269
|
+
const parsed = checkHttpMcpStatusResponseSchema.parse(raw);
|
|
270
|
+
return ((_a = parsed.statuses) !== null && _a !== void 0 ? _a : []).map((status) => { var _a; return ({
|
|
271
|
+
id: (_a = status.id) !== null && _a !== void 0 ? _a : 0,
|
|
272
|
+
requiresAuth: status.requiresAuth === true,
|
|
273
|
+
authUrl: status.authUrl,
|
|
274
|
+
error: status.error,
|
|
275
|
+
}); });
|
|
276
|
+
});
|
|
277
|
+
}
|
|
219
278
|
/** Mint a short-lived GitHub token scoped to the requested repositories. */
|
|
220
279
|
getGithubToken(repos, options) {
|
|
221
280
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -251,8 +310,11 @@ export class CursorBackendClient {
|
|
|
251
310
|
});
|
|
252
311
|
}
|
|
253
312
|
rpc(method_1, body_1) {
|
|
254
|
-
return __awaiter(this, arguments, void 0, function* (method, body, timeoutMs = LIST_TIMEOUT_MS) {
|
|
313
|
+
return __awaiter(this, arguments, void 0, function* (method, body, timeoutMs = LIST_TIMEOUT_MS, options) {
|
|
255
314
|
var _a, _b;
|
|
315
|
+
const extraHeaders = (options === null || options === void 0 ? void 0 : options.teamId) === undefined
|
|
316
|
+
? undefined
|
|
317
|
+
: { "x-cursor-team-id": String(options.teamId) };
|
|
256
318
|
const bearer = yield this.getAccessToken();
|
|
257
319
|
const first = yield dashboardRpc({
|
|
258
320
|
fetchImpl: this.fetchImpl,
|
|
@@ -261,6 +323,7 @@ export class CursorBackendClient {
|
|
|
261
323
|
bearer,
|
|
262
324
|
body,
|
|
263
325
|
timeoutMs,
|
|
326
|
+
extraHeaders,
|
|
264
327
|
});
|
|
265
328
|
if (first.status !== 401) {
|
|
266
329
|
return parseRpcResponse(method, first);
|
|
@@ -280,6 +343,7 @@ export class CursorBackendClient {
|
|
|
280
343
|
bearer: retryBearer,
|
|
281
344
|
body,
|
|
282
345
|
timeoutMs,
|
|
346
|
+
extraHeaders,
|
|
283
347
|
});
|
|
284
348
|
if (second.status === 401 && ((_b = this.token) === null || _b === void 0 ? void 0 : _b.value) === retryBearer) {
|
|
285
349
|
// The freshly minted token was rejected too; do not keep serving it.
|
|
@@ -17,7 +17,13 @@
|
|
|
17
17
|
import { z } from "zod";
|
|
18
18
|
export declare const DEFAULT_CURSOR_BACKEND_URL = "https://api2.cursor.sh";
|
|
19
19
|
export declare const DEFAULT_CURSOR_EXTERNAL_API_URL = "https://api.cursor.com";
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Base URL for main-backend-only routes (key exchange, DashboardService —
|
|
22
|
+
* these 404 on api.cursor.com). Hosted pods pin `CURSOR_API_BASE_URL` to the
|
|
23
|
+
* external API, so `AGENT_SERVE_CURSOR_BACKEND_URL` re-pins this family
|
|
24
|
+
* there. Deliberately namespaced: pod env propagates to the SDK harness,
|
|
25
|
+
* which reads the generic `CURSOR_BACKEND_URL` for its own hosts.
|
|
26
|
+
*/
|
|
21
27
|
export declare function cursorBackendUrl(): string;
|
|
22
28
|
/**
|
|
23
29
|
* External API base URL for routes served only by the external-api
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/internal/cursor/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AACnE,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AAGxE
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/internal/cursor/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AACnE,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AAGxE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAUD,QAAA,MAAM,uBAAuB,EAAE,CAAC,CAAC,SAAS,CACxC;IAAE,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAA;CAAE,EAChD,OAAO,CAKP,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAQtC;AAED,6CAA6C;AAC7C,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CACpD,iBAAiB,GAAG,SAAS,CAC9B,CAsBA;AAED,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO/D;AAMD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CActC;AAED,yEAAyE;AACzE,eAAO,MAAM,YAAY,EAAE,MAA8F,CAAC;AAQ1H,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CAU9C;AAKD;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,2CAA2C;IAC3C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmG3B"}
|
|
@@ -32,10 +32,16 @@ import { CLI_COMMAND_NAME } from "../distribution.js";
|
|
|
32
32
|
export const DEFAULT_CURSOR_BACKEND_URL = "https://api2.cursor.sh";
|
|
33
33
|
export const DEFAULT_CURSOR_EXTERNAL_API_URL = "https://api.cursor.com";
|
|
34
34
|
const DEFAULT_CURSOR_WEBSITE_URL = "https://cursor.com";
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Base URL for main-backend-only routes (key exchange, DashboardService —
|
|
37
|
+
* these 404 on api.cursor.com). Hosted pods pin `CURSOR_API_BASE_URL` to the
|
|
38
|
+
* external API, so `AGENT_SERVE_CURSOR_BACKEND_URL` re-pins this family
|
|
39
|
+
* there. Deliberately namespaced: pod env propagates to the SDK harness,
|
|
40
|
+
* which reads the generic `CURSOR_BACKEND_URL` for its own hosts.
|
|
41
|
+
*/
|
|
36
42
|
export function cursorBackendUrl() {
|
|
37
|
-
var _a;
|
|
38
|
-
return trimTrailingSlash((_a = process.env.
|
|
43
|
+
var _a, _b;
|
|
44
|
+
return trimTrailingSlash((_b = (_a = process.env.AGENT_SERVE_CURSOR_BACKEND_URL) !== null && _a !== void 0 ? _a : process.env.CURSOR_API_BASE_URL) !== null && _b !== void 0 ? _b : DEFAULT_CURSOR_BACKEND_URL);
|
|
39
45
|
}
|
|
40
46
|
/**
|
|
41
47
|
* External API base URL for routes served only by the external-api
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service-account connector authorization for
|
|
3
|
+
* `defineConnection({ cursorAccount: true })` on hosted deployments.
|
|
4
|
+
*
|
|
5
|
+
* Hosted engines authenticate as their deployment's dedicated service
|
|
6
|
+
* account, whose connector OAuth tokens live backend-side. This flow is the
|
|
7
|
+
* dashboard's Authenticate button as a CLI loop: probe the connectors via
|
|
8
|
+
* `CheckHttpMcpStatus` (which mints a complete OAuth `authUrl` per connector
|
|
9
|
+
* needing auth), open each URL for the human to grant, and poll until the
|
|
10
|
+
* backend reports the token stored. Nothing token-shaped ever touches this
|
|
11
|
+
* process — the cursor.com callback stores tokens against the service
|
|
12
|
+
* account. Used by `agentkit mcp oauth <connection>` and the post-deploy
|
|
13
|
+
* hook in `cli-deploy.ts`.
|
|
14
|
+
*/
|
|
15
|
+
import type { CursorBackendClient } from "./cursor/backend-client.js";
|
|
16
|
+
/** Same default the dashboard uses; MCP_OAUTH_REDIRECT_URI overrides for dev. */
|
|
17
|
+
export declare function mcpOauthRedirectUri(): string;
|
|
18
|
+
export interface AuthorizeCursorAccountConnectorsArgs {
|
|
19
|
+
backendClient: Pick<CursorBackendClient, "getAvailableMcpServers" | "checkHttpMcpStatus">;
|
|
20
|
+
teamId: number;
|
|
21
|
+
slug: string;
|
|
22
|
+
/** The deployment's dedicated service account (`sa_…`). */
|
|
23
|
+
serviceAccountId: string;
|
|
24
|
+
/** Connection name, for log lines. */
|
|
25
|
+
connectionName: string;
|
|
26
|
+
/** The connection's `servers` filter; undefined = every team connector. */
|
|
27
|
+
servers?: string[] | undefined;
|
|
28
|
+
/** Open auth URLs and poll for completion (TTY); false = report only. */
|
|
29
|
+
interactive: boolean;
|
|
30
|
+
out: (text: string) => void;
|
|
31
|
+
err: (text: string) => void;
|
|
32
|
+
/** Test seams. */
|
|
33
|
+
openBrowserImpl?: (url: string) => void;
|
|
34
|
+
sleep?: (ms: number) => Promise<void>;
|
|
35
|
+
pollIntervalMs?: number;
|
|
36
|
+
pollTimeoutMs?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface AuthorizeCursorAccountConnectorsResult {
|
|
39
|
+
/** Connectors with a stored credential after the flow. */
|
|
40
|
+
authorized: string[];
|
|
41
|
+
/** Connectors still requiring authorization. */
|
|
42
|
+
pending: string[];
|
|
43
|
+
/** Connectors the backend could not probe. */
|
|
44
|
+
errored: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
error: string;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Authorize the deployment service account for the connection's connectors.
|
|
51
|
+
* Already-authorized connectors are skipped; the rest get a browser OAuth
|
|
52
|
+
* each (sequentially), polled until the backend stores the token.
|
|
53
|
+
*/
|
|
54
|
+
export declare function authorizeCursorAccountConnectors(args: AuthorizeCursorAccountConnectorsArgs): Promise<AuthorizeCursorAccountConnectorsResult>;
|
|
55
|
+
//# sourceMappingURL=cursor-account-mcp-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-account-mcp-auth.d.ts","sourceRoot":"","sources":["../../src/internal/cursor-account-mcp-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AAOpC,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI,MAAM,CAM5C;AAED,MAAM,WAAW,oCAAoC;IACnD,aAAa,EAAE,IAAI,CACjB,mBAAmB,EACnB,wBAAwB,GAAG,oBAAoB,CAChD,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC/B,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,kBAAkB;IAClB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sCAAsC;IACrD,0DAA0D;IAC1D,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gDAAgD;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8CAA8C;IAC9C,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAMD;;;;GAIG;AACH,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,oCAAoC,GACzC,OAAO,CAAC,sCAAsC,CAAC,CA8FjD"}
|