@agimon-ai/po-mcp 0.0.0-alpha.7 → 0.0.0-alpha.71

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 (59) hide show
  1. package/LICENSE +149 -21
  2. package/README.md +111 -16
  3. package/dist/apiContracts.cjs +147 -56
  4. package/dist/apiContracts.cjs.map +1 -1
  5. package/dist/apiContracts.d.mts.map +1 -1
  6. package/dist/apiContracts.mjs +147 -56
  7. package/dist/apiContracts.mjs.map +1 -1
  8. package/dist/extensions/mcp.cjs +29 -13
  9. package/dist/extensions/mcp.cjs.map +1 -1
  10. package/dist/extensions/mcp.mjs +29 -13
  11. package/dist/extensions/mcp.mjs.map +1 -1
  12. package/dist/extensions/native.mjs +1500 -0
  13. package/dist/extensions/native.mjs.map +1 -0
  14. package/dist/extensions/server.cjs +3758 -2564
  15. package/dist/extensions/server.cjs.map +1 -1
  16. package/dist/extensions/server.d.mts +2 -2
  17. package/dist/extensions/server.d.mts.map +1 -1
  18. package/dist/extensions/server.mjs +3762 -2567
  19. package/dist/extensions/server.mjs.map +1 -1
  20. package/dist/extensions/web.mjs +874 -180
  21. package/dist/extensions/web.mjs.map +1 -1
  22. package/dist/index-weSvnCeI.d.mts +27 -0
  23. package/dist/index-weSvnCeI.d.mts.map +1 -0
  24. package/dist/index.cjs +1 -1
  25. package/dist/index.d.mts +8 -33
  26. package/dist/index.d.mts.map +1 -1
  27. package/dist/index.mjs +1 -1
  28. package/dist/localServers.cjs +4 -0
  29. package/dist/localServers.d.mts +39 -0
  30. package/dist/localServers.d.mts.map +1 -0
  31. package/dist/localServers.mjs +1 -0
  32. package/dist/{mcpCatalog-BHoE4gfz.cjs → mcpCatalog-Be0BcPOu.cjs} +161 -47
  33. package/dist/mcpCatalog-Be0BcPOu.cjs.map +1 -0
  34. package/dist/{mcpCatalog-Bp-mLZM1.mjs → mcpCatalog-rxpMjGIW.mjs} +140 -44
  35. package/dist/mcpCatalog-rxpMjGIW.mjs.map +1 -0
  36. package/dist/{mcpConfig-lHsIQ2fZ.d.mts → mcpConfig-DrGHS_aV.d.mts} +4 -2
  37. package/dist/{mcpConfig-lHsIQ2fZ.d.mts.map → mcpConfig-DrGHS_aV.d.mts.map} +1 -1
  38. package/dist/projection-BH-vn29y.mjs +56 -0
  39. package/dist/projection-BH-vn29y.mjs.map +1 -0
  40. package/dist/projection-DBpXsw0W.cjs +64 -0
  41. package/dist/projection-DBpXsw0W.cjs.map +1 -0
  42. package/dist/projection.cjs +1 -1
  43. package/dist/projection.d.mts +8 -2
  44. package/dist/projection.d.mts.map +1 -1
  45. package/dist/projection.mjs +1 -1
  46. package/dist/sessionServers-aDZVqS6t.mjs +182 -0
  47. package/dist/sessionServers-aDZVqS6t.mjs.map +1 -0
  48. package/dist/sessionServers-xi5PL_GP.cjs +199 -0
  49. package/dist/sessionServers-xi5PL_GP.cjs.map +1 -0
  50. package/llms.txt +2 -1
  51. package/package.json +39 -18
  52. package/src/prompts/codemode-how-to-mcp/SKILL.md +46 -0
  53. package/src/prompts/{po-use-mcp → help-how-to-mcp}/SKILL.md +41 -10
  54. package/dist/mcpCatalog-BHoE4gfz.cjs.map +0 -1
  55. package/dist/mcpCatalog-Bp-mLZM1.mjs.map +0 -1
  56. package/dist/projection-gyAA2jRB.mjs +0 -43
  57. package/dist/projection-gyAA2jRB.mjs.map +0 -1
  58. package/dist/projection-w3XxXmVi.cjs +0 -51
  59. package/dist/projection-w3XxXmVi.cjs.map +0 -1
package/LICENSE CHANGED
@@ -1,21 +1,149 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Vuong Ngo
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ License text copyright © 2017 MariaDB Corporation Ab, All Rights Reserved.
2
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
3
+
4
+ Parameters
5
+
6
+ Licensor: Agimon Pty Ltd
7
+ Licensed Work: Po, the software in the Po source repository and the
8
+ packages released from it, in each version released by
9
+ the Licensor.
10
+ The Licensed Work is (c) 2026 Agimon Pty Ltd.
11
+ Material identified as third-party in the "Third-party
12
+ components" section at the end of this file or in a
13
+ NOTICE file, and any package or directory whose own
14
+ license file grants a different license, is not part of
15
+ the Licensed Work and remains under its own license.
16
+ Additional Use Grant: You may make production use of the Licensed Work if
17
+ your use is Eligible Use. "Eligible Use" is production use that falls
18
+ within at least one of the following:
19
+
20
+ (a) Personal Use. Use by an individual for their own personal purposes,
21
+ and not on behalf of, or for the benefit of, an employer, client, or
22
+ other Organization. Use by an individual in the course of employment
23
+ or engagement by an Organization is use by that Organization.
24
+
25
+ (b) Small Organization Use. Use by or on behalf of an Organization whose
26
+ Annual Revenue is less than USD 1,000,000.
27
+
28
+ (c) Non-profit, Education and Research Use. Use, regardless of Annual
29
+ Revenue, by (i) an Organization registered or recognized as a
30
+ non-profit or charitable organization under the laws of its
31
+ jurisdiction, for its non-profit purposes; (ii) an accredited school,
32
+ college, or university, for teaching, learning, or academic research;
33
+ or (iii) a publicly funded research institution, for its research.
34
+
35
+ (d) Service Provider Use. Use by a consultant, contractor, agency, or other
36
+ service provider, regardless of its own Annual Revenue, solely to
37
+ build, deploy, host, operate, or support the Licensed Work for a client
38
+ whose own use would be Eligible Use under (a), (b), or (c). A service
39
+ provider's use for its own purposes is Eligible Use only if the service
40
+ provider itself qualifies under (b) or (c).
41
+
42
+
43
+ Hosted services. Offering the Licensed Work to third parties as a hosted
44
+ or managed service whose primary value is the Licensed Work is Eligible
45
+ Use only if each such third party's own use would be Eligible Use.
46
+
47
+ Definitions. "Organization" means any company, partnership, sole
48
+ proprietorship, trust, association, government body, or other entity, and
49
+ includes an individual acting in a business or professional capacity.
50
+ "Affiliate" means any entity that directly or indirectly controls, is
51
+ controlled by, or is under common control with an Organization, where
52
+ "control" means ownership of more than 50% of the voting interests of an
53
+ entity or the power to direct its management and policies by contract or
54
+ otherwise. "Annual Revenue" means the total gross revenue of an
55
+ Organization and all of its Affiliates combined, from all sources and
56
+ whether or not related to the Licensed Work, for its most recently
57
+ completed fiscal year, or, if it has not completed a fiscal year, for the
58
+ twelve months before the use (or since its formation, if shorter),
59
+ converted into US dollars at the average exchange rate for that period.
60
+ Proceeds of equity or debt financing are not revenue.
61
+
62
+ Threshold. If an Organization stops qualifying under (b), its existing
63
+ production use remains Eligible Use for 90 days after it stops
64
+ qualifying, after which it must obtain a commercial license or stop
65
+ production use. Use that was Eligible Use when it occurred never requires
66
+ a commercial license after the fact.
67
+ Change Date: Four years from the date a version of the Licensed Work
68
+ is first publicly released by the Licensor.
69
+ Change License: Apache License, Version 2.0
70
+
71
+ For information about alternative licensing arrangements for the Licensed
72
+ Work, please visit: https://agimon.ai/licensing
73
+
74
+ Notice
75
+
76
+ The Business Source License (this document, or the "License") is not an Open
77
+ Source license. However, the Licensed Work will eventually be made available
78
+ under an Open Source License, as stated in this License.
79
+
80
+ -----------------------------------------------------------------------------
81
+
82
+ Business Source License 1.1
83
+
84
+ Terms
85
+
86
+ The Licensor hereby grants you the right to copy, modify, create derivative
87
+ works, redistribute, and make non-production use of the Licensed Work. The
88
+ Licensor may make an Additional Use Grant, above, permitting limited
89
+ production use.
90
+
91
+ Effective on the Change Date, or the fourth anniversary of the first publicly
92
+ available distribution of a specific version of the Licensed Work under this
93
+ License, whichever comes first, the Licensor hereby grants you rights under
94
+ the terms of the Change License, and the rights granted in the paragraph
95
+ above terminate.
96
+
97
+ If your use of the Licensed Work does not comply with the requirements
98
+ currently in effect as described in this License, you must purchase a
99
+ commercial license from the Licensor, its affiliated entities, or authorized
100
+ resellers, or you must refrain from using the Licensed Work.
101
+
102
+ All copies of the original and modified Licensed Work, and derivative works
103
+ of the Licensed Work, are subject to this License. This License applies
104
+ separately for each version of the Licensed Work and the Change Date may vary
105
+ for each version of the Licensed Work released by Licensor.
106
+
107
+ You must conspicuously display this License on each original or modified copy
108
+ of the Licensed Work. If you receive the Licensed Work in original or
109
+ modified form from a third party, the terms and conditions set forth in this
110
+ License apply to your use of that work.
111
+
112
+ Any use of the Licensed Work in violation of this License will automatically
113
+ terminate your rights under this License for the current and all other
114
+ versions of the Licensed Work.
115
+
116
+ This License does not grant you any right in any trademark or logo of
117
+ Licensor or its affiliates (provided that you may use a trademark or logo of
118
+ Licensor as expressly required by this License).
119
+
120
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
121
+ AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
122
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
123
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
124
+ TITLE.
125
+
126
+ MariaDB hereby grants you permission to use this License’s text to license
127
+ your works, and to refer to it using the trademark “Business Source License”,
128
+ as long as you comply with the Covenants of Licensor below.
129
+
130
+ Covenants of Licensor
131
+
132
+ In consideration of the right to use this License’s text and the “Business
133
+ Source License” name and trademark, Licensor covenants to MariaDB, and to all
134
+ other recipients of the licensed work to be provided by Licensor:
135
+
136
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
137
+ or a license that is compatible with GPL Version 2.0 or a later version,
138
+ where “compatible” means that software provided under the Change License can
139
+ be included in a program with software provided under GPL Version 2.0 or a
140
+ later version. Licensor may specify additional Change Licenses without
141
+ limitation.
142
+
143
+ 2. To either: (a) specify an additional grant of rights to use that does not
144
+ impose any additional restriction on the right granted in this License, as
145
+ the Additional Use Grant; or (b) insert the text “None”.
146
+
147
+ 3. To specify a Change Date.
148
+
149
+ 4. Not to modify this License in any other way.
package/README.md CHANGED
@@ -39,6 +39,18 @@ 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. Named header or environment values can be kept in the Po vault
51
+ instead (`secretFields` on the add request): the vault is written first, the file gets
52
+ `${vault:<server>-<field>}` in their place, and a failed file write removes the new secrets.
53
+ Without a vault the request answers 503.
42
54
  Selected legacy plugins may also provide root `.mcp.json`. A schema-gated Agent Plugin v1 instead
43
55
  provides root `mcp.json`. Po validates its portable contract, supplies private persistent
44
56
  `PLUGIN_DATA`, and resolves plugin-relative stdio commands and working directories. It also
@@ -63,7 +75,7 @@ should load.
63
75
 
64
76
  Within Po, this package consumes the immutable `poMcpProjection` service published on the
65
77
  session Cordis root.
66
- Downstream clients run in-process through `@agimon-ai/mcp-proxy`; this adapter does not start its
78
+ Downstream clients run in-process through `@agimon-ai/po-mcp-proxy`; this adapter does not start its
67
79
  Hono server.
68
80
 
69
81
  ## Direct tools and configured identity
@@ -81,12 +93,79 @@ original downstream tool name; tool prefixes are not parsed to route calls.
81
93
  Children borrow the parent runtime. Requested `mcp` or `mcp_use` groups expand into permitted
82
94
  direct tools; `mcpDirectTools` selectors (`*`, a configured server, or `server/tool`) narrow that
83
95
  set. Capability ceilings must explicitly allow MCP and still constrain the selected tools.
84
- Children cannot manage the parent's connections. Remote `mcp_use` remains a compatibility route,
85
- not the default native model declaration.
96
+ The direct connection-management tool is main-agent-only. Borrowed trusted `exec` still uses
97
+ parent-session bindings, including Help-only `mcpTest`. Remote `mcp_use` remains a compatibility
98
+ route, not the default native model declaration.
86
99
 
87
- Full schemas cost context tokens. Select domains and child subsets rather than hiding tool
88
- availability or repeating catalogs in prompt prose. Codemode and tool search remain disabled;
89
- the Pi 1.0.0 source review did not measure savings or justify enabling them.
100
+ Select domains and child subsets to control tool availability. Keep catalogs out of prompt prose.
101
+
102
+ ## Po MCP namespace
103
+
104
+ Po's own `discover` and `exec` tools (`@agimon-ai/po-codemode`) enable the `mcp`
105
+ namespace alongside namespaces such as `browser`. Pi's internal MCP codemode and tool
106
+ search remain disabled. These are separate mechanisms, also distinct from code mode
107
+ run by a remote MCP client. While code mode is bound, the main agent's direct tool
108
+ declarations for these servers are withdrawn, since the namespace reaches every one and
109
+ their schemas would only cost context; they show as inactive in Context. A tool that carries
110
+ an MCP App keeps its direct tool for the inline UI. Without code mode every direct tool stays,
111
+ and the `mcp_use` compatibility route remains. Native child sessions still receive the
112
+ direct tools they are granted. The namespace does not change MCP access grants.
113
+
114
+ The always-active `codemode-how-to-mcp` skill teaches agents this flow and, when loaded, lists the session's servers and tool names.
115
+
116
+ Start with `discover({ namespace: 'mcp' })` to inspect the permitted catalog and typed
117
+ signatures. If the declaration output exceeds 24,000 characters, narrow discovery
118
+ with `discover({ query: 'github/search_issues' })` before calling a tool. Use only
119
+ names and argument schemas returned by discovery, never guessed names.
120
+
121
+ Inside `exec`, call a typed wrapper such as `await mcp.github.search_issues(args)`,
122
+ where `args` matches the discovered input schema. Names are exact configured server
123
+ and original tool names, not normalized direct-tool prefixes. Use bracket access
124
+ for names that need it, for example `await mcp['work-github']['search-issues'](args)`.
125
+ The generic route is `await mcp.call(server, tool, args)`, using the exact discovered
126
+ server and tool names. Both routes use the same permitted session connections and
127
+ admission checks as direct calls.
128
+
129
+ Results expose `text`, `images`, `structuredContent`, and `blocks`. Inspect the text
130
+ or structured content in the script; use `image(result)` to emit its images from
131
+ `exec`. Upstream `isError` results reject with the upstream text rather than
132
+ returning a successful result.
133
+
134
+ Outbound file parameters still require consent. Time waiting for that consent counts
135
+ against the `exec` timeout: 30 seconds by default, with `timeoutMs` up to 120 seconds.
136
+ After a runtime swap, an old run cannot access the replacement runtime. Discover again
137
+ and retry in a new `exec`, not in the old run.
138
+
139
+ MCP Apps stay on direct tools so their inline UI and interaction lifecycle remain
140
+ available. Use a direct call when an App is needed, not the namespace route.
141
+
142
+ ## Session-only URL test servers
143
+
144
+ In Help mode, ask permission, then discover `mcpTest` and add a URL server:
145
+
146
+ ```ts
147
+ await mcpTest.add({ name: 'test', url: 'https://example.com/mcp', type: 'http' });
148
+ ```
149
+
150
+ HTTP and SSE servers accept optional headers and OAuth client settings. Sign-in links appear
151
+ in the existing MCP panel. Add waits for completion and respects cancellation. With no code
152
+ mode, the main-agent-only `mcp_test_server` tool supports `add`, `remove` and `list` instead.
153
+ These management surfaces disappear when Help turns off, but connected test servers remain.
154
+ `mcpTest.remove(name)` disconnects and forgets one while Help is on.
155
+
156
+ Test server configuration, headers and credentials stay in memory, including across MCP
157
+ reloads. They are not written to config, the Po vault, credential files or the shared tool cache,
158
+ and a new session does not inherit them. They cannot replace configured names or override
159
+ `--no-mcp`. Stdio and `/mcp add` are deliberately unsupported.
160
+
161
+ Memory-only storage does not redact tool arguments or conversation history. Never paste
162
+ literal secrets into management calls. Use `${ENV_VAR}` references from the session's
163
+ admitted environment for sensitive headers or OAuth client settings.
164
+
165
+ Configured-server credentials live in the Po vault (`po/vault`, namespace `mcp.oauth`). Without a
166
+ vault they stay in memory and the session shows a diagnostic. Near-expiry tokens refresh before
167
+ requests, with no idle timer. The vault's lease coordinates refresh across processes, so a
168
+ rotating refresh token is spent once; memory stores synchronize only within their process.
90
169
 
91
170
  ## Inline Apps (development)
92
171
 
@@ -106,17 +185,17 @@ Reopening a widget reads its retained result and state, never reruns the origina
106
185
  built on the ChatGPT SDK work too. Only ChatGPT widgets receive `toolOutput` globals updates
107
186
  after their own `callTool`. Each App root gets a `light`/`dark` class, `data-theme` and
108
187
  `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.
188
+ An MCP tool card starts collapsed; an App stays visible. Expanding the card shows the call's input, then its result.
110
189
 
111
190
  The ChatGPT adapter implements tool input/output and private metadata globals, globals
112
191
  updates, `callTool`, `setWidgetState`, `sendFollowUpMessage`, inline display mode, height,
113
192
  close, and confirmed external links. File libraries, checkout, accounts, modal/fullscreen
114
193
  modes, stable custom origins, sampling, and automatic model-context updates are unsupported.
115
194
 
116
- The runtime pins published `@agimon-ai/mcp-proxy@0.32.12` for Apps capability
117
- negotiation, private result capture before output guarding, and upstream request
118
- cancellation. Model-facing output remains guarded; retained App results are bounded
119
- separately. No local proxy dependency or spill-file reads are used.
195
+ The runtime uses workspace-owned `@agimon-ai/po-mcp-proxy` from
196
+ `packages/utils/po-mcp-proxy` for Apps capability negotiation, private result capture
197
+ before output guarding, and upstream request cancellation. Model-facing output remains
198
+ guarded; retained App results are bounded separately. No spill-file reads are used.
120
199
 
121
200
  Run from the repository root:
122
201
 
@@ -157,10 +236,26 @@ catalog and authorization APIs remain separate from this live-session view.
157
236
  Allowed stdio entries execute their configured commands with the Pi process environment and
158
237
  operating system privileges. Review configuration as executable code.
159
238
 
160
- OAuth credentials use the operating system keyring when available. The private-file fallback is
161
- stored under `~/.mcp-proxy/oauth` with owner-only permissions. Credentials remain machine-wide and
162
- keyed by server name, while their upstream URL binding prevents blind replay to another endpoint.
163
- Treat both the configuration and credential store as sensitive.
239
+ OAuth credentials are encrypted entries in the Po vault. Each is keyed by scope and server name:
240
+ `user` for your own `mcp.json`, `repository:<digest>` for a repository (keyed by its git common
241
+ directory, so worktrees share it and separate clones do not), and the plugin's source id for a
242
+ plugin. One server name at three levels therefore has three credentials. The upstream URL binding
243
+ still prevents blind replay to another endpoint. Credentials saved earlier in the OS keyring or
244
+ under `~/.mcp-proxy/oauth` are not read or migrated: authorize once more. Treat both the
245
+ configuration and the vault as sensitive.
246
+
247
+ `${vault:NAME}` references (`NAME` is 1 to 64 of `A-Z a-z 0-9 . _ -`) work in header values, env
248
+ values and `bearerToken`. They are resolved when Po connects, on a copy of the configuration, so
249
+ config files, the definitions cache and config hashes only ever hold the reference. A reference
250
+ in `url`, `command`, `args` or `cwd` fails the connection. Secrets live in vault namespace
251
+ `mcp.secret` under the same scopes as OAuth credentials, so a repository server never reads a
252
+ user-scope secret. Each secret is bound to where it goes: a URL origin (https, or plain http only
253
+ to this machine, with redirects refused), or a command plus its exact arguments. A changed origin,
254
+ command or argument list reads as missing. A missing secret shows as "needs secret NAME" in the
255
+ session MCP panel, which stores it through the session's owner-only `POST /secrets` route and
256
+ reconnects the server. Compatibility frontends that read the same config files directly get the
257
+ reference left unresolved. Literal values keep working. Any in-process plugin can read every
258
+ vault namespace.
164
259
 
165
260
  The default OAuth callback is `http://127.0.0.1:19876/callback`. Authorization therefore requires the
166
261
  browser and Po runtime to share that loopback network namespace. A remote browser cannot complete
@@ -189,7 +284,7 @@ Maintained by [Agimon](https://agimon.ai/about).
189
284
 
190
285
  ## License
191
286
 
192
- MIT
287
+ Business Source License 1.1: free for personal use, organisations under USD 1M revenue, non-profits and education. See [LICENSE](LICENSE) and https://agimon.ai/licensing.
193
288
 
194
289
  Named routed `src/extensions/` entries declare host contributions and delegate to services. MCP session state and connection behavior live in named service folders, and `src/exports/` exposes reusable public APIs.
195
290
 
@@ -74,6 +74,51 @@ 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
+ secretFields: O(typebox.Type.Array(typebox.Type.String({
97
+ minLength: 1,
98
+ maxLength: 128
99
+ }), { maxItems: 64 }))
100
+ });
101
+ const SecretName = typebox.Type.String({ pattern: "^[A-Za-z0-9._-]{1,64}$" });
102
+ const McpSupplySecretSchema = typebox.Type.Object({
103
+ server: typebox.Type.String({
104
+ minLength: 1,
105
+ maxLength: 160
106
+ }),
107
+ name: SecretName,
108
+ value: typebox.Type.String({
109
+ minLength: 1,
110
+ maxLength: 4096
111
+ })
112
+ });
113
+ const McpSupplySecretResultSchema = typebox.Type.Object({
114
+ server: S,
115
+ name: SecretName
116
+ });
117
+ const McpGlobalServersSchema = typebox.Type.Object({ servers: typebox.Type.Array(typebox.Type.Object({
118
+ name: S,
119
+ kind: literals(["remote", "local"]),
120
+ target: S
121
+ })) });
77
122
  const SessionToolQuery = [{
78
123
  name: "server",
79
124
  in: "query",
@@ -95,76 +140,122 @@ const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
95
140
  version: 1,
96
141
  sockets: [],
97
142
  dynamic: [],
98
- http: [{
99
- id: "mcp.session.tool",
100
- scope: "session",
101
- basePath: "mcp-session",
102
- path: "/tool",
103
- method: "GET",
104
- authentication: "owner",
105
- description: "Read one tool the session reaches through mcp_use: its description, schema, and token cost.",
106
- parameters: SessionToolQuery,
107
- responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpSessionToolSchema)
108
- }, ...["global", "workspace"].flatMap((scope) => [
143
+ http: [
109
144
  {
110
- id: "mcp.catalog",
111
- scope,
112
- basePath: "mcp",
113
- path: "/repository",
145
+ id: "mcp.session.tool",
146
+ scope: "session",
147
+ basePath: "mcp-session",
148
+ path: "/tool",
114
149
  method: "GET",
115
150
  authentication: "owner",
116
- description: "Read the synced MCP repository catalog.",
117
- parameters: RepositoryQuery,
118
- responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpCatalogSchema)
151
+ description: "Read one tool the session reaches through mcp_use: its description, schema, and token cost.",
152
+ parameters: SessionToolQuery,
153
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpSessionToolSchema)
119
154
  },
120
155
  {
121
- id: "mcp.discover",
122
- scope,
123
- basePath: "mcp",
124
- path: "/repository/discover",
156
+ id: "mcp.session.secret",
157
+ scope: "session",
158
+ basePath: "mcp-session",
159
+ path: "/secrets",
125
160
  method: "POST",
126
161
  authentication: "owner",
127
- description: "Discover repository MCP servers.",
162
+ description: "Store a ${vault:NAME} secret this session reported missing, then reconnect its server.",
128
163
  body: {
129
164
  required: true,
130
165
  contentType: "application/json",
131
- schema: typebox.Type.Object({ repositoryId: RepositoryId })
166
+ schema: McpSupplySecretSchema
132
167
  },
133
- responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpCatalogSchema)
168
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpSupplySecretResultSchema)
134
169
  },
135
- {
136
- id: "mcp.authorize",
137
- scope,
138
- basePath: "mcp",
139
- path: "/repository/authorize",
140
- method: "POST",
141
- authentication: "owner",
142
- description: "Start MCP authorization.",
143
- body: {
144
- required: true,
145
- contentType: "application/json",
146
- schema: typebox.Type.Object({
147
- repositoryId: RepositoryId,
148
- serverName: typebox.Type.String({
149
- minLength: 1,
150
- maxLength: 160
170
+ ...["global", "workspace"].flatMap((scope) => [
171
+ {
172
+ id: "mcp.catalog",
173
+ scope,
174
+ basePath: "mcp",
175
+ path: "/repository",
176
+ method: "GET",
177
+ authentication: "owner",
178
+ description: "Read the synced MCP repository catalog.",
179
+ parameters: RepositoryQuery,
180
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpCatalogSchema)
181
+ },
182
+ {
183
+ id: "mcp.discover",
184
+ scope,
185
+ basePath: "mcp",
186
+ path: "/repository/discover",
187
+ method: "POST",
188
+ authentication: "owner",
189
+ description: "Discover repository MCP servers.",
190
+ body: {
191
+ required: true,
192
+ contentType: "application/json",
193
+ schema: typebox.Type.Object({ repositoryId: RepositoryId })
194
+ },
195
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpCatalogSchema)
196
+ },
197
+ {
198
+ id: "mcp.authorize",
199
+ scope,
200
+ basePath: "mcp",
201
+ path: "/repository/authorize",
202
+ method: "POST",
203
+ authentication: "owner",
204
+ description: "Start MCP authorization.",
205
+ body: {
206
+ required: true,
207
+ contentType: "application/json",
208
+ schema: typebox.Type.Object({
209
+ repositoryId: RepositoryId,
210
+ serverName: typebox.Type.String({
211
+ minLength: 1,
212
+ maxLength: 160
213
+ })
151
214
  })
152
- })
215
+ },
216
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpAuthorizationSchema, 202)
153
217
  },
154
- responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpAuthorizationSchema, 202)
155
- },
156
- ...["GET", "DELETE"].map((method) => ({
157
- id: `mcp.authorization.${method}`,
158
- scope,
159
- basePath: "mcp",
160
- path: "/repository/authorize/{flowId}",
161
- method,
162
- authentication: "owner",
163
- description: method === "GET" ? "Read an authorization flow." : "Cancel an authorization flow.",
164
- parameters: RepositoryQuery,
165
- responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpAuthorizationSchema)
166
- }))
167
- ])]
218
+ {
219
+ id: "mcp.server.add",
220
+ scope,
221
+ basePath: "mcp",
222
+ path: "/servers",
223
+ method: "POST",
224
+ authentication: "owner",
225
+ description: "Add one MCP server to the repository's .mcp.json or the person's own config.",
226
+ body: {
227
+ required: true,
228
+ contentType: "application/json",
229
+ schema: McpAddServerSchema
230
+ },
231
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(typebox.Type.Object({
232
+ scope: literals(["repository", "global"]),
233
+ name: S
234
+ }), 201)
235
+ },
236
+ {
237
+ id: "mcp.servers.global",
238
+ scope,
239
+ basePath: "mcp",
240
+ path: "/servers/global",
241
+ method: "GET",
242
+ authentication: "owner",
243
+ description: "List the servers in the person's own MCP config, without headers or environment.",
244
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpGlobalServersSchema)
245
+ },
246
+ ...["GET", "DELETE"].map((method) => ({
247
+ id: `mcp.authorization.${method}`,
248
+ scope,
249
+ basePath: "mcp",
250
+ path: "/repository/authorize/{flowId}",
251
+ method,
252
+ authentication: "owner",
253
+ description: method === "GET" ? "Read an authorization flow." : "Cancel an authorization flow.",
254
+ parameters: RepositoryQuery,
255
+ responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpAuthorizationSchema)
256
+ }))
257
+ ])
258
+ ]
168
259
  });
169
260
  //#endregion
170
261
  //#region src/schemas/mcpApps.ts