@agimon-ai/po-mcp 0.0.0-alpha.21 → 0.0.0-alpha.23

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 (37) hide show
  1. package/README.md +10 -1
  2. package/dist/apiContracts.cjs +53 -0
  3. package/dist/apiContracts.cjs.map +1 -1
  4. package/dist/apiContracts.d.mts.map +1 -1
  5. package/dist/apiContracts.mjs +53 -0
  6. package/dist/apiContracts.mjs.map +1 -1
  7. package/dist/extensions/mcp.cjs +23 -7
  8. package/dist/extensions/mcp.cjs.map +1 -1
  9. package/dist/extensions/mcp.mjs +23 -7
  10. package/dist/extensions/mcp.mjs.map +1 -1
  11. package/dist/extensions/server.cjs +327 -23
  12. package/dist/extensions/server.cjs.map +1 -1
  13. package/dist/extensions/server.mjs +330 -26
  14. package/dist/extensions/server.mjs.map +1 -1
  15. package/dist/extensions/web.mjs +500 -40
  16. package/dist/extensions/web.mjs.map +1 -1
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.mjs +1 -1
  19. package/dist/{mcpCatalog-CzC1OFde.mjs → mcpCatalog-Bn8S3HZw.mjs} +2 -2
  20. package/dist/mcpCatalog-Bn8S3HZw.mjs.map +1 -0
  21. package/dist/{mcpCatalog-BYxR2wMm.cjs → mcpCatalog-CzHD8N6V.cjs} +7 -1
  22. package/dist/mcpCatalog-CzHD8N6V.cjs.map +1 -0
  23. package/dist/projection-Bj7Soute.cjs +64 -0
  24. package/dist/projection-Bj7Soute.cjs.map +1 -0
  25. package/dist/projection-ouVnOTJm.mjs +56 -0
  26. package/dist/projection-ouVnOTJm.mjs.map +1 -0
  27. package/dist/projection.cjs +1 -1
  28. package/dist/projection.d.mts +7 -1
  29. package/dist/projection.d.mts.map +1 -1
  30. package/dist/projection.mjs +1 -1
  31. package/package.json +8 -7
  32. package/dist/mcpCatalog-BYxR2wMm.cjs.map +0 -1
  33. package/dist/mcpCatalog-CzC1OFde.mjs.map +0 -1
  34. package/dist/projection-gyAA2jRB.mjs +0 -43
  35. package/dist/projection-gyAA2jRB.mjs.map +0 -1
  36. package/dist/projection-w3XxXmVi.cjs +0 -51
  37. package/dist/projection-w3XxXmVi.cjs.map +0 -1
package/README.md CHANGED
@@ -39,6 +39,15 @@ Repository `.mcp.json` entries describe direct MCP servers:
39
39
  }
40
40
  ```
41
41
 
42
+ Your own servers live in `mcp.json` in your Po home (`~/.po/mcp.json`, or under `PO_HOME`), in the
43
+ same shape. Po loads them into every repository's sessions, first, so a repository, plugin or
44
+ domain entry with the same name wins.
45
+
46
+ Add a server from the cockpit without editing either file: **Add server** on a repository's MCP
47
+ servers page writes that repository's `.mcp.json`, and **Settings, MCP servers** writes your own
48
+ config. Remote servers take a URL and optional headers. A local command also needs the trust
49
+ confirmation, which the hub checks again. Adding never replaces an existing name or rewrites a
50
+ file that is not valid JSON.
42
51
  Selected legacy plugins may also provide root `.mcp.json`. A schema-gated Agent Plugin v1 instead
43
52
  provides root `mcp.json`. Po validates its portable contract, supplies private persistent
44
53
  `PLUGIN_DATA`, and resolves plugin-relative stdio commands and working directories. It also
@@ -106,7 +115,7 @@ Reopening a widget reads its retained result and state, never reruns the origina
106
115
  built on the ChatGPT SDK work too. Only ChatGPT widgets receive `toolOutput` globals updates
107
116
  after their own `callTool`. Each App root gets a `light`/`dark` class, `data-theme` and
108
117
  `color-scheme` (an App's own class or `data-theme` is kept), and theme changes sync live.
109
- A tool result that rendered an App stays behind the card toggle unless the call failed.
118
+ An MCP tool card starts collapsed; an App stays visible. Expanding the card shows the call's input, then its result.
110
119
 
111
120
  The ChatGPT adapter implements tool input/output and private metadata globals, globals
112
121
  updates, `callTool`, `setWidgetState`, `sendFollowUpMessage`, inline display mode, height,
@@ -74,6 +74,31 @@ const McpSessionToolSchema = typebox.Type.Object({
74
74
  inputSchema: typebox.Type.Record(S, typebox.Type.Unknown()),
75
75
  tokens: N
76
76
  });
77
+ const StringPairs = typebox.Type.Record(S, S);
78
+ const McpServerEntrySchema = typebox.Type.Union([typebox.Type.Object({
79
+ type: typebox.Type.Literal("http"),
80
+ url: typebox.Type.String({ maxLength: 2048 }),
81
+ headers: O(StringPairs)
82
+ }), typebox.Type.Object({
83
+ command: typebox.Type.String({
84
+ minLength: 1,
85
+ maxLength: 1024
86
+ }),
87
+ args: typebox.Type.Array(S),
88
+ env: O(StringPairs)
89
+ })]);
90
+ const McpAddServerSchema = typebox.Type.Object({
91
+ scope: literals(["repository", "global"]),
92
+ repositoryId: O(RepositoryId),
93
+ name: typebox.Type.String({ pattern: "^[A-Za-z0-9_-]{1,64}$" }),
94
+ entry: McpServerEntrySchema,
95
+ trusted: O(B)
96
+ });
97
+ const McpGlobalServersSchema = typebox.Type.Object({ servers: typebox.Type.Array(typebox.Type.Object({
98
+ name: S,
99
+ kind: literals(["remote", "local"]),
100
+ target: S
101
+ })) });
77
102
  const SessionToolQuery = [{
78
103
  name: "server",
79
104
  in: "query",
@@ -153,6 +178,34 @@ const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
153
178
  },
154
179
  responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpAuthorizationSchema, 202)
155
180
  },
181
+ {
182
+ id: "mcp.server.add",
183
+ scope,
184
+ basePath: "mcp",
185
+ path: "/servers",
186
+ method: "POST",
187
+ authentication: "owner",
188
+ description: "Add one MCP server to the repository's .mcp.json or the person's own config.",
189
+ body: {
190
+ required: true,
191
+ contentType: "application/json",
192
+ schema: McpAddServerSchema
193
+ },
194
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(typebox.Type.Object({
195
+ scope: literals(["repository", "global"]),
196
+ name: S
197
+ }), 201)
198
+ },
199
+ {
200
+ id: "mcp.servers.global",
201
+ scope,
202
+ basePath: "mcp",
203
+ path: "/servers/global",
204
+ method: "GET",
205
+ authentication: "owner",
206
+ description: "List the servers in the person's own MCP config, without headers or environment.",
207
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpGlobalServersSchema)
208
+ },
156
209
  ...["GET", "DELETE"].map((method) => ({
157
210
  id: `mcp.authorization.${method}`,
158
211
  scope,
@@ -1 +1 @@
1
- {"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses","Type","definePoPluginMethod"],"sources":["../src/schemas/apiContracts.ts","../src/schemas/mcpApps.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst RepositoryId = Type.String({\n pattern: '^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$',\n});\nconst RepositoryQuery = [{ name: 'repositoryId', in: 'query' as const, required: true, schema: RepositoryId }];\nexport const McpCatalogSchema = Type.Object({\n repositoryId: S,\n sync: Type.Object({ fresh: B, reasons: Type.Array(S) }),\n servers: Type.Array(\n Type.Object({\n name: S,\n state: literals(['not-connected', 'connecting', 'connected', 'degraded', 'needs-auth', 'failed', 'closed']),\n source: literals(['cached', 'live', 'configured']),\n credentialPresent: B,\n tools: Type.Array(Type.Object({ name: S, piName: S, description: O(S) })),\n error: O(S),\n }),\n ),\n droppedServers: Type.Array(S),\n diagnostics: Type.Array(S),\n});\nexport const McpAuthorizationSchema = Type.Object({\n id: S,\n repositoryId: S,\n serverName: S,\n status: literals(['starting', 'waiting', 'completed', 'failed', 'cancelled', 'expired']),\n authorizationUrl: O(S),\n error: O(S),\n expiresAt: N,\n});\nexport const McpSessionToolSchema = Type.Object({\n server: S,\n tool: S,\n description: O(S),\n inputSchema: Type.Record(S, Type.Unknown()),\n tokens: N,\n});\nconst SessionToolQuery = [\n { name: 'server', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 160 }) },\n { name: 'tool', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 256 }) },\n];\ntype HttpContract = Parameters<typeof defineApiContract>[0]['http'][number];\nexport const apiContracts = defineApiContract({\n version: 1,\n sockets: [],\n dynamic: [],\n http: [\n {\n id: 'mcp.session.tool',\n scope: 'session',\n basePath: 'mcp-session',\n path: '/tool',\n method: 'GET',\n authentication: 'owner',\n description: 'Read one tool the session reaches through mcp_use: its description, schema, and token cost.',\n parameters: SessionToolQuery,\n responses: jsonApiResponses(McpSessionToolSchema),\n },\n ...(['global', 'workspace'] as const).flatMap((scope): HttpContract[] => [\n {\n id: 'mcp.catalog',\n scope,\n basePath: 'mcp',\n path: '/repository',\n method: 'GET',\n authentication: 'owner',\n description: 'Read the synced MCP repository catalog.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.discover',\n scope,\n basePath: 'mcp',\n path: '/repository/discover',\n method: 'POST',\n authentication: 'owner',\n description: 'Discover repository MCP servers.',\n body: { required: true, contentType: 'application/json', schema: Type.Object({ repositoryId: RepositoryId }) },\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.authorize',\n scope,\n basePath: 'mcp',\n path: '/repository/authorize',\n method: 'POST',\n authentication: 'owner',\n description: 'Start MCP authorization.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n repositoryId: RepositoryId,\n serverName: Type.String({ minLength: 1, maxLength: 160 }),\n }),\n },\n responses: jsonApiResponses(McpAuthorizationSchema, 202),\n },\n ...(['GET', 'DELETE'] as const).map((method) => ({\n id: `mcp.authorization.${method}`,\n scope,\n basePath: 'mcp',\n path: '/repository/authorize/{flowId}',\n method,\n authentication: 'owner' as const,\n description: method === 'GET' ? 'Read an authorization flow.' : 'Cancel an authorization flow.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpAuthorizationSchema),\n })),\n ]),\n ],\n});\nexport default apiContracts;\n","import { definePoPluginMethod } from '@agimon-ai/po-core/pluginProtocol';\nimport { Type } from 'typebox';\n\nexport type { McpAppOpenResult } from '../types/webMcp';\n\nconst Lease = Type.String({ minLength: 1, maxLength: 128 });\nconst JsonObject = Type.Record(Type.String(), Type.Unknown());\nconst Empty = Type.Object({}, { additionalProperties: false });\nconst Result = Type.Object({\n content: Type.Array(Type.Unknown()),\n structuredContent: Type.Optional(Type.Unknown()),\n _meta: Type.Optional(JsonObject),\n isError: Type.Optional(Type.Boolean()),\n});\nconst Address = { service: 'mcp.apps', scope: 'session', direction: 'client-to-server' } as const;\n\nexport const mcpAppOpenMethod = definePoPluginMethod({\n ...Address,\n method: 'open',\n input: Type.Object({ toolCallId: Type.String({ minLength: 1, maxLength: 512 }) }, { additionalProperties: false }),\n output: Type.Object({\n leaseId: Lease,\n html: Type.String(),\n resourceUri: Type.String(),\n protocol: Type.Union([Type.Literal('mcp'), Type.Literal('openai')]),\n resourceMeta: JsonObject,\n tool: Type.Object({\n name: Type.String(),\n description: Type.String(),\n inputSchema: Type.Object({ type: Type.Literal('object') }, { additionalProperties: true }),\n _meta: JsonObject,\n }),\n args: JsonObject,\n result: Result,\n state: Type.Unknown(),\n readOnly: Type.Boolean(),\n }),\n});\n\nexport const mcpAppActivateMethod = definePoPluginMethod({\n ...Address,\n method: 'activate',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Type.Object({ readOnly: Type.Literal(false) }),\n});\nexport const mcpAppCallToolMethod = definePoPluginMethod({\n ...Address,\n method: 'callTool',\n input: Type.Object(\n { leaseId: Lease, name: Type.String({ minLength: 1, maxLength: 256 }), arguments: JsonObject },\n { additionalProperties: false },\n ),\n output: Result,\n});\nexport const mcpAppSetStateMethod = definePoPluginMethod({\n ...Address,\n method: 'setState',\n input: Type.Object({ leaseId: Lease, state: Type.Unknown() }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppFollowUpMethod = definePoPluginMethod({\n ...Address,\n method: 'followUp',\n input: Type.Object(\n { leaseId: Lease, prompt: Type.String({ minLength: 1, maxLength: 16000 }) },\n { additionalProperties: false },\n ),\n output: Empty,\n});\nexport const mcpAppCloseMethod = definePoPluginMethod({\n ...Address,\n method: 'close',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppMethods = [\n mcpAppOpenMethod,\n mcpAppActivateMethod,\n mcpAppCallToolMethod,\n mcpAppSetStateMethod,\n mcpAppFollowUpMethod,\n mcpAppCloseMethod,\n] as const;\n"],"mappings":"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"}
1
+ {"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses","Type","definePoPluginMethod"],"sources":["../src/schemas/apiContracts.ts","../src/schemas/mcpApps.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst RepositoryId = Type.String({\n pattern: '^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$',\n});\nconst RepositoryQuery = [{ name: 'repositoryId', in: 'query' as const, required: true, schema: RepositoryId }];\nexport const McpCatalogSchema = Type.Object({\n repositoryId: S,\n sync: Type.Object({ fresh: B, reasons: Type.Array(S) }),\n servers: Type.Array(\n Type.Object({\n name: S,\n state: literals(['not-connected', 'connecting', 'connected', 'degraded', 'needs-auth', 'failed', 'closed']),\n source: literals(['cached', 'live', 'configured']),\n credentialPresent: B,\n tools: Type.Array(Type.Object({ name: S, piName: S, description: O(S) })),\n error: O(S),\n }),\n ),\n droppedServers: Type.Array(S),\n diagnostics: Type.Array(S),\n});\nexport const McpAuthorizationSchema = Type.Object({\n id: S,\n repositoryId: S,\n serverName: S,\n status: literals(['starting', 'waiting', 'completed', 'failed', 'cancelled', 'expired']),\n authorizationUrl: O(S),\n error: O(S),\n expiresAt: N,\n});\nexport const McpSessionToolSchema = Type.Object({\n server: S,\n tool: S,\n description: O(S),\n inputSchema: Type.Record(S, Type.Unknown()),\n tokens: N,\n});\nconst StringPairs = Type.Record(S, S);\nexport const McpServerEntrySchema = Type.Union([\n Type.Object({ type: Type.Literal('http'), url: Type.String({ maxLength: 2048 }), headers: O(StringPairs) }),\n Type.Object({ command: Type.String({ minLength: 1, maxLength: 1024 }), args: Type.Array(S), env: O(StringPairs) }),\n]);\nexport const McpAddServerSchema = Type.Object({\n scope: literals(['repository', 'global']),\n repositoryId: O(RepositoryId),\n name: Type.String({ pattern: '^[A-Za-z0-9_-]{1,64}$' }),\n entry: McpServerEntrySchema,\n trusted: O(B),\n});\nexport const McpGlobalServersSchema = Type.Object({\n servers: Type.Array(Type.Object({ name: S, kind: literals(['remote', 'local']), target: S })),\n});\nconst SessionToolQuery = [\n { name: 'server', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 160 }) },\n { name: 'tool', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 256 }) },\n];\ntype HttpContract = Parameters<typeof defineApiContract>[0]['http'][number];\nexport const apiContracts = defineApiContract({\n version: 1,\n sockets: [],\n dynamic: [],\n http: [\n {\n id: 'mcp.session.tool',\n scope: 'session',\n basePath: 'mcp-session',\n path: '/tool',\n method: 'GET',\n authentication: 'owner',\n description: 'Read one tool the session reaches through mcp_use: its description, schema, and token cost.',\n parameters: SessionToolQuery,\n responses: jsonApiResponses(McpSessionToolSchema),\n },\n ...(['global', 'workspace'] as const).flatMap((scope): HttpContract[] => [\n {\n id: 'mcp.catalog',\n scope,\n basePath: 'mcp',\n path: '/repository',\n method: 'GET',\n authentication: 'owner',\n description: 'Read the synced MCP repository catalog.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.discover',\n scope,\n basePath: 'mcp',\n path: '/repository/discover',\n method: 'POST',\n authentication: 'owner',\n description: 'Discover repository MCP servers.',\n body: { required: true, contentType: 'application/json', schema: Type.Object({ repositoryId: RepositoryId }) },\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.authorize',\n scope,\n basePath: 'mcp',\n path: '/repository/authorize',\n method: 'POST',\n authentication: 'owner',\n description: 'Start MCP authorization.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n repositoryId: RepositoryId,\n serverName: Type.String({ minLength: 1, maxLength: 160 }),\n }),\n },\n responses: jsonApiResponses(McpAuthorizationSchema, 202),\n },\n {\n id: 'mcp.server.add',\n scope,\n basePath: 'mcp',\n path: '/servers',\n method: 'POST',\n authentication: 'owner',\n description: \"Add one MCP server to the repository's .mcp.json or the person's own config.\",\n body: { required: true, contentType: 'application/json', schema: McpAddServerSchema },\n responses: jsonApiResponses(Type.Object({ scope: literals(['repository', 'global']), name: S }), 201),\n },\n {\n id: 'mcp.servers.global',\n scope,\n basePath: 'mcp',\n path: '/servers/global',\n method: 'GET',\n authentication: 'owner',\n description: \"List the servers in the person's own MCP config, without headers or environment.\",\n responses: jsonApiResponses(McpGlobalServersSchema),\n },\n ...(['GET', 'DELETE'] as const).map((method) => ({\n id: `mcp.authorization.${method}`,\n scope,\n basePath: 'mcp',\n path: '/repository/authorize/{flowId}',\n method,\n authentication: 'owner' as const,\n description: method === 'GET' ? 'Read an authorization flow.' : 'Cancel an authorization flow.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpAuthorizationSchema),\n })),\n ]),\n ],\n});\nexport default apiContracts;\n","import { definePoPluginMethod } from '@agimon-ai/po-core/pluginProtocol';\nimport { Type } from 'typebox';\n\nexport type { McpAppOpenResult } from '../types/webMcp';\n\nconst Lease = Type.String({ minLength: 1, maxLength: 128 });\nconst JsonObject = Type.Record(Type.String(), Type.Unknown());\nconst Empty = Type.Object({}, { additionalProperties: false });\nconst Result = Type.Object({\n content: Type.Array(Type.Unknown()),\n structuredContent: Type.Optional(Type.Unknown()),\n _meta: Type.Optional(JsonObject),\n isError: Type.Optional(Type.Boolean()),\n});\nconst Address = { service: 'mcp.apps', scope: 'session', direction: 'client-to-server' } as const;\n\nexport const mcpAppOpenMethod = definePoPluginMethod({\n ...Address,\n method: 'open',\n input: Type.Object({ toolCallId: Type.String({ minLength: 1, maxLength: 512 }) }, { additionalProperties: false }),\n output: Type.Object({\n leaseId: Lease,\n html: Type.String(),\n resourceUri: Type.String(),\n protocol: Type.Union([Type.Literal('mcp'), Type.Literal('openai')]),\n resourceMeta: JsonObject,\n tool: Type.Object({\n name: Type.String(),\n description: Type.String(),\n inputSchema: Type.Object({ type: Type.Literal('object') }, { additionalProperties: true }),\n _meta: JsonObject,\n }),\n args: JsonObject,\n result: Result,\n state: Type.Unknown(),\n readOnly: Type.Boolean(),\n }),\n});\n\nexport const mcpAppActivateMethod = definePoPluginMethod({\n ...Address,\n method: 'activate',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Type.Object({ readOnly: Type.Literal(false) }),\n});\nexport const mcpAppCallToolMethod = definePoPluginMethod({\n ...Address,\n method: 'callTool',\n input: Type.Object(\n { leaseId: Lease, name: Type.String({ minLength: 1, maxLength: 256 }), arguments: JsonObject },\n { additionalProperties: false },\n ),\n output: Result,\n});\nexport const mcpAppSetStateMethod = definePoPluginMethod({\n ...Address,\n method: 'setState',\n input: Type.Object({ leaseId: Lease, state: Type.Unknown() }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppFollowUpMethod = definePoPluginMethod({\n ...Address,\n method: 'followUp',\n input: Type.Object(\n { leaseId: Lease, prompt: Type.String({ minLength: 1, maxLength: 16000 }) },\n { additionalProperties: false },\n ),\n output: Empty,\n});\nexport const mcpAppCloseMethod = definePoPluginMethod({\n ...Address,\n method: 'close',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppMethods = [\n mcpAppOpenMethod,\n mcpAppActivateMethod,\n mcpAppCallToolMethod,\n mcpAppSetStateMethod,\n mcpAppFollowUpMethod,\n mcpAppCloseMethod,\n] as const;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts","../src/types/webMcp.ts","../src/schemas/mcpApps.ts"],"mappings":";;;;qBAiDa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UCvCI;EACf;EACA;EACA;EACA;EACA,cAAc;EACd;IACE;IACA;IACA;MAAe;OAAiB;;IAChC,OAAO;;EAET,MAAM;EACN;IAAU;IAAoB;IAA6B,QAAQ;IAAyB;;EAC5F;EACA;;;;qBCTW,8DAAgB,eAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;qBAuBhB,kEAAoB,eAAA,KAAA;;;;;qBAMpB,kEAAoB,eAAA,KAAA;;;;;;;;;;qBASpB,kEAAoB,eAAA,KAAA;;;IAK/B,KAAA;qBACW,kEAAoB,eAAA,KAAA;;;IAQ/B,KAAA;qBACW,+DAAiB,eAAA,KAAA;;IAK5B,KAAA"}
1
+ {"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts","../src/types/webMcp.ts","../src/schemas/mcpApps.ts"],"mappings":";;;;qBAgEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UCtDI;EACf;EACA;EACA;EACA;EACA,cAAc;EACd;IACE;IACA;IACA;MAAe;OAAiB;;IAChC,OAAO;;EAET,MAAM;EACN;IAAU;IAAoB;IAA6B,QAAQ;IAAyB;;EAC5F;EACA;;;;qBCTW,8DAAgB,eAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;qBAuBhB,kEAAoB,eAAA,KAAA;;;;;qBAMpB,kEAAoB,eAAA,KAAA;;;;;;;;;;qBASpB,kEAAoB,eAAA,KAAA;;;IAK/B,KAAA;qBACW,kEAAoB,eAAA,KAAA;;;IAQ/B,KAAA;qBACW,+DAAiB,eAAA,KAAA;;IAK5B,KAAA"}
@@ -70,6 +70,31 @@ const McpSessionToolSchema = Type.Object({
70
70
  inputSchema: Type.Record(S, Type.Unknown()),
71
71
  tokens: N
72
72
  });
73
+ const StringPairs = Type.Record(S, S);
74
+ const McpServerEntrySchema = Type.Union([Type.Object({
75
+ type: Type.Literal("http"),
76
+ url: Type.String({ maxLength: 2048 }),
77
+ headers: O(StringPairs)
78
+ }), Type.Object({
79
+ command: Type.String({
80
+ minLength: 1,
81
+ maxLength: 1024
82
+ }),
83
+ args: Type.Array(S),
84
+ env: O(StringPairs)
85
+ })]);
86
+ const McpAddServerSchema = Type.Object({
87
+ scope: literals(["repository", "global"]),
88
+ repositoryId: O(RepositoryId),
89
+ name: Type.String({ pattern: "^[A-Za-z0-9_-]{1,64}$" }),
90
+ entry: McpServerEntrySchema,
91
+ trusted: O(B)
92
+ });
93
+ const McpGlobalServersSchema = Type.Object({ servers: Type.Array(Type.Object({
94
+ name: S,
95
+ kind: literals(["remote", "local"]),
96
+ target: S
97
+ })) });
73
98
  const SessionToolQuery = [{
74
99
  name: "server",
75
100
  in: "query",
@@ -149,6 +174,34 @@ const apiContracts = defineApiContract({
149
174
  },
150
175
  responses: jsonApiResponses(McpAuthorizationSchema, 202)
151
176
  },
177
+ {
178
+ id: "mcp.server.add",
179
+ scope,
180
+ basePath: "mcp",
181
+ path: "/servers",
182
+ method: "POST",
183
+ authentication: "owner",
184
+ description: "Add one MCP server to the repository's .mcp.json or the person's own config.",
185
+ body: {
186
+ required: true,
187
+ contentType: "application/json",
188
+ schema: McpAddServerSchema
189
+ },
190
+ responses: jsonApiResponses(Type.Object({
191
+ scope: literals(["repository", "global"]),
192
+ name: S
193
+ }), 201)
194
+ },
195
+ {
196
+ id: "mcp.servers.global",
197
+ scope,
198
+ basePath: "mcp",
199
+ path: "/servers/global",
200
+ method: "GET",
201
+ authentication: "owner",
202
+ description: "List the servers in the person's own MCP config, without headers or environment.",
203
+ responses: jsonApiResponses(McpGlobalServersSchema)
204
+ },
152
205
  ...["GET", "DELETE"].map((method) => ({
153
206
  id: `mcp.authorization.${method}`,
154
207
  scope,
@@ -1 +1 @@
1
- {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts","../src/schemas/mcpApps.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst RepositoryId = Type.String({\n pattern: '^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$',\n});\nconst RepositoryQuery = [{ name: 'repositoryId', in: 'query' as const, required: true, schema: RepositoryId }];\nexport const McpCatalogSchema = Type.Object({\n repositoryId: S,\n sync: Type.Object({ fresh: B, reasons: Type.Array(S) }),\n servers: Type.Array(\n Type.Object({\n name: S,\n state: literals(['not-connected', 'connecting', 'connected', 'degraded', 'needs-auth', 'failed', 'closed']),\n source: literals(['cached', 'live', 'configured']),\n credentialPresent: B,\n tools: Type.Array(Type.Object({ name: S, piName: S, description: O(S) })),\n error: O(S),\n }),\n ),\n droppedServers: Type.Array(S),\n diagnostics: Type.Array(S),\n});\nexport const McpAuthorizationSchema = Type.Object({\n id: S,\n repositoryId: S,\n serverName: S,\n status: literals(['starting', 'waiting', 'completed', 'failed', 'cancelled', 'expired']),\n authorizationUrl: O(S),\n error: O(S),\n expiresAt: N,\n});\nexport const McpSessionToolSchema = Type.Object({\n server: S,\n tool: S,\n description: O(S),\n inputSchema: Type.Record(S, Type.Unknown()),\n tokens: N,\n});\nconst SessionToolQuery = [\n { name: 'server', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 160 }) },\n { name: 'tool', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 256 }) },\n];\ntype HttpContract = Parameters<typeof defineApiContract>[0]['http'][number];\nexport const apiContracts = defineApiContract({\n version: 1,\n sockets: [],\n dynamic: [],\n http: [\n {\n id: 'mcp.session.tool',\n scope: 'session',\n basePath: 'mcp-session',\n path: '/tool',\n method: 'GET',\n authentication: 'owner',\n description: 'Read one tool the session reaches through mcp_use: its description, schema, and token cost.',\n parameters: SessionToolQuery,\n responses: jsonApiResponses(McpSessionToolSchema),\n },\n ...(['global', 'workspace'] as const).flatMap((scope): HttpContract[] => [\n {\n id: 'mcp.catalog',\n scope,\n basePath: 'mcp',\n path: '/repository',\n method: 'GET',\n authentication: 'owner',\n description: 'Read the synced MCP repository catalog.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.discover',\n scope,\n basePath: 'mcp',\n path: '/repository/discover',\n method: 'POST',\n authentication: 'owner',\n description: 'Discover repository MCP servers.',\n body: { required: true, contentType: 'application/json', schema: Type.Object({ repositoryId: RepositoryId }) },\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.authorize',\n scope,\n basePath: 'mcp',\n path: '/repository/authorize',\n method: 'POST',\n authentication: 'owner',\n description: 'Start MCP authorization.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n repositoryId: RepositoryId,\n serverName: Type.String({ minLength: 1, maxLength: 160 }),\n }),\n },\n responses: jsonApiResponses(McpAuthorizationSchema, 202),\n },\n ...(['GET', 'DELETE'] as const).map((method) => ({\n id: `mcp.authorization.${method}`,\n scope,\n basePath: 'mcp',\n path: '/repository/authorize/{flowId}',\n method,\n authentication: 'owner' as const,\n description: method === 'GET' ? 'Read an authorization flow.' : 'Cancel an authorization flow.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpAuthorizationSchema),\n })),\n ]),\n ],\n});\nexport default apiContracts;\n","import { definePoPluginMethod } from '@agimon-ai/po-core/pluginProtocol';\nimport { Type } from 'typebox';\n\nexport type { McpAppOpenResult } from '../types/webMcp';\n\nconst Lease = Type.String({ minLength: 1, maxLength: 128 });\nconst JsonObject = Type.Record(Type.String(), Type.Unknown());\nconst Empty = Type.Object({}, { additionalProperties: false });\nconst Result = Type.Object({\n content: Type.Array(Type.Unknown()),\n structuredContent: Type.Optional(Type.Unknown()),\n _meta: Type.Optional(JsonObject),\n isError: Type.Optional(Type.Boolean()),\n});\nconst Address = { service: 'mcp.apps', scope: 'session', direction: 'client-to-server' } as const;\n\nexport const mcpAppOpenMethod = definePoPluginMethod({\n ...Address,\n method: 'open',\n input: Type.Object({ toolCallId: Type.String({ minLength: 1, maxLength: 512 }) }, { additionalProperties: false }),\n output: Type.Object({\n leaseId: Lease,\n html: Type.String(),\n resourceUri: Type.String(),\n protocol: Type.Union([Type.Literal('mcp'), Type.Literal('openai')]),\n resourceMeta: JsonObject,\n tool: Type.Object({\n name: Type.String(),\n description: Type.String(),\n inputSchema: Type.Object({ type: Type.Literal('object') }, { additionalProperties: true }),\n _meta: JsonObject,\n }),\n args: JsonObject,\n result: Result,\n state: Type.Unknown(),\n readOnly: Type.Boolean(),\n }),\n});\n\nexport const mcpAppActivateMethod = definePoPluginMethod({\n ...Address,\n method: 'activate',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Type.Object({ readOnly: Type.Literal(false) }),\n});\nexport const mcpAppCallToolMethod = definePoPluginMethod({\n ...Address,\n method: 'callTool',\n input: Type.Object(\n { leaseId: Lease, name: Type.String({ minLength: 1, maxLength: 256 }), arguments: JsonObject },\n { additionalProperties: false },\n ),\n output: Result,\n});\nexport const mcpAppSetStateMethod = definePoPluginMethod({\n ...Address,\n method: 'setState',\n input: Type.Object({ leaseId: Lease, state: Type.Unknown() }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppFollowUpMethod = definePoPluginMethod({\n ...Address,\n method: 'followUp',\n input: Type.Object(\n { leaseId: Lease, prompt: Type.String({ minLength: 1, maxLength: 16000 }) },\n { additionalProperties: false },\n ),\n output: Empty,\n});\nexport const mcpAppCloseMethod = definePoPluginMethod({\n ...Address,\n method: 'close',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppMethods = [\n mcpAppOpenMethod,\n mcpAppActivateMethod,\n mcpAppCallToolMethod,\n mcpAppSetStateMethod,\n mcpAppFollowUpMethod,\n mcpAppCloseMethod,\n] as const;\n"],"mappings":"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"}
1
+ {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts","../src/schemas/mcpApps.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst RepositoryId = Type.String({\n pattern: '^(?:[a-f0-9]{32}|repo-[A-Za-z0-9_-]{24}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$',\n});\nconst RepositoryQuery = [{ name: 'repositoryId', in: 'query' as const, required: true, schema: RepositoryId }];\nexport const McpCatalogSchema = Type.Object({\n repositoryId: S,\n sync: Type.Object({ fresh: B, reasons: Type.Array(S) }),\n servers: Type.Array(\n Type.Object({\n name: S,\n state: literals(['not-connected', 'connecting', 'connected', 'degraded', 'needs-auth', 'failed', 'closed']),\n source: literals(['cached', 'live', 'configured']),\n credentialPresent: B,\n tools: Type.Array(Type.Object({ name: S, piName: S, description: O(S) })),\n error: O(S),\n }),\n ),\n droppedServers: Type.Array(S),\n diagnostics: Type.Array(S),\n});\nexport const McpAuthorizationSchema = Type.Object({\n id: S,\n repositoryId: S,\n serverName: S,\n status: literals(['starting', 'waiting', 'completed', 'failed', 'cancelled', 'expired']),\n authorizationUrl: O(S),\n error: O(S),\n expiresAt: N,\n});\nexport const McpSessionToolSchema = Type.Object({\n server: S,\n tool: S,\n description: O(S),\n inputSchema: Type.Record(S, Type.Unknown()),\n tokens: N,\n});\nconst StringPairs = Type.Record(S, S);\nexport const McpServerEntrySchema = Type.Union([\n Type.Object({ type: Type.Literal('http'), url: Type.String({ maxLength: 2048 }), headers: O(StringPairs) }),\n Type.Object({ command: Type.String({ minLength: 1, maxLength: 1024 }), args: Type.Array(S), env: O(StringPairs) }),\n]);\nexport const McpAddServerSchema = Type.Object({\n scope: literals(['repository', 'global']),\n repositoryId: O(RepositoryId),\n name: Type.String({ pattern: '^[A-Za-z0-9_-]{1,64}$' }),\n entry: McpServerEntrySchema,\n trusted: O(B),\n});\nexport const McpGlobalServersSchema = Type.Object({\n servers: Type.Array(Type.Object({ name: S, kind: literals(['remote', 'local']), target: S })),\n});\nconst SessionToolQuery = [\n { name: 'server', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 160 }) },\n { name: 'tool', in: 'query' as const, required: true, schema: Type.String({ minLength: 1, maxLength: 256 }) },\n];\ntype HttpContract = Parameters<typeof defineApiContract>[0]['http'][number];\nexport const apiContracts = defineApiContract({\n version: 1,\n sockets: [],\n dynamic: [],\n http: [\n {\n id: 'mcp.session.tool',\n scope: 'session',\n basePath: 'mcp-session',\n path: '/tool',\n method: 'GET',\n authentication: 'owner',\n description: 'Read one tool the session reaches through mcp_use: its description, schema, and token cost.',\n parameters: SessionToolQuery,\n responses: jsonApiResponses(McpSessionToolSchema),\n },\n ...(['global', 'workspace'] as const).flatMap((scope): HttpContract[] => [\n {\n id: 'mcp.catalog',\n scope,\n basePath: 'mcp',\n path: '/repository',\n method: 'GET',\n authentication: 'owner',\n description: 'Read the synced MCP repository catalog.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.discover',\n scope,\n basePath: 'mcp',\n path: '/repository/discover',\n method: 'POST',\n authentication: 'owner',\n description: 'Discover repository MCP servers.',\n body: { required: true, contentType: 'application/json', schema: Type.Object({ repositoryId: RepositoryId }) },\n responses: jsonApiResponses(McpCatalogSchema),\n },\n {\n id: 'mcp.authorize',\n scope,\n basePath: 'mcp',\n path: '/repository/authorize',\n method: 'POST',\n authentication: 'owner',\n description: 'Start MCP authorization.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n repositoryId: RepositoryId,\n serverName: Type.String({ minLength: 1, maxLength: 160 }),\n }),\n },\n responses: jsonApiResponses(McpAuthorizationSchema, 202),\n },\n {\n id: 'mcp.server.add',\n scope,\n basePath: 'mcp',\n path: '/servers',\n method: 'POST',\n authentication: 'owner',\n description: \"Add one MCP server to the repository's .mcp.json or the person's own config.\",\n body: { required: true, contentType: 'application/json', schema: McpAddServerSchema },\n responses: jsonApiResponses(Type.Object({ scope: literals(['repository', 'global']), name: S }), 201),\n },\n {\n id: 'mcp.servers.global',\n scope,\n basePath: 'mcp',\n path: '/servers/global',\n method: 'GET',\n authentication: 'owner',\n description: \"List the servers in the person's own MCP config, without headers or environment.\",\n responses: jsonApiResponses(McpGlobalServersSchema),\n },\n ...(['GET', 'DELETE'] as const).map((method) => ({\n id: `mcp.authorization.${method}`,\n scope,\n basePath: 'mcp',\n path: '/repository/authorize/{flowId}',\n method,\n authentication: 'owner' as const,\n description: method === 'GET' ? 'Read an authorization flow.' : 'Cancel an authorization flow.',\n parameters: RepositoryQuery,\n responses: jsonApiResponses(McpAuthorizationSchema),\n })),\n ]),\n ],\n});\nexport default apiContracts;\n","import { definePoPluginMethod } from '@agimon-ai/po-core/pluginProtocol';\nimport { Type } from 'typebox';\n\nexport type { McpAppOpenResult } from '../types/webMcp';\n\nconst Lease = Type.String({ minLength: 1, maxLength: 128 });\nconst JsonObject = Type.Record(Type.String(), Type.Unknown());\nconst Empty = Type.Object({}, { additionalProperties: false });\nconst Result = Type.Object({\n content: Type.Array(Type.Unknown()),\n structuredContent: Type.Optional(Type.Unknown()),\n _meta: Type.Optional(JsonObject),\n isError: Type.Optional(Type.Boolean()),\n});\nconst Address = { service: 'mcp.apps', scope: 'session', direction: 'client-to-server' } as const;\n\nexport const mcpAppOpenMethod = definePoPluginMethod({\n ...Address,\n method: 'open',\n input: Type.Object({ toolCallId: Type.String({ minLength: 1, maxLength: 512 }) }, { additionalProperties: false }),\n output: Type.Object({\n leaseId: Lease,\n html: Type.String(),\n resourceUri: Type.String(),\n protocol: Type.Union([Type.Literal('mcp'), Type.Literal('openai')]),\n resourceMeta: JsonObject,\n tool: Type.Object({\n name: Type.String(),\n description: Type.String(),\n inputSchema: Type.Object({ type: Type.Literal('object') }, { additionalProperties: true }),\n _meta: JsonObject,\n }),\n args: JsonObject,\n result: Result,\n state: Type.Unknown(),\n readOnly: Type.Boolean(),\n }),\n});\n\nexport const mcpAppActivateMethod = definePoPluginMethod({\n ...Address,\n method: 'activate',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Type.Object({ readOnly: Type.Literal(false) }),\n});\nexport const mcpAppCallToolMethod = definePoPluginMethod({\n ...Address,\n method: 'callTool',\n input: Type.Object(\n { leaseId: Lease, name: Type.String({ minLength: 1, maxLength: 256 }), arguments: JsonObject },\n { additionalProperties: false },\n ),\n output: Result,\n});\nexport const mcpAppSetStateMethod = definePoPluginMethod({\n ...Address,\n method: 'setState',\n input: Type.Object({ leaseId: Lease, state: Type.Unknown() }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppFollowUpMethod = definePoPluginMethod({\n ...Address,\n method: 'followUp',\n input: Type.Object(\n { leaseId: Lease, prompt: Type.String({ minLength: 1, maxLength: 16000 }) },\n { additionalProperties: false },\n ),\n output: Empty,\n});\nexport const mcpAppCloseMethod = definePoPluginMethod({\n ...Address,\n method: 'close',\n input: Type.Object({ leaseId: Lease }, { additionalProperties: false }),\n output: Empty,\n});\nexport const mcpAppMethods = [\n mcpAppOpenMethod,\n mcpAppActivateMethod,\n mcpAppCallToolMethod,\n mcpAppSetStateMethod,\n mcpAppFollowUpMethod,\n mcpAppCloseMethod,\n] as const;\n"],"mappings":"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"}
@@ -4,21 +4,42 @@ Object.defineProperties(exports, {
4
4
  });
5
5
  let _agimon_ai_po_core_mcpFacet = require("@agimon-ai/po-core/mcpFacet");
6
6
  let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin");
7
+ let typebox = require("typebox");
7
8
  let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
8
9
  require("typebox/value");
9
- let typebox = require("typebox");
10
10
  //#region src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp.ts
11
11
  var po_use_mcp_mcp_default = (0, _agimon_ai_po_core_mcpFacet.defineMcpSkill)({
12
12
  name: "po-use-mcp",
13
13
  description: "Use Po Pi MCP to inspect domain-scoped servers, authenticate, reload configuration, and troubleshoot tool availability.",
14
14
  read: () => (0, _agimon_ai_po_core_serverPlugin.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/po-use-mcp/SKILL.md")
15
15
  });
16
+ typebox.Type.Object({
17
+ server: typebox.Type.String({ minLength: 1 }),
18
+ tool: typebox.Type.String({ minLength: 1 }),
19
+ arguments: typebox.Type.Optional(typebox.Type.Record(typebox.Type.String(), typebox.Type.Unknown()))
20
+ });
21
+ /** The placeholder a session gets when the MCP tool catalog failed to mount; it takes nothing. */
22
+ const UnavailableMcpToolParameters = typebox.Type.Object({});
16
23
  //#endregion
17
24
  //#region src/services/mcpHeadlessTools/index.ts
18
25
  const MCP_HEADLESS_TOOLS_SERVICE = "po/mcp-headless-tools";
26
+ /**
27
+ * A tool that explains it is unavailable, so a session whose MCP package failed to load still
28
+ * wakes, without MCP, instead of failing as a whole with an opaque server error.
29
+ */
30
+ function unavailableTool(name) {
31
+ return {
32
+ name,
33
+ description: "Unavailable in this session: Po could not load its MCP package.",
34
+ parameters: UnavailableMcpToolParameters,
35
+ execute() {
36
+ return Promise.reject(/* @__PURE__ */ new Error(`MCP tool is unavailable: ${name}. Po could not load its MCP package; restart Po to retry.`));
37
+ }
38
+ };
39
+ }
19
40
  function bindMcpHeadlessTool(context, name) {
20
41
  const tool = context.services.get(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);
21
- if (!tool) throw new Error(`MCP tool is unavailable: ${name}`);
42
+ if (!tool) return unavailableTool(name);
22
43
  return {
23
44
  ...tool,
24
45
  execute(toolCallId, parameters, signal, onUpdate) {
@@ -33,11 +54,6 @@ var mcp_use_mcp_default = (0, _agimon_ai_po_core_mcpFacet.defineMcpTool)((contex
33
54
  //#endregion
34
55
  //#region src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp.ts
35
56
  var save_file_mcp_default = (0, _agimon_ai_po_core_mcpFacet.defineMcpTool)((context) => bindMcpHeadlessTool(context, "save_file"));
36
- typebox.Type.Object({
37
- server: typebox.Type.String({ minLength: 1 }),
38
- tool: typebox.Type.String({ minLength: 1 }),
39
- arguments: typebox.Type.Optional(typebox.Type.Record(typebox.Type.String(), typebox.Type.Unknown()))
40
- });
41
57
  //#endregion
42
58
  //#region src/services/mcpSessionTools/index.ts
43
59
  const MCP_SESSION_TOOLS_SERVICE = "po/mcp-session-tools";
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.cjs","names":["defineMcpSkill","readPackageResource","defineMcpTool","defineMcpTool","Type","defineRoutedContribution","defineMcpTool","defineMcpPlugin","skillPoUseMcp","toolMcpUse","toolSaveFile","toolSessionMcp","toolShareFile"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp.ts","../../src/services/mcpHeadlessTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp.ts","../../src/schemas/mcpHeadlessTool.ts","../../src/services/mcpSessionTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverPlugin';\n\nexport default defineMcpSkill({\n name: 'po-use-mcp',\n description:\n 'Use Po Pi MCP to inspect domain-scoped servers, authenticate, reload configuration, and troubleshoot tool availability.',\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-mcp/SKILL.md'),\n});\n","import type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nexport const MCP_HEADLESS_TOOLS_SERVICE = 'po/mcp-headless-tools';\n\nexport interface McpHeadlessToolCatalog {\n get(name: string): PoHeadlessTool | undefined;\n}\n\nexport function mountMcpHeadlessTools(tools: readonly PoHeadlessTool[]) {\n return (context: Context): void => {\n context.plugin((providerContext) => {\n providerContext.provide(MCP_HEADLESS_TOOLS_SERVICE, {\n get: (name) => tools.find((tool) => tool.name === name),\n } satisfies McpHeadlessToolCatalog);\n });\n };\n}\n\nexport function bindMcpHeadlessTool(context: PoMcpPluginContext, name: string): PoHeadlessTool {\n const tool = context.services.get<McpHeadlessToolCatalog>(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);\n if (!tool) throw new Error(`MCP tool is unavailable: ${name}`);\n return {\n ...tool,\n execute(toolCallId, parameters, signal, onUpdate) {\n const executionSignal = AbortSignal.any([context.signal, signal ?? context.signal]);\n return tool.execute(toolCallId, parameters, executionSignal, onUpdate, context.execution);\n },\n };\n}\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'mcp_use'));\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'save_file'));\n","import { Type } from 'typebox';\n\nexport const McpHeadlessToolParameters = Type.Object({\n server: Type.String({ minLength: 1 }),\n tool: Type.String({ minLength: 1 }),\n arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n});\n","import type { PoChildSessionMcpCatalog, PoChildSessionMcpTool } from '@agimon-ai/po-core/childSession';\nimport type { PoHeadlessTool, PoHeadlessToolResult } from '@agimon-ai/po-core/headless';\nimport type { ReadResourceResult } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\nimport { Value } from 'typebox/value';\n\nimport { McpHeadlessToolParameters } from '../../schemas/mcpHeadlessTool';\nimport { mcpToolExecutionMetadata, type CatalogTool } from '../mcpCatalog';\nimport { modelInputSchema } from '../mcpFileParams';\nimport type { McpSession } from '../mcpSession';\n\nexport const MCP_SESSION_TOOLS_SERVICE = 'po/mcp-session-tools';\n\n/** This projection needs no caller-owned execution context and can be borrowed unchanged. */\nexport interface McpDirectTool extends PoHeadlessTool {\n execute(toolCallId: string, parameters: unknown, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\n/** Narrow cross-root access to the Pi session's existing upstream MCP runtime. */\nexport interface McpSessionToolsService {\n readonly generation: string;\n runtimeRevision(): number;\n readAppResource(server: string, tool: string, resourceUri: string, signal?: AbortSignal): Promise<ReadResourceResult>;\n snapshot(): readonly CatalogTool[];\n project(): readonly McpDirectTool[];\n refresh(): void;\n dispose(): void;\n resolveSelectors(selectors: readonly string[]): readonly string[];\n onChange(listener: () => void): () => void;\n invoke(name: string, parameters: Record<string, unknown>, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\nexport function createMcpSessionToolsService(\n session: McpSession,\n generation: string,\n assertAvailable: () => void = () => undefined,\n): McpSessionToolsService {\n let disposed = false;\n const listeners = new Set<() => void>();\n const retained = new Map<string, { fingerprint: string; tool: McpDirectTool; retire(): void }>();\n const snapshot = () => {\n try {\n if (disposed) return [];\n assertAvailable();\n return session.activeToolDefinitions();\n } catch {\n // An inactive or stale parent lends no declarations.\n return [];\n }\n };\n const project = (): readonly McpDirectTool[] => {\n const definitions = snapshot();\n const names = new Set(definitions.map((tool) => tool.piName));\n for (const [name, entry] of retained) {\n if (names.has(name)) continue;\n entry.retire();\n retained.delete(name);\n }\n return definitions.map((definition) => {\n const fingerprint = JSON.stringify([session.toolGeneration, definition]);\n const previous = retained.get(definition.piName);\n if (previous?.fingerprint === fingerprint) return previous.tool;\n previous?.retire();\n let retired = false;\n const invoke = session.bindToolInvocation(definition);\n const tool: McpDirectTool = {\n name: definition.piName,\n label: `${definition.serverName}: ${definition.toolName}`,\n description: definition.description ?? `${definition.toolName} on the ${definition.serverName} MCP server.`,\n ...(definition.annotations === undefined ? {} : { annotations: definition.annotations }),\n ...(definition._meta === undefined ? {} : { _meta: mcpToolExecutionMetadata(definition) }),\n ...(definition.outputSchema === undefined ? {} : { outputSchema: definition.outputSchema }),\n // File parameters are validated as the `{path}` objects the model sends.\n parameters: modelInputSchema(definition) as TSchema,\n async execute(_toolCallId, parameters, signal) {\n assertAvailable();\n if (retired) throw new Error(`MCP tool ${definition.piName} is no longer available.`);\n signal?.throwIfAborted();\n const arguments_ = parameters === undefined ? {} : parameters;\n if (!Value.Check(tool.parameters, arguments_))\n throw new Error(`Invalid arguments for MCP tool ${definition.piName}.`);\n const result = await invoke(arguments_ as Record<string, unknown>, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n retained.set(definition.piName, {\n fingerprint,\n tool,\n retire: () => {\n retired = true;\n },\n });\n return tool;\n });\n };\n const refresh = () => {\n project();\n for (const listener of listeners) listener();\n };\n // Retirement must happen even if a borrower temporarily has no change listener.\n const stopSession = session.onChange(refresh);\n return Object.freeze({\n generation,\n runtimeRevision: () => session.toolGeneration,\n readAppResource: async (server: string, tool: string, resourceUri: string, signal?: AbortSignal) => {\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n const result = await session.readAppResource(server, tool, resourceUri, signal);\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n return result;\n },\n snapshot,\n project,\n refresh,\n dispose: () => {\n disposed = true;\n stopSession();\n refresh();\n listeners.clear();\n },\n resolveSelectors: (selectors: readonly string[]) => {\n const active = new Set(snapshot().map((tool) => tool.piName));\n return session\n .resolveToolSelectors(selectors)\n .map((tool) => tool.name)\n .filter((name) => active.has(name));\n },\n onChange: (listener: () => void) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n invoke: async (name: string, parameters: Record<string, unknown>, signal?: AbortSignal) => {\n assertAvailable();\n const tool = project().find((candidate) => candidate.name === name);\n if (!tool) throw new Error(`MCP tool ${name} is not available in this session.`);\n return tool.execute('mcp', parameters, signal);\n },\n });\n}\n\n/** Borrow an existing MCP runtime; a child never starts or disposes its own upstream connections. */\nexport function createMcpChildTool(\n invoke: (parameters: Static<typeof McpHeadlessToolParameters>, signal?: AbortSignal) => Promise<PoHeadlessToolResult>,\n catalog?: PoChildSessionMcpCatalog,\n): PoChildSessionMcpTool {\n return {\n name: 'mcp',\n ...(catalog === undefined ? {} : { catalog }),\n description: 'Call a tool exposed by a connected MCP server.',\n parameters: McpHeadlessToolParameters,\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n if (!Value.Check(McpHeadlessToolParameters, parameters)) throw new Error('Invalid MCP tool arguments.');\n const result = await invoke(parameters, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n}\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport {\n MCP_SESSION_TOOLS_SERVICE,\n type McpDirectTool,\n type McpSessionToolsService,\n} from '../../../../../services/mcpSessionTools';\n\nexport default defineRoutedContribution(\n (context: PoMcpPluginContext): readonly PoHeadlessTool[] => {\n const service = context.services.get<McpSessionToolsService>(MCP_SESSION_TOOLS_SERVICE);\n if (!service) return [];\n let current: readonly McpDirectTool[] = [];\n const stop = service.onChange(() => {\n const next = service.project();\n if (next.length === current.length && next.every((tool, index) => tool === current[index])) return;\n current = next;\n context.refresh();\n });\n current = service.project();\n context.signal.addEventListener('abort', stop, { once: true });\n return current.map((tool) => ({\n ...tool,\n execute: (toolCallId, parameters, signal) =>\n tool.execute(toolCallId, parameters, AbortSignal.any([context.signal, signal ?? context.signal])),\n }));\n },\n { cardinality: 'many' },\n);\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'share_file'));\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type PoMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoUseMcp from '../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp';\nimport toolSaveFile from '../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp';\nimport toolSessionMcp from '../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp';\nimport toolShareFile from '../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nconst withWidget = <T>(key: string, value: T): T => value === undefined ? value : ({\n ...value, _meta: { ...(value as { _meta?: object })._meta, [\"po/widget\"]: key },\n});\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-mcp',\n session: (context) => ({\n get skills(): PoMcpSessionPlugin['skills'] { return [at(skillPoUseMcp, context)]; },\n get tools(): PoMcpSessionPlugin['tools'] { return [withWidget(\"@agimon-ai/po-mcp/mcp_use\", via({ name: 'mcp_use' }, at(toolMcpUse, context))), via({ name: 'save_file' }, at(toolSaveFile, context)), ...many(toolSessionMcp, context).map((tool) => withWidget(\"@agimon-ai/po-mcp/session_mcp\", tool)), via({ name: 'share_file' }, at(toolShareFile, context))]; },\n }) satisfies PoMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp.cjs","names":["defineMcpSkill","readPackageResource","Type","defineMcpTool","defineMcpTool","defineRoutedContribution","defineMcpTool","defineMcpPlugin","skillPoUseMcp","toolMcpUse","toolSaveFile","toolSessionMcp","toolShareFile"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp.ts","../../src/schemas/mcpHeadlessTool.ts","../../src/services/mcpHeadlessTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp.ts","../../src/services/mcpSessionTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverPlugin';\n\nexport default defineMcpSkill({\n name: 'po-use-mcp',\n description:\n 'Use Po Pi MCP to inspect domain-scoped servers, authenticate, reload configuration, and troubleshoot tool availability.',\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-mcp/SKILL.md'),\n});\n","import { Type } from 'typebox';\n\nexport const McpHeadlessToolParameters = Type.Object({\n server: Type.String({ minLength: 1 }),\n tool: Type.String({ minLength: 1 }),\n arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n});\n\n/** The placeholder a session gets when the MCP tool catalog failed to mount; it takes nothing. */\nexport const UnavailableMcpToolParameters = Type.Object({});\n","import type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { UnavailableMcpToolParameters } from '../../schemas/mcpHeadlessTool';\n\nexport const MCP_HEADLESS_TOOLS_SERVICE = 'po/mcp-headless-tools';\n\nexport interface McpHeadlessToolCatalog {\n get(name: string): PoHeadlessTool | undefined;\n}\n\nexport function mountMcpHeadlessTools(tools: readonly PoHeadlessTool[]) {\n return (context: Context): void => {\n context.plugin((providerContext) => {\n providerContext.provide(MCP_HEADLESS_TOOLS_SERVICE, {\n get: (name) => tools.find((tool) => tool.name === name),\n } satisfies McpHeadlessToolCatalog);\n });\n };\n}\n\n/**\n * A tool that explains it is unavailable, so a session whose MCP package failed to load still\n * wakes, without MCP, instead of failing as a whole with an opaque server error.\n */\nfunction unavailableTool(name: string): PoHeadlessTool {\n return {\n name,\n description: 'Unavailable in this session: Po could not load its MCP package.',\n parameters: UnavailableMcpToolParameters,\n execute() {\n return Promise.reject(\n new Error(`MCP tool is unavailable: ${name}. Po could not load its MCP package; restart Po to retry.`),\n );\n },\n };\n}\n\nexport function bindMcpHeadlessTool(context: PoMcpPluginContext, name: string): PoHeadlessTool {\n const tool = context.services.get<McpHeadlessToolCatalog>(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);\n if (!tool) return unavailableTool(name);\n return {\n ...tool,\n execute(toolCallId, parameters, signal, onUpdate) {\n const executionSignal = AbortSignal.any([context.signal, signal ?? context.signal]);\n return tool.execute(toolCallId, parameters, executionSignal, onUpdate, context.execution);\n },\n };\n}\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'mcp_use'));\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'save_file'));\n","import type { PoChildSessionMcpCatalog, PoChildSessionMcpTool } from '@agimon-ai/po-core/childSession';\nimport type { PoHeadlessTool, PoHeadlessToolResult } from '@agimon-ai/po-core/headless';\nimport type { ReadResourceResult } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\nimport { Value } from 'typebox/value';\n\nimport { McpHeadlessToolParameters } from '../../schemas/mcpHeadlessTool';\nimport { mcpToolExecutionMetadata, type CatalogTool } from '../mcpCatalog';\nimport { modelInputSchema } from '../mcpFileParams';\nimport type { McpSession } from '../mcpSession';\n\nexport const MCP_SESSION_TOOLS_SERVICE = 'po/mcp-session-tools';\n\n/** This projection needs no caller-owned execution context and can be borrowed unchanged. */\nexport interface McpDirectTool extends PoHeadlessTool {\n execute(toolCallId: string, parameters: unknown, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\n/** Narrow cross-root access to the Pi session's existing upstream MCP runtime. */\nexport interface McpSessionToolsService {\n readonly generation: string;\n runtimeRevision(): number;\n readAppResource(server: string, tool: string, resourceUri: string, signal?: AbortSignal): Promise<ReadResourceResult>;\n snapshot(): readonly CatalogTool[];\n project(): readonly McpDirectTool[];\n refresh(): void;\n dispose(): void;\n resolveSelectors(selectors: readonly string[]): readonly string[];\n onChange(listener: () => void): () => void;\n invoke(name: string, parameters: Record<string, unknown>, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\nexport function createMcpSessionToolsService(\n session: McpSession,\n generation: string,\n assertAvailable: () => void = () => undefined,\n): McpSessionToolsService {\n let disposed = false;\n const listeners = new Set<() => void>();\n const retained = new Map<string, { fingerprint: string; tool: McpDirectTool; retire(): void }>();\n const snapshot = () => {\n try {\n if (disposed) return [];\n assertAvailable();\n return session.activeToolDefinitions();\n } catch {\n // An inactive or stale parent lends no declarations.\n return [];\n }\n };\n const project = (): readonly McpDirectTool[] => {\n const definitions = snapshot();\n const names = new Set(definitions.map((tool) => tool.piName));\n for (const [name, entry] of retained) {\n if (names.has(name)) continue;\n entry.retire();\n retained.delete(name);\n }\n return definitions.map((definition) => {\n const fingerprint = JSON.stringify([session.toolGeneration, definition]);\n const previous = retained.get(definition.piName);\n if (previous?.fingerprint === fingerprint) return previous.tool;\n previous?.retire();\n let retired = false;\n const invoke = session.bindToolInvocation(definition);\n const tool: McpDirectTool = {\n name: definition.piName,\n label: `${definition.serverName}: ${definition.toolName}`,\n description: definition.description ?? `${definition.toolName} on the ${definition.serverName} MCP server.`,\n ...(definition.annotations === undefined ? {} : { annotations: definition.annotations }),\n ...(definition._meta === undefined ? {} : { _meta: mcpToolExecutionMetadata(definition) }),\n ...(definition.outputSchema === undefined ? {} : { outputSchema: definition.outputSchema }),\n // File parameters are validated as the `{path}` objects the model sends.\n parameters: modelInputSchema(definition) as TSchema,\n async execute(_toolCallId, parameters, signal) {\n assertAvailable();\n if (retired) throw new Error(`MCP tool ${definition.piName} is no longer available.`);\n signal?.throwIfAborted();\n const arguments_ = parameters === undefined ? {} : parameters;\n if (!Value.Check(tool.parameters, arguments_))\n throw new Error(`Invalid arguments for MCP tool ${definition.piName}.`);\n const result = await invoke(arguments_ as Record<string, unknown>, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n retained.set(definition.piName, {\n fingerprint,\n tool,\n retire: () => {\n retired = true;\n },\n });\n return tool;\n });\n };\n const refresh = () => {\n project();\n for (const listener of listeners) listener();\n };\n // Retirement must happen even if a borrower temporarily has no change listener.\n const stopSession = session.onChange(refresh);\n return Object.freeze({\n generation,\n runtimeRevision: () => session.toolGeneration,\n readAppResource: async (server: string, tool: string, resourceUri: string, signal?: AbortSignal) => {\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n const result = await session.readAppResource(server, tool, resourceUri, signal);\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n return result;\n },\n snapshot,\n project,\n refresh,\n dispose: () => {\n disposed = true;\n stopSession();\n refresh();\n listeners.clear();\n },\n resolveSelectors: (selectors: readonly string[]) => {\n const active = new Set(snapshot().map((tool) => tool.piName));\n return session\n .resolveToolSelectors(selectors)\n .map((tool) => tool.name)\n .filter((name) => active.has(name));\n },\n onChange: (listener: () => void) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n invoke: async (name: string, parameters: Record<string, unknown>, signal?: AbortSignal) => {\n assertAvailable();\n const tool = project().find((candidate) => candidate.name === name);\n if (!tool) throw new Error(`MCP tool ${name} is not available in this session.`);\n return tool.execute('mcp', parameters, signal);\n },\n });\n}\n\n/** Borrow an existing MCP runtime; a child never starts or disposes its own upstream connections. */\nexport function createMcpChildTool(\n invoke: (parameters: Static<typeof McpHeadlessToolParameters>, signal?: AbortSignal) => Promise<PoHeadlessToolResult>,\n catalog?: PoChildSessionMcpCatalog,\n): PoChildSessionMcpTool {\n return {\n name: 'mcp',\n ...(catalog === undefined ? {} : { catalog }),\n description: 'Call a tool exposed by a connected MCP server.',\n parameters: McpHeadlessToolParameters,\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n if (!Value.Check(McpHeadlessToolParameters, parameters)) throw new Error('Invalid MCP tool arguments.');\n const result = await invoke(parameters, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n}\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport {\n MCP_SESSION_TOOLS_SERVICE,\n type McpDirectTool,\n type McpSessionToolsService,\n} from '../../../../../services/mcpSessionTools';\n\nexport default defineRoutedContribution(\n (context: PoMcpPluginContext): readonly PoHeadlessTool[] => {\n const service = context.services.get<McpSessionToolsService>(MCP_SESSION_TOOLS_SERVICE);\n if (!service) return [];\n let current: readonly McpDirectTool[] = [];\n const stop = service.onChange(() => {\n const next = service.project();\n if (next.length === current.length && next.every((tool, index) => tool === current[index])) return;\n current = next;\n context.refresh();\n });\n current = service.project();\n context.signal.addEventListener('abort', stop, { once: true });\n return current.map((tool) => ({\n ...tool,\n execute: (toolCallId, parameters, signal) =>\n tool.execute(toolCallId, parameters, AbortSignal.any([context.signal, signal ?? context.signal])),\n }));\n },\n { cardinality: 'many' },\n);\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'share_file'));\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type PoMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoUseMcp from '../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp';\nimport toolSaveFile from '../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp';\nimport toolSessionMcp from '../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp';\nimport toolShareFile from '../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nconst withWidget = <T>(key: string, value: T): T => value === undefined ? value : ({\n ...value, _meta: { ...(value as { _meta?: object })._meta, [\"po/widget\"]: key },\n});\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-mcp',\n session: (context) => ({\n get skills(): PoMcpSessionPlugin['skills'] { return [at(skillPoUseMcp, context)]; },\n get tools(): PoMcpSessionPlugin['tools'] { return [withWidget(\"@agimon-ai/po-mcp/mcp_use\", via({ name: 'mcp_use' }, at(toolMcpUse, context))), via({ name: 'save_file' }, at(toolSaveFile, context)), ...many(toolSessionMcp, context).map((tool) => withWidget(\"@agimon-ai/po-mcp/session_mcp\", tool)), via({ name: 'share_file' }, at(toolShareFile, context))]; },\n }) satisfies PoMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":"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"}
@@ -1,20 +1,41 @@
1
1
  import { defineMcpPlugin, defineMcpSkill, defineMcpTool } from "@agimon-ai/po-core/mcpFacet";
2
2
  import { readPackageResource } from "@agimon-ai/po-core/serverPlugin";
3
+ import { Type } from "typebox";
3
4
  import { defineRoutedContribution } from "@agimon-ai/po-core/extensionFile";
4
5
  import "typebox/value";
5
- import { Type } from "typebox";
6
6
  //#region src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp.ts
7
7
  var po_use_mcp_mcp_default = defineMcpSkill({
8
8
  name: "po-use-mcp",
9
9
  description: "Use Po Pi MCP to inspect domain-scoped servers, authenticate, reload configuration, and troubleshoot tool availability.",
10
10
  read: () => readPackageResource(import.meta.url, "src/prompts/po-use-mcp/SKILL.md")
11
11
  });
12
+ Type.Object({
13
+ server: Type.String({ minLength: 1 }),
14
+ tool: Type.String({ minLength: 1 }),
15
+ arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown()))
16
+ });
17
+ /** The placeholder a session gets when the MCP tool catalog failed to mount; it takes nothing. */
18
+ const UnavailableMcpToolParameters = Type.Object({});
12
19
  //#endregion
13
20
  //#region src/services/mcpHeadlessTools/index.ts
14
21
  const MCP_HEADLESS_TOOLS_SERVICE = "po/mcp-headless-tools";
22
+ /**
23
+ * A tool that explains it is unavailable, so a session whose MCP package failed to load still
24
+ * wakes, without MCP, instead of failing as a whole with an opaque server error.
25
+ */
26
+ function unavailableTool(name) {
27
+ return {
28
+ name,
29
+ description: "Unavailable in this session: Po could not load its MCP package.",
30
+ parameters: UnavailableMcpToolParameters,
31
+ execute() {
32
+ return Promise.reject(/* @__PURE__ */ new Error(`MCP tool is unavailable: ${name}. Po could not load its MCP package; restart Po to retry.`));
33
+ }
34
+ };
35
+ }
15
36
  function bindMcpHeadlessTool(context, name) {
16
37
  const tool = context.services.get(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);
17
- if (!tool) throw new Error(`MCP tool is unavailable: ${name}`);
38
+ if (!tool) return unavailableTool(name);
18
39
  return {
19
40
  ...tool,
20
41
  execute(toolCallId, parameters, signal, onUpdate) {
@@ -29,11 +50,6 @@ var mcp_use_mcp_default = defineMcpTool((context) => bindMcpHeadlessTool(context
29
50
  //#endregion
30
51
  //#region src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp.ts
31
52
  var save_file_mcp_default = defineMcpTool((context) => bindMcpHeadlessTool(context, "save_file"));
32
- Type.Object({
33
- server: Type.String({ minLength: 1 }),
34
- tool: Type.String({ minLength: 1 }),
35
- arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown()))
36
- });
37
53
  //#endregion
38
54
  //#region src/services/mcpSessionTools/index.ts
39
55
  const MCP_SESSION_TOOLS_SERVICE = "po/mcp-session-tools";
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.mjs","names":["skillPoUseMcp","toolMcpUse","toolSaveFile","toolSessionMcp","toolShareFile"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp.ts","../../src/services/mcpHeadlessTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp.ts","../../src/schemas/mcpHeadlessTool.ts","../../src/services/mcpSessionTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverPlugin';\n\nexport default defineMcpSkill({\n name: 'po-use-mcp',\n description:\n 'Use Po Pi MCP to inspect domain-scoped servers, authenticate, reload configuration, and troubleshoot tool availability.',\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-mcp/SKILL.md'),\n});\n","import type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nexport const MCP_HEADLESS_TOOLS_SERVICE = 'po/mcp-headless-tools';\n\nexport interface McpHeadlessToolCatalog {\n get(name: string): PoHeadlessTool | undefined;\n}\n\nexport function mountMcpHeadlessTools(tools: readonly PoHeadlessTool[]) {\n return (context: Context): void => {\n context.plugin((providerContext) => {\n providerContext.provide(MCP_HEADLESS_TOOLS_SERVICE, {\n get: (name) => tools.find((tool) => tool.name === name),\n } satisfies McpHeadlessToolCatalog);\n });\n };\n}\n\nexport function bindMcpHeadlessTool(context: PoMcpPluginContext, name: string): PoHeadlessTool {\n const tool = context.services.get<McpHeadlessToolCatalog>(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);\n if (!tool) throw new Error(`MCP tool is unavailable: ${name}`);\n return {\n ...tool,\n execute(toolCallId, parameters, signal, onUpdate) {\n const executionSignal = AbortSignal.any([context.signal, signal ?? context.signal]);\n return tool.execute(toolCallId, parameters, executionSignal, onUpdate, context.execution);\n },\n };\n}\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'mcp_use'));\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'save_file'));\n","import { Type } from 'typebox';\n\nexport const McpHeadlessToolParameters = Type.Object({\n server: Type.String({ minLength: 1 }),\n tool: Type.String({ minLength: 1 }),\n arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n});\n","import type { PoChildSessionMcpCatalog, PoChildSessionMcpTool } from '@agimon-ai/po-core/childSession';\nimport type { PoHeadlessTool, PoHeadlessToolResult } from '@agimon-ai/po-core/headless';\nimport type { ReadResourceResult } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\nimport { Value } from 'typebox/value';\n\nimport { McpHeadlessToolParameters } from '../../schemas/mcpHeadlessTool';\nimport { mcpToolExecutionMetadata, type CatalogTool } from '../mcpCatalog';\nimport { modelInputSchema } from '../mcpFileParams';\nimport type { McpSession } from '../mcpSession';\n\nexport const MCP_SESSION_TOOLS_SERVICE = 'po/mcp-session-tools';\n\n/** This projection needs no caller-owned execution context and can be borrowed unchanged. */\nexport interface McpDirectTool extends PoHeadlessTool {\n execute(toolCallId: string, parameters: unknown, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\n/** Narrow cross-root access to the Pi session's existing upstream MCP runtime. */\nexport interface McpSessionToolsService {\n readonly generation: string;\n runtimeRevision(): number;\n readAppResource(server: string, tool: string, resourceUri: string, signal?: AbortSignal): Promise<ReadResourceResult>;\n snapshot(): readonly CatalogTool[];\n project(): readonly McpDirectTool[];\n refresh(): void;\n dispose(): void;\n resolveSelectors(selectors: readonly string[]): readonly string[];\n onChange(listener: () => void): () => void;\n invoke(name: string, parameters: Record<string, unknown>, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\nexport function createMcpSessionToolsService(\n session: McpSession,\n generation: string,\n assertAvailable: () => void = () => undefined,\n): McpSessionToolsService {\n let disposed = false;\n const listeners = new Set<() => void>();\n const retained = new Map<string, { fingerprint: string; tool: McpDirectTool; retire(): void }>();\n const snapshot = () => {\n try {\n if (disposed) return [];\n assertAvailable();\n return session.activeToolDefinitions();\n } catch {\n // An inactive or stale parent lends no declarations.\n return [];\n }\n };\n const project = (): readonly McpDirectTool[] => {\n const definitions = snapshot();\n const names = new Set(definitions.map((tool) => tool.piName));\n for (const [name, entry] of retained) {\n if (names.has(name)) continue;\n entry.retire();\n retained.delete(name);\n }\n return definitions.map((definition) => {\n const fingerprint = JSON.stringify([session.toolGeneration, definition]);\n const previous = retained.get(definition.piName);\n if (previous?.fingerprint === fingerprint) return previous.tool;\n previous?.retire();\n let retired = false;\n const invoke = session.bindToolInvocation(definition);\n const tool: McpDirectTool = {\n name: definition.piName,\n label: `${definition.serverName}: ${definition.toolName}`,\n description: definition.description ?? `${definition.toolName} on the ${definition.serverName} MCP server.`,\n ...(definition.annotations === undefined ? {} : { annotations: definition.annotations }),\n ...(definition._meta === undefined ? {} : { _meta: mcpToolExecutionMetadata(definition) }),\n ...(definition.outputSchema === undefined ? {} : { outputSchema: definition.outputSchema }),\n // File parameters are validated as the `{path}` objects the model sends.\n parameters: modelInputSchema(definition) as TSchema,\n async execute(_toolCallId, parameters, signal) {\n assertAvailable();\n if (retired) throw new Error(`MCP tool ${definition.piName} is no longer available.`);\n signal?.throwIfAborted();\n const arguments_ = parameters === undefined ? {} : parameters;\n if (!Value.Check(tool.parameters, arguments_))\n throw new Error(`Invalid arguments for MCP tool ${definition.piName}.`);\n const result = await invoke(arguments_ as Record<string, unknown>, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n retained.set(definition.piName, {\n fingerprint,\n tool,\n retire: () => {\n retired = true;\n },\n });\n return tool;\n });\n };\n const refresh = () => {\n project();\n for (const listener of listeners) listener();\n };\n // Retirement must happen even if a borrower temporarily has no change listener.\n const stopSession = session.onChange(refresh);\n return Object.freeze({\n generation,\n runtimeRevision: () => session.toolGeneration,\n readAppResource: async (server: string, tool: string, resourceUri: string, signal?: AbortSignal) => {\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n const result = await session.readAppResource(server, tool, resourceUri, signal);\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n return result;\n },\n snapshot,\n project,\n refresh,\n dispose: () => {\n disposed = true;\n stopSession();\n refresh();\n listeners.clear();\n },\n resolveSelectors: (selectors: readonly string[]) => {\n const active = new Set(snapshot().map((tool) => tool.piName));\n return session\n .resolveToolSelectors(selectors)\n .map((tool) => tool.name)\n .filter((name) => active.has(name));\n },\n onChange: (listener: () => void) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n invoke: async (name: string, parameters: Record<string, unknown>, signal?: AbortSignal) => {\n assertAvailable();\n const tool = project().find((candidate) => candidate.name === name);\n if (!tool) throw new Error(`MCP tool ${name} is not available in this session.`);\n return tool.execute('mcp', parameters, signal);\n },\n });\n}\n\n/** Borrow an existing MCP runtime; a child never starts or disposes its own upstream connections. */\nexport function createMcpChildTool(\n invoke: (parameters: Static<typeof McpHeadlessToolParameters>, signal?: AbortSignal) => Promise<PoHeadlessToolResult>,\n catalog?: PoChildSessionMcpCatalog,\n): PoChildSessionMcpTool {\n return {\n name: 'mcp',\n ...(catalog === undefined ? {} : { catalog }),\n description: 'Call a tool exposed by a connected MCP server.',\n parameters: McpHeadlessToolParameters,\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n if (!Value.Check(McpHeadlessToolParameters, parameters)) throw new Error('Invalid MCP tool arguments.');\n const result = await invoke(parameters, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n}\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport {\n MCP_SESSION_TOOLS_SERVICE,\n type McpDirectTool,\n type McpSessionToolsService,\n} from '../../../../../services/mcpSessionTools';\n\nexport default defineRoutedContribution(\n (context: PoMcpPluginContext): readonly PoHeadlessTool[] => {\n const service = context.services.get<McpSessionToolsService>(MCP_SESSION_TOOLS_SERVICE);\n if (!service) return [];\n let current: readonly McpDirectTool[] = [];\n const stop = service.onChange(() => {\n const next = service.project();\n if (next.length === current.length && next.every((tool, index) => tool === current[index])) return;\n current = next;\n context.refresh();\n });\n current = service.project();\n context.signal.addEventListener('abort', stop, { once: true });\n return current.map((tool) => ({\n ...tool,\n execute: (toolCallId, parameters, signal) =>\n tool.execute(toolCallId, parameters, AbortSignal.any([context.signal, signal ?? context.signal])),\n }));\n },\n { cardinality: 'many' },\n);\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'share_file'));\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type PoMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoUseMcp from '../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp';\nimport toolSaveFile from '../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp';\nimport toolSessionMcp from '../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp';\nimport toolShareFile from '../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nconst withWidget = <T>(key: string, value: T): T => value === undefined ? value : ({\n ...value, _meta: { ...(value as { _meta?: object })._meta, [\"po/widget\"]: key },\n});\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-mcp',\n session: (context) => ({\n get skills(): PoMcpSessionPlugin['skills'] { return [at(skillPoUseMcp, context)]; },\n get tools(): PoMcpSessionPlugin['tools'] { return [withWidget(\"@agimon-ai/po-mcp/mcp_use\", via({ name: 'mcp_use' }, at(toolMcpUse, context))), via({ name: 'save_file' }, at(toolSaveFile, context)), ...many(toolSessionMcp, context).map((tool) => withWidget(\"@agimon-ai/po-mcp/session_mcp\", tool)), via({ name: 'share_file' }, at(toolShareFile, context))]; },\n }) satisfies PoMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp.mjs","names":["skillPoUseMcp","toolMcpUse","toolSaveFile","toolSessionMcp","toolShareFile"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp.ts","../../src/schemas/mcpHeadlessTool.ts","../../src/services/mcpHeadlessTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp.ts","../../src/services/mcpSessionTools/index.ts","../../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp.ts","../../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverPlugin';\n\nexport default defineMcpSkill({\n name: 'po-use-mcp',\n description:\n 'Use Po Pi MCP to inspect domain-scoped servers, authenticate, reload configuration, and troubleshoot tool availability.',\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-mcp/SKILL.md'),\n});\n","import { Type } from 'typebox';\n\nexport const McpHeadlessToolParameters = Type.Object({\n server: Type.String({ minLength: 1 }),\n tool: Type.String({ minLength: 1 }),\n arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n});\n\n/** The placeholder a session gets when the MCP tool catalog failed to mount; it takes nothing. */\nexport const UnavailableMcpToolParameters = Type.Object({});\n","import type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { UnavailableMcpToolParameters } from '../../schemas/mcpHeadlessTool';\n\nexport const MCP_HEADLESS_TOOLS_SERVICE = 'po/mcp-headless-tools';\n\nexport interface McpHeadlessToolCatalog {\n get(name: string): PoHeadlessTool | undefined;\n}\n\nexport function mountMcpHeadlessTools(tools: readonly PoHeadlessTool[]) {\n return (context: Context): void => {\n context.plugin((providerContext) => {\n providerContext.provide(MCP_HEADLESS_TOOLS_SERVICE, {\n get: (name) => tools.find((tool) => tool.name === name),\n } satisfies McpHeadlessToolCatalog);\n });\n };\n}\n\n/**\n * A tool that explains it is unavailable, so a session whose MCP package failed to load still\n * wakes, without MCP, instead of failing as a whole with an opaque server error.\n */\nfunction unavailableTool(name: string): PoHeadlessTool {\n return {\n name,\n description: 'Unavailable in this session: Po could not load its MCP package.',\n parameters: UnavailableMcpToolParameters,\n execute() {\n return Promise.reject(\n new Error(`MCP tool is unavailable: ${name}. Po could not load its MCP package; restart Po to retry.`),\n );\n },\n };\n}\n\nexport function bindMcpHeadlessTool(context: PoMcpPluginContext, name: string): PoHeadlessTool {\n const tool = context.services.get<McpHeadlessToolCatalog>(MCP_HEADLESS_TOOLS_SERVICE)?.get(name);\n if (!tool) return unavailableTool(name);\n return {\n ...tool,\n execute(toolCallId, parameters, signal, onUpdate) {\n const executionSignal = AbortSignal.any([context.signal, signal ?? context.signal]);\n return tool.execute(toolCallId, parameters, executionSignal, onUpdate, context.execution);\n },\n };\n}\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'mcp_use'));\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'save_file'));\n","import type { PoChildSessionMcpCatalog, PoChildSessionMcpTool } from '@agimon-ai/po-core/childSession';\nimport type { PoHeadlessTool, PoHeadlessToolResult } from '@agimon-ai/po-core/headless';\nimport type { ReadResourceResult } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\nimport { Value } from 'typebox/value';\n\nimport { McpHeadlessToolParameters } from '../../schemas/mcpHeadlessTool';\nimport { mcpToolExecutionMetadata, type CatalogTool } from '../mcpCatalog';\nimport { modelInputSchema } from '../mcpFileParams';\nimport type { McpSession } from '../mcpSession';\n\nexport const MCP_SESSION_TOOLS_SERVICE = 'po/mcp-session-tools';\n\n/** This projection needs no caller-owned execution context and can be borrowed unchanged. */\nexport interface McpDirectTool extends PoHeadlessTool {\n execute(toolCallId: string, parameters: unknown, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\n/** Narrow cross-root access to the Pi session's existing upstream MCP runtime. */\nexport interface McpSessionToolsService {\n readonly generation: string;\n runtimeRevision(): number;\n readAppResource(server: string, tool: string, resourceUri: string, signal?: AbortSignal): Promise<ReadResourceResult>;\n snapshot(): readonly CatalogTool[];\n project(): readonly McpDirectTool[];\n refresh(): void;\n dispose(): void;\n resolveSelectors(selectors: readonly string[]): readonly string[];\n onChange(listener: () => void): () => void;\n invoke(name: string, parameters: Record<string, unknown>, signal?: AbortSignal): Promise<PoHeadlessToolResult>;\n}\n\nexport function createMcpSessionToolsService(\n session: McpSession,\n generation: string,\n assertAvailable: () => void = () => undefined,\n): McpSessionToolsService {\n let disposed = false;\n const listeners = new Set<() => void>();\n const retained = new Map<string, { fingerprint: string; tool: McpDirectTool; retire(): void }>();\n const snapshot = () => {\n try {\n if (disposed) return [];\n assertAvailable();\n return session.activeToolDefinitions();\n } catch {\n // An inactive or stale parent lends no declarations.\n return [];\n }\n };\n const project = (): readonly McpDirectTool[] => {\n const definitions = snapshot();\n const names = new Set(definitions.map((tool) => tool.piName));\n for (const [name, entry] of retained) {\n if (names.has(name)) continue;\n entry.retire();\n retained.delete(name);\n }\n return definitions.map((definition) => {\n const fingerprint = JSON.stringify([session.toolGeneration, definition]);\n const previous = retained.get(definition.piName);\n if (previous?.fingerprint === fingerprint) return previous.tool;\n previous?.retire();\n let retired = false;\n const invoke = session.bindToolInvocation(definition);\n const tool: McpDirectTool = {\n name: definition.piName,\n label: `${definition.serverName}: ${definition.toolName}`,\n description: definition.description ?? `${definition.toolName} on the ${definition.serverName} MCP server.`,\n ...(definition.annotations === undefined ? {} : { annotations: definition.annotations }),\n ...(definition._meta === undefined ? {} : { _meta: mcpToolExecutionMetadata(definition) }),\n ...(definition.outputSchema === undefined ? {} : { outputSchema: definition.outputSchema }),\n // File parameters are validated as the `{path}` objects the model sends.\n parameters: modelInputSchema(definition) as TSchema,\n async execute(_toolCallId, parameters, signal) {\n assertAvailable();\n if (retired) throw new Error(`MCP tool ${definition.piName} is no longer available.`);\n signal?.throwIfAborted();\n const arguments_ = parameters === undefined ? {} : parameters;\n if (!Value.Check(tool.parameters, arguments_))\n throw new Error(`Invalid arguments for MCP tool ${definition.piName}.`);\n const result = await invoke(arguments_ as Record<string, unknown>, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n retained.set(definition.piName, {\n fingerprint,\n tool,\n retire: () => {\n retired = true;\n },\n });\n return tool;\n });\n };\n const refresh = () => {\n project();\n for (const listener of listeners) listener();\n };\n // Retirement must happen even if a borrower temporarily has no change listener.\n const stopSession = session.onChange(refresh);\n return Object.freeze({\n generation,\n runtimeRevision: () => session.toolGeneration,\n readAppResource: async (server: string, tool: string, resourceUri: string, signal?: AbortSignal) => {\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n const result = await session.readAppResource(server, tool, resourceUri, signal);\n assertAvailable();\n if (disposed) throw new Error('The MCP session is no longer available.');\n return result;\n },\n snapshot,\n project,\n refresh,\n dispose: () => {\n disposed = true;\n stopSession();\n refresh();\n listeners.clear();\n },\n resolveSelectors: (selectors: readonly string[]) => {\n const active = new Set(snapshot().map((tool) => tool.piName));\n return session\n .resolveToolSelectors(selectors)\n .map((tool) => tool.name)\n .filter((name) => active.has(name));\n },\n onChange: (listener: () => void) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n invoke: async (name: string, parameters: Record<string, unknown>, signal?: AbortSignal) => {\n assertAvailable();\n const tool = project().find((candidate) => candidate.name === name);\n if (!tool) throw new Error(`MCP tool ${name} is not available in this session.`);\n return tool.execute('mcp', parameters, signal);\n },\n });\n}\n\n/** Borrow an existing MCP runtime; a child never starts or disposes its own upstream connections. */\nexport function createMcpChildTool(\n invoke: (parameters: Static<typeof McpHeadlessToolParameters>, signal?: AbortSignal) => Promise<PoHeadlessToolResult>,\n catalog?: PoChildSessionMcpCatalog,\n): PoChildSessionMcpTool {\n return {\n name: 'mcp',\n ...(catalog === undefined ? {} : { catalog }),\n description: 'Call a tool exposed by a connected MCP server.',\n parameters: McpHeadlessToolParameters,\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n if (!Value.Check(McpHeadlessToolParameters, parameters)) throw new Error('Invalid MCP tool arguments.');\n const result = await invoke(parameters, signal);\n signal?.throwIfAborted();\n return result;\n },\n };\n}\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { PoHeadlessTool } from '@agimon-ai/po-core/headless';\nimport type { PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport {\n MCP_SESSION_TOOLS_SERVICE,\n type McpDirectTool,\n type McpSessionToolsService,\n} from '../../../../../services/mcpSessionTools';\n\nexport default defineRoutedContribution(\n (context: PoMcpPluginContext): readonly PoHeadlessTool[] => {\n const service = context.services.get<McpSessionToolsService>(MCP_SESSION_TOOLS_SERVICE);\n if (!service) return [];\n let current: readonly McpDirectTool[] = [];\n const stop = service.onChange(() => {\n const next = service.project();\n if (next.length === current.length && next.every((tool, index) => tool === current[index])) return;\n current = next;\n context.refresh();\n });\n current = service.project();\n context.signal.addEventListener('abort', stop, { once: true });\n return current.map((tool) => ({\n ...tool,\n execute: (toolCallId, parameters, signal) =>\n tool.execute(toolCallId, parameters, AbortSignal.any([context.signal, signal ?? context.signal])),\n }));\n },\n { cardinality: 'many' },\n);\n","import { defineMcpTool, type PoMcpPluginContext } from '@agimon-ai/po-core/mcpFacet';\n\nimport { bindMcpHeadlessTool } from '../../../../../services/mcpHeadlessTools';\n\nexport default defineMcpTool((context: PoMcpPluginContext) => bindMcpHeadlessTool(context, 'share_file'));\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type PoMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoUseMcp from '../src/extensions/workspaces/sessions/(backend)/skill/po-use-mcp.mcp';\nimport toolMcpUse from '../src/extensions/workspaces/sessions/(backend)/tool/mcp_use.mcp';\nimport toolSaveFile from '../src/extensions/workspaces/sessions/(backend)/tool/save_file.mcp';\nimport toolSessionMcp from '../src/extensions/workspaces/sessions/(backend)/tool/session_mcp.mcp';\nimport toolShareFile from '../src/extensions/workspaces/sessions/(backend)/tool/share_file.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nconst withWidget = <T>(key: string, value: T): T => value === undefined ? value : ({\n ...value, _meta: { ...(value as { _meta?: object })._meta, [\"po/widget\"]: key },\n});\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-mcp',\n session: (context) => ({\n get skills(): PoMcpSessionPlugin['skills'] { return [at(skillPoUseMcp, context)]; },\n get tools(): PoMcpSessionPlugin['tools'] { return [withWidget(\"@agimon-ai/po-mcp/mcp_use\", via({ name: 'mcp_use' }, at(toolMcpUse, context))), via({ name: 'save_file' }, at(toolSaveFile, context)), ...many(toolSessionMcp, context).map((tool) => withWidget(\"@agimon-ai/po-mcp/session_mcp\", tool)), via({ name: 'share_file' }, at(toolShareFile, context))]; },\n }) satisfies PoMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":"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"}