@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.
- package/LICENSE +149 -21
- package/README.md +111 -16
- package/dist/apiContracts.cjs +147 -56
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts.map +1 -1
- package/dist/apiContracts.mjs +147 -56
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/extensions/mcp.cjs +29 -13
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.mjs +29 -13
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/native.mjs +1500 -0
- package/dist/extensions/native.mjs.map +1 -0
- package/dist/extensions/server.cjs +3758 -2564
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +3762 -2567
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +874 -180
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/index-weSvnCeI.d.mts +27 -0
- package/dist/index-weSvnCeI.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts +8 -33
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/localServers.cjs +4 -0
- package/dist/localServers.d.mts +39 -0
- package/dist/localServers.d.mts.map +1 -0
- package/dist/localServers.mjs +1 -0
- package/dist/{mcpCatalog-BHoE4gfz.cjs → mcpCatalog-Be0BcPOu.cjs} +161 -47
- package/dist/mcpCatalog-Be0BcPOu.cjs.map +1 -0
- package/dist/{mcpCatalog-Bp-mLZM1.mjs → mcpCatalog-rxpMjGIW.mjs} +140 -44
- package/dist/mcpCatalog-rxpMjGIW.mjs.map +1 -0
- package/dist/{mcpConfig-lHsIQ2fZ.d.mts → mcpConfig-DrGHS_aV.d.mts} +4 -2
- package/dist/{mcpConfig-lHsIQ2fZ.d.mts.map → mcpConfig-DrGHS_aV.d.mts.map} +1 -1
- package/dist/projection-BH-vn29y.mjs +56 -0
- package/dist/projection-BH-vn29y.mjs.map +1 -0
- package/dist/projection-DBpXsw0W.cjs +64 -0
- package/dist/projection-DBpXsw0W.cjs.map +1 -0
- package/dist/projection.cjs +1 -1
- package/dist/projection.d.mts +8 -2
- package/dist/projection.d.mts.map +1 -1
- package/dist/projection.mjs +1 -1
- package/dist/sessionServers-aDZVqS6t.mjs +182 -0
- package/dist/sessionServers-aDZVqS6t.mjs.map +1 -0
- package/dist/sessionServers-xi5PL_GP.cjs +199 -0
- package/dist/sessionServers-xi5PL_GP.cjs.map +1 -0
- package/llms.txt +2 -1
- package/package.json +39 -18
- package/src/prompts/codemode-how-to-mcp/SKILL.md +46 -0
- package/src/prompts/{po-use-mcp → help-how-to-mcp}/SKILL.md +41 -10
- package/dist/mcpCatalog-BHoE4gfz.cjs.map +0 -1
- package/dist/mcpCatalog-Bp-mLZM1.mjs.map +0 -1
- package/dist/projection-gyAA2jRB.mjs +0 -43
- package/dist/projection-gyAA2jRB.mjs.map +0 -1
- package/dist/projection-w3XxXmVi.cjs +0 -51
- package/dist/projection-w3XxXmVi.cjs.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,149 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
85
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
|
117
|
-
negotiation, private result capture
|
|
118
|
-
cancellation. Model-facing output remains
|
|
119
|
-
|
|
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
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
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
|
|
package/dist/apiContracts.cjs
CHANGED
|
@@ -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.
|
|
111
|
-
scope,
|
|
112
|
-
basePath: "mcp",
|
|
113
|
-
path: "/
|
|
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
|
|
117
|
-
parameters:
|
|
118
|
-
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(
|
|
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.
|
|
122
|
-
scope,
|
|
123
|
-
basePath: "mcp",
|
|
124
|
-
path: "/
|
|
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: "
|
|
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:
|
|
166
|
+
schema: McpSupplySecretSchema
|
|
132
167
|
},
|
|
133
|
-
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(
|
|
168
|
+
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(McpSupplySecretResultSchema)
|
|
134
169
|
},
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|