@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.
Files changed (186) hide show
  1. package/README.md +1 -1
  2. package/dist/artifacts.d.ts.map +1 -1
  3. package/dist/artifacts.js +0 -5
  4. package/dist/bin/agent-serve.d.ts +1 -0
  5. package/dist/bin/agent-serve.d.ts.map +1 -1
  6. package/dist/bin/agent-serve.js +32 -2
  7. package/dist/channels/github/types.d.ts +10 -7
  8. package/dist/channels/github/types.d.ts.map +1 -1
  9. package/dist/docs/404.html +2 -2
  10. package/dist/docs/ab.html +3 -3
  11. package/dist/docs/assets/{app.C2aVczmo.js → app.FPupl4SP.js} +1 -1
  12. package/dist/docs/assets/chunks/@localSearchIndexroot.WoYunhnT.js +1 -0
  13. package/dist/docs/assets/chunks/{VPLocalSearchBox.DLEzetbD.js → VPLocalSearchBox.Cd182Cu0.js} +1 -1
  14. package/dist/docs/assets/chunks/{theme.BkOH1oMp.js → theme.BEM3Okcd.js} +2 -2
  15. package/dist/docs/assets/{example-agents_weather-agent.md.Dmrcphhl.js → example-agents_weather-agent.md.BADkPqxQ.js} +6 -4
  16. package/dist/docs/assets/example-agents_weather-agent.md.BADkPqxQ.lean.js +1 -0
  17. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.js +9 -0
  18. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.lean.js +1 -0
  19. package/dist/docs/building-with-agents.html +3 -3
  20. package/dist/docs/concepts.html +3 -3
  21. package/dist/docs/deployment.html +3 -3
  22. package/dist/docs/evals.html +3 -3
  23. package/dist/docs/example-agents/approval-buddy.html +3 -3
  24. package/dist/docs/example-agents/benny.html +3 -3
  25. package/dist/docs/example-agents/bugbot.html +3 -3
  26. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  27. package/dist/docs/example-agents/codeowners-review.html +3 -3
  28. package/dist/docs/example-agents/concierge.html +3 -3
  29. package/dist/docs/example-agents/fsd.html +3 -3
  30. package/dist/docs/example-agents/index.html +3 -3
  31. package/dist/docs/example-agents/knowledge-base.html +3 -3
  32. package/dist/docs/example-agents/oncall.html +3 -3
  33. package/dist/docs/example-agents/security-reviewer.html +3 -3
  34. package/dist/docs/example-agents/slack-agent.html +3 -3
  35. package/dist/docs/example-agents/weather-agent.html +10 -8
  36. package/dist/docs/guides/agent-to-agent.html +3 -3
  37. package/dist/docs/guides/cloud-runtime.html +5 -5
  38. package/dist/docs/guides/github.html +3 -3
  39. package/dist/docs/guides/human-in-the-loop.html +3 -3
  40. package/dist/docs/guides/mcp-oauth.html +3 -3
  41. package/dist/docs/guides/slack.html +3 -3
  42. package/dist/docs/guides/webhooks.html +3 -3
  43. package/dist/docs/hashmap.json +1 -1
  44. package/dist/docs/hillclimbing.html +3 -3
  45. package/dist/docs/index.html +3 -3
  46. package/dist/docs/quickstart.html +3 -3
  47. package/dist/docs/reference/agent-config.html +3 -3
  48. package/dist/docs/reference/channels.html +3 -3
  49. package/dist/docs/reference/cli.html +3 -3
  50. package/dist/docs/reference/connections.html +3 -3
  51. package/dist/docs/reference/hooks.html +3 -3
  52. package/dist/docs/reference/http-api.html +3 -3
  53. package/dist/docs/reference/instructions.html +3 -3
  54. package/dist/docs/reference/playground.html +3 -3
  55. package/dist/docs/reference/project-layout.html +3 -3
  56. package/dist/docs/reference/prompt.html +3 -3
  57. package/dist/docs/reference/schedules.html +3 -3
  58. package/dist/docs/reference/sessions.html +3 -3
  59. package/dist/docs/reference/skills.html +3 -3
  60. package/dist/docs/reference/subagents.html +3 -3
  61. package/dist/docs/reference/tools.html +3 -3
  62. package/dist/docs/scaffolding-agents.html +3 -3
  63. package/dist/docs/storage.html +3 -3
  64. package/dist/docs/troubleshooting.html +3 -3
  65. package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -1
  66. package/dist/files-backends/agent-store-presigned-url.js +19 -810
  67. package/dist/files.d.ts +20 -0
  68. package/dist/files.d.ts.map +1 -1
  69. package/dist/files.js +20 -0
  70. package/dist/index.d.ts +2 -2
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +2 -2
  73. package/dist/internal/artifacts-store.d.ts +14 -6
  74. package/dist/internal/artifacts-store.d.ts.map +1 -1
  75. package/dist/internal/artifacts-store.js +160 -16
  76. package/dist/internal/cli-convert-automation.d.ts +39 -0
  77. package/dist/internal/cli-convert-automation.d.ts.map +1 -0
  78. package/dist/internal/cli-convert-automation.js +280 -0
  79. package/dist/internal/cli-deploy.d.ts +2 -0
  80. package/dist/internal/cli-deploy.d.ts.map +1 -1
  81. package/dist/internal/cli-deploy.js +1 -1
  82. package/dist/internal/cli-mcp-oauth.d.ts +23 -0
  83. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  84. package/dist/internal/cli-mcp-oauth.js +57 -33
  85. package/dist/internal/convert-automation/convert-workflow.d.ts +10 -0
  86. package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -0
  87. package/dist/internal/convert-automation/convert-workflow.js +998 -0
  88. package/dist/internal/convert-automation/index.d.ts +3 -0
  89. package/dist/internal/convert-automation/index.d.ts.map +1 -0
  90. package/dist/internal/convert-automation/index.js +1 -0
  91. package/dist/internal/convert-automation/slug.d.ts +11 -0
  92. package/dist/internal/convert-automation/slug.d.ts.map +1 -0
  93. package/dist/internal/convert-automation/slug.js +36 -0
  94. package/dist/internal/convert-automation/types.d.ts +191 -0
  95. package/dist/internal/convert-automation/types.d.ts.map +1 -0
  96. package/dist/internal/convert-automation/types.js +13 -0
  97. package/dist/internal/cursor-relay-core.d.ts +12 -0
  98. package/dist/internal/cursor-relay-core.d.ts.map +1 -1
  99. package/dist/internal/cursor-relay-core.js +42 -8
  100. package/dist/internal/deploy-client.d.ts +31 -0
  101. package/dist/internal/deploy-client.d.ts.map +1 -1
  102. package/dist/internal/deploy-client.js +48 -0
  103. package/dist/internal/discovery.d.ts.map +1 -1
  104. package/dist/internal/discovery.js +3 -32
  105. package/dist/internal/init-project.d.ts +1 -0
  106. package/dist/internal/init-project.d.ts.map +1 -1
  107. package/dist/internal/init-project.js +1 -1
  108. package/dist/internal/mcp-endpoint.d.ts +6 -0
  109. package/dist/internal/mcp-endpoint.d.ts.map +1 -1
  110. package/dist/internal/mcp-endpoint.js +168 -0
  111. package/dist/internal/resolved-connections.d.ts +15 -0
  112. package/dist/internal/resolved-connections.d.ts.map +1 -1
  113. package/dist/internal/resolved-connections.js +12 -5
  114. package/dist/internal/review-comments.d.ts +9 -1
  115. package/dist/internal/review-comments.d.ts.map +1 -1
  116. package/dist/internal/review-comments.js +76 -0
  117. package/dist/internal/server.d.ts.map +1 -1
  118. package/dist/internal/server.js +83 -8
  119. package/dist/internal/session-engine.d.ts +56 -3
  120. package/dist/internal/session-engine.d.ts.map +1 -1
  121. package/dist/internal/session-engine.js +252 -83
  122. package/dist/internal/storage-coordinator.d.ts +0 -15
  123. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  124. package/dist/internal/storage-coordinator.js +0 -52
  125. package/dist/internal/workspace.d.ts +10 -5
  126. package/dist/internal/workspace.d.ts.map +1 -1
  127. package/dist/internal/workspace.js +13 -0
  128. package/dist/memory.d.ts +22 -6
  129. package/dist/memory.d.ts.map +1 -1
  130. package/dist/memory.js +100 -8
  131. package/dist/playground/assets/index-CDDWw0YX.js +85 -0
  132. package/dist/playground/assets/index-MVuNTd8v.css +1 -0
  133. package/dist/playground/index.html +2 -2
  134. package/dist/storage.d.ts +0 -4
  135. package/dist/storage.d.ts.map +1 -1
  136. package/dist/storage.js +0 -4
  137. package/dist/types.d.ts +18 -0
  138. package/dist/types.d.ts.map +1 -1
  139. package/docs/example-agents/weather-agent.md +29 -11
  140. package/docs/guides/cloud-runtime.md +6 -4
  141. package/package.json +3 -22
  142. package/src/artifacts.ts +0 -6
  143. package/src/bin/agent-serve.ts +36 -2
  144. package/src/channels/github/types.ts +10 -7
  145. package/src/files-backends/agent-store-presigned-url.ts +7 -5
  146. package/src/files.ts +27 -0
  147. package/src/index.ts +6 -1
  148. package/src/internal/artifacts-store.ts +185 -22
  149. package/src/internal/cli-convert-automation.ts +352 -0
  150. package/src/internal/cli-deploy.ts +1 -1
  151. package/src/internal/cli-mcp-oauth.ts +69 -31
  152. package/src/internal/convert-automation/convert-workflow.ts +1422 -0
  153. package/src/internal/convert-automation/index.ts +10 -0
  154. package/src/internal/convert-automation/slug.ts +38 -0
  155. package/src/internal/convert-automation/types.ts +199 -0
  156. package/src/internal/cursor-relay-core.ts +62 -3
  157. package/src/internal/deploy-client.ts +78 -0
  158. package/src/internal/discovery.ts +3 -37
  159. package/src/internal/init-project.ts +1 -1
  160. package/src/internal/mcp-endpoint.ts +243 -0
  161. package/src/internal/resolved-connections.ts +32 -6
  162. package/src/internal/review-comments.ts +102 -2
  163. package/src/internal/server.ts +108 -2
  164. package/src/internal/session-engine.ts +329 -99
  165. package/src/internal/storage-coordinator.ts +0 -62
  166. package/src/internal/workspace.ts +19 -5
  167. package/src/memory.ts +126 -10
  168. package/src/storage.ts +0 -6
  169. package/src/types.ts +15 -0
  170. package/dist/channels/slack/post-update-delivery.d.ts +0 -85
  171. package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
  172. package/dist/docs/assets/chunks/@localSearchIndexroot.xgMnlUSO.js +0 -1
  173. package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +0 -1
  174. package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +0 -9
  175. package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.lean.js +0 -1
  176. package/dist/internal/json-dir-store.d.ts +0 -32
  177. package/dist/internal/json-dir-store.d.ts.map +0 -1
  178. package/dist/internal/persistence-coordinator.d.ts +0 -127
  179. package/dist/internal/persistence-coordinator.d.ts.map +0 -1
  180. package/dist/multi-tenant.d.ts +0 -80
  181. package/dist/multi-tenant.d.ts.map +0 -1
  182. package/dist/multi-tenant.js +0 -69
  183. package/dist/persistence.d.ts +0 -184
  184. package/dist/persistence.d.ts.map +0 -1
  185. package/dist/playground/assets/index-50PKeJlG.css +0 -1
  186. package/dist/playground/assets/index-C0f2Wl1q.js +0 -85
@@ -151,7 +151,7 @@ export default memoryHook();
151
151
  };
152
152
  });
153
153
  }
154
- function isEexist(error) {
154
+ export function isEexist(error) {
155
155
  return (error !== null &&
156
156
  typeof error === "object" &&
157
157
  "code" in error &&
@@ -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;AAGH,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAC;AAEzH,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;AAU3C,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"}
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;CACpB,GAAG,IAAI,CA4BP;AAED,qEAAqE;AACrE,wBAAgB,wCAAwC,CAAC,IAAI,EAAE;IAC7D,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IAC3B,mBAAmB,EAAE,SAAS,wBAAwB,EAAE,CAAC;CAC1D,GAAG,IAAI,CAmBP;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,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,GAAG,wBAAwB,EAAE,CA8D7B"}
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 || args.publicUrl !== undefined) {
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(`[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.`);
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(`[agent-sdk] agent "${label}": cloud-runtime turns omit the account bridge without --public-url (cloud agents fall back to the account's native connectors).`);
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
- export type ReviewCommentPublisher = "local_gh";
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":"AAEA,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAEhD,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"}
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;AA8FrB,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,CAsrB3B"}
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"}
@@ -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 _r;
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 = (_r = process.env).CURSOR_AGENTKIT_VERSION) !== null && _j !== void 0 ? _j : (_r.CURSOR_AGENTKIT_VERSION = packageVersion());
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
- handler: () => jsonResponse({ ok: true, name: project.name }),
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({