@cursor/july 0.1.32 → 0.1.34
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/README.md +1 -1
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +0 -5
- package/dist/bin/agent-serve.d.ts +1 -0
- package/dist/bin/agent-serve.d.ts.map +1 -1
- package/dist/bin/agent-serve.js +32 -2
- package/dist/channels/github/types.d.ts +10 -7
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.C2aVczmo.js → app.FPupl4SP.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.WoYunhnT.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DLEzetbD.js → VPLocalSearchBox.Cd182Cu0.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BkOH1oMp.js → theme.BEM3Okcd.js} +2 -2
- package/dist/docs/assets/{example-agents_weather-agent.md.Dmrcphhl.js → example-agents_weather-agent.md.BADkPqxQ.js} +6 -4
- package/dist/docs/assets/example-agents_weather-agent.md.BADkPqxQ.lean.js +1 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.js +9 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.lean.js +1 -0
- 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 +3 -3
- 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 +10 -8
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +5 -5
- 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 +3 -3
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- 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/files-backends/agent-store-presigned-url.d.ts.map +1 -1
- package/dist/files-backends/agent-store-presigned-url.js +19 -810
- package/dist/files.d.ts +20 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +20 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/internal/artifacts-store.d.ts +14 -6
- package/dist/internal/artifacts-store.d.ts.map +1 -1
- package/dist/internal/artifacts-store.js +160 -16
- package/dist/internal/cli-convert-automation.d.ts +39 -0
- package/dist/internal/cli-convert-automation.d.ts.map +1 -0
- package/dist/internal/cli-convert-automation.js +280 -0
- package/dist/internal/cli-deploy.d.ts +2 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +1 -1
- package/dist/internal/cli-mcp-oauth.d.ts +23 -0
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +57 -33
- package/dist/internal/convert-automation/convert-workflow.d.ts +10 -0
- package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -0
- package/dist/internal/convert-automation/convert-workflow.js +998 -0
- package/dist/internal/convert-automation/index.d.ts +3 -0
- package/dist/internal/convert-automation/index.d.ts.map +1 -0
- package/dist/internal/convert-automation/index.js +1 -0
- package/dist/internal/convert-automation/slug.d.ts +11 -0
- package/dist/internal/convert-automation/slug.d.ts.map +1 -0
- package/dist/internal/convert-automation/slug.js +36 -0
- package/dist/internal/convert-automation/types.d.ts +191 -0
- package/dist/internal/convert-automation/types.d.ts.map +1 -0
- package/dist/internal/convert-automation/types.js +13 -0
- package/dist/internal/cursor-relay-core.d.ts +12 -0
- package/dist/internal/cursor-relay-core.d.ts.map +1 -1
- package/dist/internal/cursor-relay-core.js +42 -8
- package/dist/internal/deploy-client.d.ts +31 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +48 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +3 -32
- package/dist/internal/init-project.d.ts +1 -0
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +1 -1
- package/dist/internal/mcp-endpoint.d.ts +6 -0
- package/dist/internal/mcp-endpoint.d.ts.map +1 -1
- package/dist/internal/mcp-endpoint.js +168 -0
- package/dist/internal/resolved-connections.d.ts +15 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +12 -5
- package/dist/internal/review-comments.d.ts +9 -1
- package/dist/internal/review-comments.d.ts.map +1 -1
- package/dist/internal/review-comments.js +76 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +83 -8
- package/dist/internal/session-engine.d.ts +56 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +252 -83
- package/dist/internal/storage-coordinator.d.ts +0 -15
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +0 -52
- package/dist/internal/workspace.d.ts +10 -5
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +13 -0
- package/dist/memory.d.ts +22 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +100 -8
- package/dist/playground/assets/index-CDDWw0YX.js +85 -0
- package/dist/playground/assets/index-MVuNTd8v.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +0 -4
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +0 -4
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/example-agents/weather-agent.md +29 -11
- package/docs/guides/cloud-runtime.md +6 -4
- package/package.json +3 -22
- package/src/artifacts.ts +0 -6
- package/src/bin/agent-serve.ts +36 -2
- package/src/channels/github/types.ts +10 -7
- package/src/files-backends/agent-store-presigned-url.ts +7 -5
- package/src/files.ts +27 -0
- package/src/index.ts +6 -1
- package/src/internal/artifacts-store.ts +185 -22
- package/src/internal/cli-convert-automation.ts +352 -0
- package/src/internal/cli-deploy.ts +1 -1
- package/src/internal/cli-mcp-oauth.ts +69 -31
- package/src/internal/convert-automation/convert-workflow.ts +1422 -0
- package/src/internal/convert-automation/index.ts +10 -0
- package/src/internal/convert-automation/slug.ts +38 -0
- package/src/internal/convert-automation/types.ts +199 -0
- package/src/internal/cursor-relay-core.ts +62 -3
- package/src/internal/deploy-client.ts +78 -0
- package/src/internal/discovery.ts +3 -37
- package/src/internal/init-project.ts +1 -1
- package/src/internal/mcp-endpoint.ts +243 -0
- package/src/internal/resolved-connections.ts +32 -6
- package/src/internal/review-comments.ts +102 -2
- package/src/internal/server.ts +108 -2
- package/src/internal/session-engine.ts +329 -99
- package/src/internal/storage-coordinator.ts +0 -62
- package/src/internal/workspace.ts +19 -5
- package/src/memory.ts +126 -10
- package/src/storage.ts +0 -6
- package/src/types.ts +15 -0
- package/dist/channels/slack/post-update-delivery.d.ts +0 -85
- package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.xgMnlUSO.js +0 -1
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +0 -9
- package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.lean.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/persistence-coordinator.d.ts +0 -127
- package/dist/internal/persistence-coordinator.d.ts.map +0 -1
- package/dist/multi-tenant.d.ts +0 -80
- package/dist/multi-tenant.d.ts.map +0 -1
- package/dist/multi-tenant.js +0 -69
- package/dist/persistence.d.ts +0 -184
- package/dist/persistence.d.ts.map +0 -1
- package/dist/playground/assets/index-50PKeJlG.css +0 -1
- package/dist/playground/assets/index-C0f2Wl1q.js +0 -85
|
@@ -22,6 +22,8 @@ import { type SessionEngine } from "./session-engine.js";
|
|
|
22
22
|
export declare const MCP_CHANNEL_ID = "mcp";
|
|
23
23
|
/** Mount path of the MCP surface, relative to the agent base. */
|
|
24
24
|
export declare const MCP_ENDPOINT_PATH = "/v1/mcp";
|
|
25
|
+
/** Direct authored server tools used by this agent's cloud turns. */
|
|
26
|
+
export declare const TOOL_MCP_ENDPOINT_PATH = "/v1/mcp/tools";
|
|
25
27
|
export interface AgentMcpEndpoint {
|
|
26
28
|
/**
|
|
27
29
|
* Handle one HTTP request to the MCP mount. `auth` is the principal
|
|
@@ -55,5 +57,9 @@ export declare function createAgentMcpEndpoint(args: {
|
|
|
55
57
|
engine: SessionEngine;
|
|
56
58
|
logger?: (line: string) => void;
|
|
57
59
|
}): AgentMcpEndpoint;
|
|
60
|
+
export declare function createToolMcpEndpoint(args: {
|
|
61
|
+
engine: SessionEngine;
|
|
62
|
+
logger?: (line: string) => void;
|
|
63
|
+
}): AgentMcpEndpoint;
|
|
58
64
|
export {};
|
|
59
65
|
//# sourceMappingURL=mcp-endpoint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-endpoint.d.ts","sourceRoot":"","sources":["../../src/internal/mcp-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"mcp-endpoint.d.ts","sourceRoot":"","sources":["../../src/internal/mcp-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAC;AAOzH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EAGZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAEL,KAAK,aAAa,EAKnB,MAAM,qBAAqB,CAAC;AAE7B,uEAAuE;AACvE,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAUtD,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACvE;AAED,yEAAyE;AACzE,UAAU,oBAAoB;IAC5B,OAAO,CAAC,SAAS,EAAE,wCAAwC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,oBAAoB,CAAC;IACxC,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyCpB;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,CAMpE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,gBAAgB,CAanB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,gBAAgB,CAyBnB"}
|
|
@@ -24,8 +24,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
24
24
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25
25
|
});
|
|
26
26
|
};
|
|
27
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
27
28
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
28
29
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
30
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
29
31
|
import { z } from "zod";
|
|
30
32
|
import { samePrincipal } from "./auth.js";
|
|
31
33
|
import { SessionBusyError, ToolInputError, ToolNotDirectlyCallableError, UnknownSessionError, UnknownToolError, } from "./session-engine.js";
|
|
@@ -33,6 +35,8 @@ import { SessionBusyError, ToolInputError, ToolNotDirectlyCallableError, Unknown
|
|
|
33
35
|
export const MCP_CHANNEL_ID = "mcp";
|
|
34
36
|
/** Mount path of the MCP surface, relative to the agent base. */
|
|
35
37
|
export const MCP_ENDPOINT_PATH = "/v1/mcp";
|
|
38
|
+
/** Direct authored server tools used by this agent's cloud turns. */
|
|
39
|
+
export const TOOL_MCP_ENDPOINT_PATH = "/v1/mcp/tools";
|
|
36
40
|
/**
|
|
37
41
|
* Bounded waits stay below the MCP client default request timeout (60s) so
|
|
38
42
|
* a long model turn degrades to `status: "running"` instead of a client
|
|
@@ -103,6 +107,123 @@ export function createAgentMcpEndpoint(args) {
|
|
|
103
107
|
},
|
|
104
108
|
};
|
|
105
109
|
}
|
|
110
|
+
export function createToolMcpEndpoint(args) {
|
|
111
|
+
const { engine, logger } = args;
|
|
112
|
+
return {
|
|
113
|
+
handle(request) {
|
|
114
|
+
const url = new URL(request.url);
|
|
115
|
+
const sessionId = url.searchParams.get("agentkitSessionId");
|
|
116
|
+
// `connection=<name>` serves a host connection bridge instead of the
|
|
117
|
+
// authored server tools: same endpoint, same auth, same session
|
|
118
|
+
// binding, but tools/list and tools/call forward to `host.mcp` for
|
|
119
|
+
// that connection (see buildConnectionBridgeMcpServer).
|
|
120
|
+
const connection = url.searchParams.get("connection");
|
|
121
|
+
return handleStatelessMcpRequest(Object.assign({ request, buildServer: () => connection === null
|
|
122
|
+
? buildToolMcpServer(engine, sessionId)
|
|
123
|
+
: buildConnectionBridgeMcpServer(engine, sessionId, connection), label: connection === null
|
|
124
|
+
? "tool mcp endpoint"
|
|
125
|
+
: `connection bridge mcp endpoint (${connection})` }, (logger === undefined ? {} : { logger })));
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function buildToolMcpServer(engine, sessionId) {
|
|
130
|
+
const server = new Server({ name: `${engine.project.name}:tools`, version: "0.1.0" }, {
|
|
131
|
+
capabilities: { tools: {} },
|
|
132
|
+
instructions: "Direct tools implemented by the AgentSDK deployment for its active cloud turn.",
|
|
133
|
+
});
|
|
134
|
+
const tools = engine.project.agent.tools.filter((tool) => tool.execution === "server");
|
|
135
|
+
server.setRequestHandler(ListToolsRequestSchema, () => Promise.resolve({
|
|
136
|
+
tools: tools.map((tool) => ({
|
|
137
|
+
name: tool.name,
|
|
138
|
+
description: tool.description,
|
|
139
|
+
inputSchema: tool.inputSchema,
|
|
140
|
+
})),
|
|
141
|
+
}));
|
|
142
|
+
server.setRequestHandler(CallToolRequestSchema, (request) => __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
var _a;
|
|
144
|
+
if (sessionId === null || sessionId === "") {
|
|
145
|
+
return errorResult("Missing AgentSDK session binding.");
|
|
146
|
+
}
|
|
147
|
+
const tool = tools.find((candidate) => candidate.name === request.params.name);
|
|
148
|
+
if (tool === undefined) {
|
|
149
|
+
return errorResult(`Unknown server tool "${request.params.name}".`);
|
|
150
|
+
}
|
|
151
|
+
const result = yield engine.callActiveServerTool(sessionId, tool.name, (_a = request.params.arguments) !== null && _a !== void 0 ? _a : {});
|
|
152
|
+
return sdkResultToMcpResult(result);
|
|
153
|
+
}));
|
|
154
|
+
return server;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Host connection bridge: one authored MCP connection served to a cloud turn
|
|
158
|
+
* over the tool MCP endpoint. Listing and calling forward to the host-side
|
|
159
|
+
* client (`host.mcp`), where the connection's credential — account bridge
|
|
160
|
+
* secret or host OAuth token — actually lives, so nothing key-shaped ever
|
|
161
|
+
* travels in the turn's MCP config or lands on the VM.
|
|
162
|
+
*
|
|
163
|
+
* The engine gates access twice, mirroring the authored server-tool path:
|
|
164
|
+
* only bridgeable names (`isCloudBridgedConnection`) — `hostOnly`
|
|
165
|
+
* connections and unknown names stay unreachable from a VM even with a
|
|
166
|
+
* valid endpoint credential — and only while the bound session has a turn
|
|
167
|
+
* in flight (`hasActiveTurn`), so a credential that persists on a VM after
|
|
168
|
+
* its turn cannot keep calling host connectors. Listing forwards per
|
|
169
|
+
* request, so a server that adds tools mid-session (`tools/list_changed`,
|
|
170
|
+
* e.g. Datadog's skills-first mode) is picked up on the next list instead
|
|
171
|
+
* of never.
|
|
172
|
+
*/
|
|
173
|
+
function buildConnectionBridgeMcpServer(engine, sessionId, connectionName) {
|
|
174
|
+
const server = new Server({
|
|
175
|
+
name: `${engine.project.name}:bridge:${connectionName}`,
|
|
176
|
+
version: "0.1.0",
|
|
177
|
+
}, {
|
|
178
|
+
capabilities: { tools: {} },
|
|
179
|
+
instructions: `Tools from the "${connectionName}" MCP connection, listed and called on the serve host where its credential lives.`,
|
|
180
|
+
});
|
|
181
|
+
const rejected = () => {
|
|
182
|
+
if (sessionId === null || sessionId === "") {
|
|
183
|
+
return "Missing AgentSDK session binding.";
|
|
184
|
+
}
|
|
185
|
+
if (!engine.isCloudBridgedConnection(connectionName)) {
|
|
186
|
+
return `MCP connection "${connectionName}" is not bridged to cloud turns.`;
|
|
187
|
+
}
|
|
188
|
+
if (!engine.hasActiveTurn(sessionId)) {
|
|
189
|
+
return `Session ${sessionId} has no active turn for connection "${connectionName}".`;
|
|
190
|
+
}
|
|
191
|
+
return undefined;
|
|
192
|
+
};
|
|
193
|
+
server.setRequestHandler(ListToolsRequestSchema, () => __awaiter(this, void 0, void 0, function* () {
|
|
194
|
+
const reason = rejected();
|
|
195
|
+
if (reason !== undefined) {
|
|
196
|
+
throw new Error(reason);
|
|
197
|
+
}
|
|
198
|
+
const tools = yield engine.host.mcp.listTools(connectionName);
|
|
199
|
+
return {
|
|
200
|
+
tools: tools.map((tool) => { var _a; return (Object.assign(Object.assign({ name: tool.name }, (tool.description === undefined
|
|
201
|
+
? {}
|
|
202
|
+
: { description: tool.description })), { inputSchema: (_a = tool.inputSchema) !== null && _a !== void 0 ? _a : { type: "object" } })); }),
|
|
203
|
+
};
|
|
204
|
+
}));
|
|
205
|
+
server.setRequestHandler(CallToolRequestSchema, (request) => __awaiter(this, void 0, void 0, function* () {
|
|
206
|
+
var _a;
|
|
207
|
+
const reason = rejected();
|
|
208
|
+
if (reason !== undefined) {
|
|
209
|
+
return errorResult(reason);
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
const result = yield engine.host.mcp.callTool(connectionName, request.params.name, (_a = request.params.arguments) !== null && _a !== void 0 ? _a : {});
|
|
213
|
+
return Object.assign(Object.assign({
|
|
214
|
+
// The host client already speaks MCP, so the content array is valid
|
|
215
|
+
// CallToolResult content; HostMcpCallResult just types the tail of
|
|
216
|
+
// the union open-endedly.
|
|
217
|
+
content: result.content }, (result.isError === undefined ? {} : { isError: result.isError })), (result.structuredContent === undefined
|
|
218
|
+
? {}
|
|
219
|
+
: { structuredContent: result.structuredContent }));
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
return errorResult(`MCP connection "${connectionName}" is not reachable from the serve host: ${describeError(error)}`);
|
|
223
|
+
}
|
|
224
|
+
}));
|
|
225
|
+
return server;
|
|
226
|
+
}
|
|
106
227
|
// ============================================================================
|
|
107
228
|
// Server construction (per request; tools close over the caller principal)
|
|
108
229
|
// ============================================================================
|
|
@@ -335,6 +456,53 @@ function errorResult(message) {
|
|
|
335
456
|
isError: true,
|
|
336
457
|
};
|
|
337
458
|
}
|
|
459
|
+
function sdkResultToMcpResult(result) {
|
|
460
|
+
if (isSdkToolEnvelope(result)) {
|
|
461
|
+
return Object.assign(Object.assign({ content: result.content.map(toMcpContent) }, (result.isError === true ? { isError: true } : {})), (result.structuredContent === undefined
|
|
462
|
+
? {}
|
|
463
|
+
: { structuredContent: result.structuredContent }));
|
|
464
|
+
}
|
|
465
|
+
if (typeof result === "string") {
|
|
466
|
+
return { content: [{ type: "text", text: result }] };
|
|
467
|
+
}
|
|
468
|
+
return Object.assign({ content: [{ type: "text", text: JSON.stringify(result) }] }, (isJsonObject(result) ? { structuredContent: result } : {}));
|
|
469
|
+
}
|
|
470
|
+
function toMcpContent(content) {
|
|
471
|
+
var _a;
|
|
472
|
+
if (content.type === "text") {
|
|
473
|
+
return content;
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
type: "image",
|
|
477
|
+
data: content.data,
|
|
478
|
+
mimeType: (_a = content.mimeType) !== null && _a !== void 0 ? _a : "application/octet-stream",
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
function isSdkToolEnvelope(result) {
|
|
482
|
+
return (typeof result === "object" &&
|
|
483
|
+
result !== null &&
|
|
484
|
+
!Array.isArray(result) &&
|
|
485
|
+
"content" in result &&
|
|
486
|
+
Array.isArray(result.content) &&
|
|
487
|
+
result.content.every(isSdkToolContent));
|
|
488
|
+
}
|
|
489
|
+
function isSdkToolContent(value) {
|
|
490
|
+
if (typeof value !== "object" || value === null || !("type" in value)) {
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
if (value.type === "text") {
|
|
494
|
+
return "text" in value && typeof value.text === "string";
|
|
495
|
+
}
|
|
496
|
+
return (value.type === "image" &&
|
|
497
|
+
"data" in value &&
|
|
498
|
+
typeof value.data === "string" &&
|
|
499
|
+
(!("mimeType" in value) ||
|
|
500
|
+
value.mimeType === undefined ||
|
|
501
|
+
typeof value.mimeType === "string"));
|
|
502
|
+
}
|
|
503
|
+
function isJsonObject(value) {
|
|
504
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
505
|
+
}
|
|
338
506
|
/** Resolve to the promise value, or undefined once `ms` elapses first. */
|
|
339
507
|
function raceTimeout(promise, ms) {
|
|
340
508
|
return new Promise((resolve, reject) => {
|
|
@@ -16,11 +16,24 @@ export declare function validateMountConnectionsConfig(args: {
|
|
|
16
16
|
project: AgentProject;
|
|
17
17
|
accountRefs?: CursorAccountConnectionRef[];
|
|
18
18
|
publicUrl?: string;
|
|
19
|
+
/**
|
|
20
|
+
* True when serve has a cloud tools URL (`--cloud-tools-url`, always set on
|
|
21
|
+
* managed hosting): cloud turns then reach filtered account connections
|
|
22
|
+
* through the host connection bridge on the tool MCP endpoint, so the
|
|
23
|
+
* filter is honored host-side and no `--public-url` is needed.
|
|
24
|
+
*/
|
|
25
|
+
cloudToolsBridge?: boolean;
|
|
19
26
|
}): void;
|
|
20
27
|
/** Fail closed when a cloud turn cannot honor a `servers` filter. */
|
|
21
28
|
export declare function assertCloudCanHonorAccountServersFilters(args: {
|
|
22
29
|
runtime: "local" | "cloud";
|
|
23
30
|
resolvedConnections: readonly EngineResolvedConnection[];
|
|
31
|
+
/**
|
|
32
|
+
* Connection names this cloud turn reaches through the host connection
|
|
33
|
+
* bridge (tool MCP endpoint). The filter is honored on the serve host
|
|
34
|
+
* there, so a missing `cloudUrl` is not a fail-open.
|
|
35
|
+
*/
|
|
36
|
+
bridgedNames?: ReadonlySet<string>;
|
|
24
37
|
}): void;
|
|
25
38
|
/** Fail closed when anonymous HTTP admission would expose account connectors. */
|
|
26
39
|
export declare function assertAccountConnectionsNotAnonymous(args: {
|
|
@@ -42,6 +55,8 @@ export declare function resolveMountConnections(args: {
|
|
|
42
55
|
accountBridge?: CursorAccountMcpBridge;
|
|
43
56
|
publicUrl?: string;
|
|
44
57
|
authToken?: string;
|
|
58
|
+
/** See {@link validateMountConnectionsConfig}. */
|
|
59
|
+
cloudToolsBridge?: boolean;
|
|
45
60
|
logger: (line: string) => void;
|
|
46
61
|
}): EngineResolvedConnection[];
|
|
47
62
|
//# sourceMappingURL=resolved-connections.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolved-connections.d.ts","sourceRoot":"","sources":["../../src/internal/resolved-connections.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAkC,MAAM,aAAa,CAAC;AAChF,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"resolved-connections.d.ts","sourceRoot":"","sources":["../../src/internal/resolved-connections.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAkC,MAAM,aAAa,CAAC;AAChF,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,IAAI,CAgCP;AAED,qEAAqE;AACrE,wBAAgB,wCAAwC,CAAC,IAAI,EAAE;IAC7D,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IAC3B,mBAAmB,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACzD;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC,GAAG,IAAI,CAoBP;AAED,iFAAiF;AACjF,wBAAgB,oCAAoC,CAAC,IAAI,EAAE;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,qBAAqB,EAAE,OAAO,CAAC;CAChC,GAAG,IAAI,CAUP;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,GAAG,wBAAwB,EAAE,CAoE7B"}
|
|
@@ -16,7 +16,9 @@ export function validateMountConnectionsConfig(args) {
|
|
|
16
16
|
}
|
|
17
17
|
const agent = args.project.agent;
|
|
18
18
|
const cloudCapable = agent.runtime === "cloud" || agent.cloud !== undefined;
|
|
19
|
-
if (!cloudCapable ||
|
|
19
|
+
if (!cloudCapable ||
|
|
20
|
+
args.publicUrl !== undefined ||
|
|
21
|
+
args.cloudToolsBridge === true) {
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
22
24
|
const label = args.slug === "" ? args.project.name : args.slug;
|
|
@@ -36,8 +38,9 @@ export function assertCloudCanHonorAccountServersFilters(args) {
|
|
|
36
38
|
if (args.runtime !== "cloud") {
|
|
37
39
|
return;
|
|
38
40
|
}
|
|
39
|
-
const blocked = args.resolvedConnections.filter((connection) => connection.accountServersFilter !== undefined &&
|
|
40
|
-
connection.cloudUrl === undefined
|
|
41
|
+
const blocked = args.resolvedConnections.filter((connection) => { var _a; return connection.accountServersFilter !== undefined &&
|
|
42
|
+
connection.cloudUrl === undefined &&
|
|
43
|
+
((_a = args.bridgedNames) === null || _a === void 0 ? void 0 : _a.has(connection.name)) !== true; });
|
|
41
44
|
if (blocked.length === 0) {
|
|
42
45
|
return;
|
|
43
46
|
}
|
|
@@ -66,7 +69,9 @@ export function resolveMountConnections(args) {
|
|
|
66
69
|
isHostOauthConnectionTransport(connection.transport))
|
|
67
70
|
.map((connection) => connection.name);
|
|
68
71
|
if (hostOauthNames.length > 0) {
|
|
69
|
-
args.logger(
|
|
72
|
+
args.logger(args.cloudToolsBridge === true
|
|
73
|
+
? `[agent-sdk] agent "${label}": host-OAuth MCP connections (${hostOauthNames.join(", ")}) reach cloud turns through the host connection bridge; their tokens stay on this serve host.`
|
|
74
|
+
: `[agent-sdk] warning: agent "${label}" has host-OAuth MCP connections (${hostOauthNames.join(", ")}) whose tokens live on this serve host; cloud-runtime turns omit them. Mark them \`hostOnly: true\` and call them from host tools, or drop \`oauth\` and authorize the server another way.`);
|
|
70
75
|
}
|
|
71
76
|
}
|
|
72
77
|
if (args.peerRefs !== undefined && args.peerRefs.length > 0) {
|
|
@@ -83,7 +88,9 @@ export function resolveMountConnections(args) {
|
|
|
83
88
|
// Non-blocking startup DX: connector statuses land in the serve log.
|
|
84
89
|
args.accountBridge.logPreflight(args.accountRefs);
|
|
85
90
|
if (cloudCapable && args.publicUrl === undefined) {
|
|
86
|
-
args.logger(
|
|
91
|
+
args.logger(args.cloudToolsBridge === true
|
|
92
|
+
? `[agent-sdk] agent "${label}": cloud-runtime turns reach filtered account connections through the host connection bridge (unfiltered ones fall back to the account's native connectors).`
|
|
93
|
+
: `[agent-sdk] agent "${label}": cloud-runtime turns omit the account bridge without --public-url (cloud agents fall back to the account's native connectors).`);
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
96
|
return resolved;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { HostGitHubClient } from "../types.js";
|
|
2
|
+
export type ReviewCommentPublisher = "local_gh" | "host_github";
|
|
2
3
|
export type ReviewCommentPostResult = {
|
|
3
4
|
posted: boolean;
|
|
4
5
|
publisher: ReviewCommentPublisher;
|
|
@@ -47,4 +48,11 @@ export declare function prepareReviewCommentsRequest(args: ReviewCommentPostArgs
|
|
|
47
48
|
* GH_TOKEN). Does not use the security-bugbot comments service.
|
|
48
49
|
*/
|
|
49
50
|
export declare function createLocalGhReviewPublisher(): ReviewCommentPublisherImplementation;
|
|
51
|
+
/**
|
|
52
|
+
* Posts a PR review through the host GitHub client (Cursor account lease,
|
|
53
|
+
* App installation token, or PAT). Prefer this on Cursor-deployed agents —
|
|
54
|
+
* no separate GitHub write secret is required when `githubChannel({
|
|
55
|
+
* cursorAccount })` is bound.
|
|
56
|
+
*/
|
|
57
|
+
export declare function createHostGithubReviewPublisher(github: HostGitHubClient): ReviewCommentPublisherImplementation;
|
|
50
58
|
//# sourceMappingURL=review-comments.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-comments.d.ts","sourceRoot":"","sources":["../../src/internal/review-comments.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-comments.d.ts","sourceRoot":"","sources":["../../src/internal/review-comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,aAAa,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,6BAA6B,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,UAAU,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC/E,CAAC;AAOF;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,qBAAqB,GAEzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,CAkBvD;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,oCAAoC,CAMnF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,gBAAgB,GACvB,oCAAoC,CAMtC"}
|
|
@@ -43,6 +43,70 @@ export function createLocalGhReviewPublisher() {
|
|
|
43
43
|
},
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Posts a PR review through the host GitHub client (Cursor account lease,
|
|
48
|
+
* App installation token, or PAT). Prefer this on Cursor-deployed agents —
|
|
49
|
+
* no separate GitHub write secret is required when `githubChannel({
|
|
50
|
+
* cursorAccount })` is bound.
|
|
51
|
+
*/
|
|
52
|
+
export function createHostGithubReviewPublisher(github) {
|
|
53
|
+
return {
|
|
54
|
+
postReview(args) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
return postReviewViaHostGithub(github, args);
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function postReviewViaHostGithub(github, args) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
var _a, _b, _c;
|
|
64
|
+
const prepared = prepareReviewCommentsRequest(args);
|
|
65
|
+
if (prepared.kind === "skipped") {
|
|
66
|
+
return Object.assign(Object.assign({}, prepared.result), { publisher: "host_github" });
|
|
67
|
+
}
|
|
68
|
+
const { request } = prepared;
|
|
69
|
+
const [owner, repo] = request.repo.split("/", 2);
|
|
70
|
+
if (owner === undefined || repo === undefined || repo === "") {
|
|
71
|
+
return skippedHost("unparseable owner/repo from PR URL");
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
(_a = args.signal) === null || _a === void 0 ? void 0 : _a.throwIfAborted();
|
|
75
|
+
const octokit = yield github.getOctokit();
|
|
76
|
+
(_b = args.signal) === null || _b === void 0 ? void 0 : _b.throwIfAborted();
|
|
77
|
+
const response = yield octokit.rest.pulls.createReview({
|
|
78
|
+
owner,
|
|
79
|
+
repo,
|
|
80
|
+
pull_number: request.prNumber,
|
|
81
|
+
commit_id: request.headSha,
|
|
82
|
+
body: request.message,
|
|
83
|
+
event: "COMMENT",
|
|
84
|
+
comments: request.comments.map(toGithubPullRequestReviewComment),
|
|
85
|
+
});
|
|
86
|
+
const htmlUrl = typeof response.data.html_url === "string"
|
|
87
|
+
? response.data.html_url
|
|
88
|
+
: undefined;
|
|
89
|
+
const inlineCommentCount = request.comments.length;
|
|
90
|
+
return {
|
|
91
|
+
posted: true,
|
|
92
|
+
publisher: "host_github",
|
|
93
|
+
mode: inlineCommentCount > 0
|
|
94
|
+
? "review_with_inline_comments"
|
|
95
|
+
: "review_body_only",
|
|
96
|
+
inlineCommentCount,
|
|
97
|
+
detail: htmlUrl
|
|
98
|
+
? `posted via host GitHub: ${htmlUrl}`
|
|
99
|
+
: `posted via host GitHub with ${inlineCommentCount} inline comment(s)`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if ((_c = args.signal) === null || _c === void 0 ? void 0 : _c.aborted) {
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
return skippedHost(`host GitHub review post failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
46
110
|
function postReviewViaLocalGh(args) {
|
|
47
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
112
|
var _a, _b;
|
|
@@ -84,6 +148,9 @@ function postReviewViaLocalGh(args) {
|
|
|
84
148
|
});
|
|
85
149
|
}
|
|
86
150
|
function toGithubReviewComment(comment) {
|
|
151
|
+
return toGithubPullRequestReviewComment(comment);
|
|
152
|
+
}
|
|
153
|
+
function toGithubPullRequestReviewComment(comment) {
|
|
87
154
|
const body = {
|
|
88
155
|
path: comment.file,
|
|
89
156
|
body: comment.body,
|
|
@@ -107,6 +174,15 @@ function skipped(detail) {
|
|
|
107
174
|
detail,
|
|
108
175
|
};
|
|
109
176
|
}
|
|
177
|
+
function skippedHost(detail) {
|
|
178
|
+
return {
|
|
179
|
+
posted: false,
|
|
180
|
+
publisher: "host_github",
|
|
181
|
+
mode: "skipped",
|
|
182
|
+
inlineCommentCount: 0,
|
|
183
|
+
detail,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
110
186
|
function parseGithubPrUrl(prUrl) {
|
|
111
187
|
let url;
|
|
112
188
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAmGrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAiBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAaD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAmuB3B"}
|
package/dist/internal/server.js
CHANGED
|
@@ -56,7 +56,7 @@ import { buildHttpChannelRoutes, errorResponse, jsonResponse, readJsonObject, re
|
|
|
56
56
|
import { validateToolInput } from "./json-schema.js";
|
|
57
57
|
import { createLocalControlPlane, } from "./local-control-plane.js";
|
|
58
58
|
import { createLogRing } from "./log-ring.js";
|
|
59
|
-
import { createAgentMcpEndpoint, MCP_ENDPOINT_PATH } from "./mcp-endpoint.js";
|
|
59
|
+
import { createAgentMcpEndpoint, createToolMcpEndpoint, MCP_ENDPOINT_PATH, TOOL_MCP_ENDPOINT_PATH, } from "./mcp-endpoint.js";
|
|
60
60
|
import { isLoopbackAddress } from "./net.js";
|
|
61
61
|
import { collectPeerConnections } from "./peer-connections.js";
|
|
62
62
|
import { PLATFORM_SCHEDULE_CATALOG_FILENAME, syncHostedPlatformSchedules, } from "./platform-schedule-sync.js";
|
|
@@ -82,8 +82,8 @@ const ARTIFACTS_LIST_MAX_LIMIT = 1000;
|
|
|
82
82
|
export function startServer(mounts_1) {
|
|
83
83
|
return __awaiter(this, arguments, void 0, function* (mounts, options = {}) {
|
|
84
84
|
var _a, _b, _c;
|
|
85
|
-
var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
86
|
-
var
|
|
85
|
+
var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
86
|
+
var _s;
|
|
87
87
|
if (mounts.length === 0) {
|
|
88
88
|
throw new Error("startServer requires at least one agent mount");
|
|
89
89
|
}
|
|
@@ -104,7 +104,7 @@ export function startServer(mounts_1) {
|
|
|
104
104
|
// Identify this process to the Cursor backend as agentkit (the SDK reads
|
|
105
105
|
// this when building its client-version header) so the internal-only
|
|
106
106
|
// agentkit_enabled gate applies to every turn.
|
|
107
|
-
(_j = (
|
|
107
|
+
(_j = (_s = process.env).CURSOR_AGENTKIT_VERSION) !== null && _j !== void 0 ? _j : (_s.CURSOR_AGENTKIT_VERSION = packageVersion());
|
|
108
108
|
const cursorGithubTargets = collectCursorGithubTargets(mounts);
|
|
109
109
|
const cursorGithubConfig = resolveCursorGithubEventConfig({
|
|
110
110
|
configured: options.cursorEvents,
|
|
@@ -469,10 +469,10 @@ export function startServer(mounts_1) {
|
|
|
469
469
|
}),
|
|
470
470
|
});
|
|
471
471
|
for (const { slug, project } of mounts) {
|
|
472
|
-
validateMountConnectionsConfig(Object.assign({ slug,
|
|
472
|
+
validateMountConnectionsConfig(Object.assign(Object.assign({ slug,
|
|
473
473
|
project, accountRefs: accountRefsBySlug.get(slug) }, (options.publicUrl === undefined
|
|
474
474
|
? {}
|
|
475
|
-
: { publicUrl: options.publicUrl })));
|
|
475
|
+
: { publicUrl: options.publicUrl })), { cloudToolsBridge: options.cloudToolsUrl !== undefined }));
|
|
476
476
|
}
|
|
477
477
|
// Cursor Slack relay: automatic when a mounted agent authored
|
|
478
478
|
// `slackChannel({ cursorAccount: true })`. Inbound rides the account's
|
|
@@ -530,10 +530,40 @@ export function startServer(mounts_1) {
|
|
|
530
530
|
? {}
|
|
531
531
|
: { publicUrl: options.publicUrl })), (options.authToken === undefined
|
|
532
532
|
? {}
|
|
533
|
-
: { authToken: options.authToken })), { logger }));
|
|
533
|
+
: { authToken: options.authToken })), { cloudToolsBridge: options.cloudToolsUrl !== undefined, logger }));
|
|
534
534
|
if (resolved.length > 0) {
|
|
535
535
|
runtime.engine.setResolvedConnections(resolved);
|
|
536
536
|
}
|
|
537
|
+
const hasServerTools = runtime.project.agent.tools.some((tool) => tool.execution === "server");
|
|
538
|
+
// Host-bridged connections ride the same endpoint as server tools, so
|
|
539
|
+
// the cloud tools connection is set whenever either needs it.
|
|
540
|
+
const bridgeableNames = runtime.engine.cloudBridgeableConnectionNames();
|
|
541
|
+
const cloudCapable = runtime.project.agent.runtime === "cloud" ||
|
|
542
|
+
runtime.project.agent.cloud !== undefined;
|
|
543
|
+
if ((hasServerTools || bridgeableNames.length > 0) && cloudCapable) {
|
|
544
|
+
const basePath = runtime.slug === "" ? "" : `/${runtime.slug}`;
|
|
545
|
+
const publicToolsUrl = (_r = options.cloudToolsUrl) !== null && _r !== void 0 ? _r : (options.publicUrl === undefined
|
|
546
|
+
? undefined
|
|
547
|
+
: `${options.publicUrl.replace(/\/$/, "")}${basePath}${TOOL_MCP_ENDPOINT_PATH}`);
|
|
548
|
+
if (publicToolsUrl === undefined) {
|
|
549
|
+
if (hasServerTools) {
|
|
550
|
+
logger(`[agent-sdk] warning: agent "${runtime.project.name}" has server tools but no --public-url or --cloud-tools-url; cloud turns omit those tools.`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
const headers = options.cloudToolsUrl !== undefined
|
|
555
|
+
? accountKey === undefined
|
|
556
|
+
? undefined
|
|
557
|
+
: { authorization: `Bearer ${accountKey.apiKey}` }
|
|
558
|
+
: options.authToken === undefined
|
|
559
|
+
? undefined
|
|
560
|
+
: { authorization: `Bearer ${options.authToken}` };
|
|
561
|
+
if (options.cloudToolsUrl !== undefined && headers === undefined) {
|
|
562
|
+
throw new Error(`Agent "${runtime.project.name}" needs a Cursor API key to authenticate --cloud-tools-url. ${SIGN_IN_HINT}`);
|
|
563
|
+
}
|
|
564
|
+
runtime.engine.setCloudServerToolsConnection(Object.assign({ type: "http", url: publicToolsUrl }, (headers === undefined ? {} : { headers })));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
537
567
|
}
|
|
538
568
|
const agents = runtimes.map(({ slug, project }) => ({
|
|
539
569
|
slug,
|
|
@@ -727,7 +757,14 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
727
757
|
method: "GET",
|
|
728
758
|
pattern: `${base}/v1/health`,
|
|
729
759
|
auth: "none",
|
|
730
|
-
|
|
760
|
+
// Temporal consumes this response before promoting a newly deployed pod.
|
|
761
|
+
// Include the framework build there so deploy observability gets the
|
|
762
|
+
// version from the process that will serve turns, with no second request.
|
|
763
|
+
handler: () => jsonResponse({
|
|
764
|
+
ok: true,
|
|
765
|
+
name: project.name,
|
|
766
|
+
version: packageVersion(),
|
|
767
|
+
}),
|
|
731
768
|
});
|
|
732
769
|
// Bootstrap the SPA can't derive from its own URL (agent name, dev mode, and
|
|
733
770
|
// — in multi-agent mode — where the agents index lives).
|
|
@@ -840,6 +877,35 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
840
877
|
return jsonResponse({ artifacts: artifacts.slice(0, limit) });
|
|
841
878
|
}),
|
|
842
879
|
});
|
|
880
|
+
// File/blob payload of one artifact (`tag({ contents })`).
|
|
881
|
+
router.add({
|
|
882
|
+
method: "GET",
|
|
883
|
+
pattern: `${base}/v1/artifacts/:id/content`,
|
|
884
|
+
auth: httpAuth,
|
|
885
|
+
handler: (_request, ctx) => __awaiter(this, void 0, void 0, function* () {
|
|
886
|
+
var _a;
|
|
887
|
+
var _b, _c;
|
|
888
|
+
const includeAll = relaxSessionReadAuth &&
|
|
889
|
+
(relaxSessionReadAuthBeyondLoopback ||
|
|
890
|
+
(typeof ctx.requestIp === "string" &&
|
|
891
|
+
isLoopbackAddress(ctx.requestIp)));
|
|
892
|
+
const found = yield engine.getArtifactContent(ctx.auth, (_b = ctx.params.id) !== null && _b !== void 0 ? _b : "", { includeAll });
|
|
893
|
+
if (found === undefined) {
|
|
894
|
+
return errorResponse(404, "not_found", "No such artifact, or it carries no content.");
|
|
895
|
+
}
|
|
896
|
+
// A view over bytes is a valid fetch body; the DOM lib types are
|
|
897
|
+
// narrower than the runtime.
|
|
898
|
+
// contentType is author/model-controlled and the playground shares
|
|
899
|
+
// this origin: force download, never render or sniff.
|
|
900
|
+
return new Response(found.body, {
|
|
901
|
+
headers: {
|
|
902
|
+
"content-type": (_c = (_a = found.record.content) === null || _a === void 0 ? void 0 : _a.contentType) !== null && _c !== void 0 ? _c : "application/octet-stream",
|
|
903
|
+
"content-disposition": "attachment",
|
|
904
|
+
"x-content-type-options": "nosniff",
|
|
905
|
+
},
|
|
906
|
+
});
|
|
907
|
+
}),
|
|
908
|
+
});
|
|
843
909
|
// The agent's MCP surface: peers and external MCP clients delegate to
|
|
844
910
|
// this agent (ask / check / call_tool) over streamable HTTP. Stateless —
|
|
845
911
|
// POST only; GET/DELETE get a spec-compliant 405 from the endpoint.
|
|
@@ -852,6 +918,15 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
852
918
|
handler: (request, ctx) => mcpEndpoint.handle(request, ctx.auth),
|
|
853
919
|
});
|
|
854
920
|
}
|
|
921
|
+
const toolMcpEndpoint = createToolMcpEndpoint({ engine, logger });
|
|
922
|
+
for (const method of ["POST", "GET", "DELETE"]) {
|
|
923
|
+
router.add({
|
|
924
|
+
method,
|
|
925
|
+
pattern: `${base}${TOOL_MCP_ENDPOINT_PATH}`,
|
|
926
|
+
auth: defaultAuth,
|
|
927
|
+
handler: (request, ctx) => toolMcpEndpoint.handle(request, ctx.auth),
|
|
928
|
+
});
|
|
929
|
+
}
|
|
855
930
|
// Deterministic tool invocation: run an authored server tool directly,
|
|
856
931
|
// without a model turn deciding to call it.
|
|
857
932
|
router.add({
|