pilotswarm 0.5.12 → 0.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +230 -7
- package/mcp/README.md +13 -1
- package/mcp/dist/src/context.d.ts +13 -0
- package/mcp/dist/src/context.d.ts.map +1 -1
- package/mcp/dist/src/context.js +20 -0
- package/mcp/dist/src/context.js.map +1 -1
- package/mcp/dist/src/tools/capabilities.d.ts +3 -0
- package/mcp/dist/src/tools/capabilities.d.ts.map +1 -1
- package/mcp/dist/src/tools/capabilities.js +8 -0
- package/mcp/dist/src/tools/capabilities.js.map +1 -1
- package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
- package/mcp/dist/src/tools/sessions.js +114 -0
- package/mcp/dist/src/tools/sessions.js.map +1 -1
- package/package.json +3 -2
- package/tui/src/app.js +19 -2
- package/tui/src/auth/cli.js +13 -0
- package/tui/src/node-sdk-transport.js +53 -8
- package/tui/tui-splash-mobile.txt +5 -7
- package/tui/tui-splash.txt +13 -9
- package/ui/core/src/commands.js +2 -0
- package/ui/core/src/controller.js +275 -6
- package/ui/core/src/history.js +19 -1
- package/ui/core/src/reducer.js +4 -0
- package/ui/core/src/selectors.js +139 -14
- package/ui/core/src/themes/helpers.js +4 -0
- package/ui/react/src/components.js +95 -6
- package/ui/react/src/web-app.js +555 -117
- package/web/api/router.js +7 -6
- package/web/api/ws.js +9 -0
- package/web/auth/index.js +5 -0
- package/web/auth/providers/dev.js +119 -0
- package/web/authz.js +142 -0
- package/web/dist/assets/index-BnxC8cNG.js +24 -0
- package/web/dist/assets/{index-oldX95Tp.css → index-Bx6KHIaj.css} +1 -1
- package/web/dist/assets/pilotswarm-NE7H63ha.js +90 -0
- package/web/dist/assets/react-l0sNRNKZ.js +1 -0
- package/web/dist/index.html +3 -4
- package/web/runtime.js +453 -9
- package/web/server.js +2 -2
- package/web/dist/assets/index-CJJRJUex.js +0 -24
- package/web/dist/assets/pilotswarm-DRs6o-lA.js +0 -90
- package/web/dist/assets/react-C9iQPS2h.js +0 -1
package/README.md
CHANGED
|
@@ -7,22 +7,242 @@ surface of a [PilotSwarm](https://github.com/affandar/pilotswarm) deployment:
|
|
|
7
7
|
|---|---|
|
|
8
8
|
| `pilotswarm` | Terminal UI. `pilotswarm remote --api-url <portal-url>` attaches to any deployment (auto Entra sign-in); `pilotswarm local` runs an embedded dev stack. `pilotswarm-cli` is an alias. |
|
|
9
9
|
| `pilotswarm-web` | The portal server: hosts the browser UI **and** the deployment's Web API (`/api/v1` + `/api/v1/ws`) — the single integration surface every client rides. |
|
|
10
|
-
| `pilotswarm-mcp` | MCP server exposing PilotSwarm sessions/facts/models to Claude Desktop, Cursor, or any MCP client.
|
|
10
|
+
| `pilotswarm-mcp` | MCP server exposing PilotSwarm sessions/facts/models to Claude Code, Claude Desktop, Copilot CLI, VS Code, Cursor, or any MCP client. |
|
|
11
|
+
|
|
12
|
+
Requires **Node 24+**. Everything below assumes you already have a deployment's
|
|
13
|
+
portal URL — that URL is the only thing you need to configure.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
### 1. Install
|
|
11
20
|
|
|
12
21
|
```bash
|
|
13
22
|
npm install -g pilotswarm
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
(Or skip the install and prefix every command with `npx -p pilotswarm`.)
|
|
26
|
+
|
|
27
|
+
### 2. Sign in to a deployment
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pilotswarm auth login --api-url https://portal.example.com
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This opens your browser for Entra sign-in and caches the token under
|
|
34
|
+
`~/.config/pilotswarm/auth/<origin>.json`. **Every surface in this package —
|
|
35
|
+
the TUI and the MCP server — reads that same cache**, so you sign in once per
|
|
36
|
+
deployment, not once per client.
|
|
14
37
|
|
|
15
|
-
|
|
38
|
+
If the deployment has auth disabled, the command simply tells you so and there
|
|
39
|
+
is nothing to do.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pilotswarm auth status --api-url https://portal.example.com # who am I, is the token still good
|
|
43
|
+
pilotswarm auth logout --api-url https://portal.example.com # drop cached tokens for that origin
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
On a headless box (no browser), add `--device-code` to use the device-code flow
|
|
47
|
+
instead — but note many corporate tenants block device code via Conditional
|
|
48
|
+
Access.
|
|
49
|
+
|
|
50
|
+
### 3. Run the TUI
|
|
51
|
+
|
|
52
|
+
```bash
|
|
16
53
|
pilotswarm remote --api-url https://portal.example.com
|
|
54
|
+
```
|
|
17
55
|
|
|
18
|
-
|
|
19
|
-
pilotswarm
|
|
56
|
+
The `remote` positional is required — `--api-url` without it is an error,
|
|
57
|
+
because bare `pilotswarm` means *local* mode. You can drop the flag entirely by
|
|
58
|
+
setting `PILOTSWARM_API_URL`, or by putting it in a `.env.remote` file next to
|
|
59
|
+
you (remote mode auto-loads `.env.remote`; local mode auto-loads `.env`):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
export PILOTSWARM_API_URL=https://portal.example.com
|
|
63
|
+
pilotswarm remote
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Step 2 is optional in practice: the TUI runs the same sign-in lazily on start
|
|
67
|
+
if no cached token is found. Running `auth login` first just gets the browser
|
|
68
|
+
dance out of the way before the full-screen UI takes over your terminal, and it
|
|
69
|
+
is what makes the MCP servers below work without any further setup.
|
|
70
|
+
|
|
71
|
+
Useful TUI flags: `-m, --model <name>` (initial model), `-p, --plugin <dir>`
|
|
72
|
+
(plugin directory), `-e, --env <file>` (env file), `-h, --help`.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Connect your AI assistant (MCP)
|
|
77
|
+
|
|
78
|
+
`pilotswarm-mcp` is a local, stdio MCP server: your assistant spawns it as a
|
|
79
|
+
child process, and it calls the deployment's Web API **as you**, reusing the
|
|
80
|
+
token cached by `pilotswarm auth login`. Nothing extra is deployed, and no
|
|
81
|
+
secret goes into the config file — just the URL.
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
MCP host (Claude Code / Claude Desktop / Copilot CLI / VS Code)
|
|
85
|
+
└─ spawns → pilotswarm-mcp (local, stdio)
|
|
86
|
+
└─ HTTPS → https://portal.example.com/api/v1
|
|
87
|
+
(your identity; your role decides your tool surface)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Your Entra app role gates the surface: admin-only tools (embedder start/stop,
|
|
91
|
+
`facts_admin`, `restart_system_session`, graph-namespace writes) register only
|
|
92
|
+
for admin credentials.
|
|
93
|
+
|
|
94
|
+
On shared deployments, sessions are owner-scoped. Owners can open a whole
|
|
95
|
+
session tree as read/write or grant a named teammate targeted read/write access;
|
|
96
|
+
management, deletion, and sharing remain owner/admin operations. The portal,
|
|
97
|
+
TUI, Web API, WebSocket stream, and MCP server enforce the same rules. See the
|
|
98
|
+
[security and sharing guide](https://github.com/affandar/pilotswarm/blob/main/docs/user-guide/security-and-sharing.md).
|
|
99
|
+
|
|
100
|
+
### Claude Code
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
claude mcp add pilotswarm -- npx -y -p pilotswarm pilotswarm-mcp \
|
|
104
|
+
--api-url https://portal.example.com
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Or check a `.mcp.json` into the project root so your whole team gets it:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"pilotswarm": {
|
|
113
|
+
"type": "stdio",
|
|
114
|
+
"command": "npx",
|
|
115
|
+
"args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
|
|
116
|
+
"--api-url", "https://portal.example.com"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Claude Desktop
|
|
123
|
+
|
|
124
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
125
|
+
or `%APPDATA%\Claude\claude_desktop_config.json` (Windows), then restart the
|
|
126
|
+
app:
|
|
20
127
|
|
|
21
|
-
|
|
22
|
-
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
"pilotswarm": {
|
|
132
|
+
"command": "npx",
|
|
133
|
+
"args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
|
|
134
|
+
"--api-url", "https://portal.example.com"]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
23
138
|
```
|
|
24
139
|
|
|
25
|
-
|
|
140
|
+
### GitHub Copilot CLI
|
|
141
|
+
|
|
142
|
+
Write `.copilot/mcp-config.json` in the repo (or `~/.copilot/mcp-config.json`
|
|
143
|
+
to have it everywhere):
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"mcpServers": {
|
|
148
|
+
"pilotswarm": {
|
|
149
|
+
"type": "stdio",
|
|
150
|
+
"command": "npx",
|
|
151
|
+
"args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
|
|
152
|
+
"--api-url", "https://portal.example.com"]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### VS Code (Copilot)
|
|
159
|
+
|
|
160
|
+
Add `.vscode/mcp.json` to the workspace — note the key is `servers`, not
|
|
161
|
+
`mcpServers`. The server then shows up in agent mode's tool picker:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"servers": {
|
|
166
|
+
"pilotswarm": {
|
|
167
|
+
"type": "stdio",
|
|
168
|
+
"command": "npx",
|
|
169
|
+
"args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
|
|
170
|
+
"--api-url", "https://portal.example.com"]
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Cursor
|
|
177
|
+
|
|
178
|
+
Same shape as Claude Desktop, in `~/.cursor/mcp.json` (or **Settings → MCP**).
|
|
179
|
+
|
|
180
|
+
### Check that it worked
|
|
181
|
+
|
|
182
|
+
Ask your assistant to call `get_capabilities`. You should get back
|
|
183
|
+
`mode: "web"`, your `admin` flag, and the deployment's facts/graph flags. Then
|
|
184
|
+
`list_sessions` for a fleet view, and `create_session` → `send_and_wait` to
|
|
185
|
+
drive one.
|
|
186
|
+
|
|
187
|
+
If it fails to start, run the same command by hand — the error is much easier
|
|
188
|
+
to read outside the MCP host:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npx -y -p pilotswarm pilotswarm-mcp --api-url https://portal.example.com --log-level info
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The usual cause is a missing or expired token: re-run
|
|
195
|
+
`pilotswarm auth login --api-url <url>`.
|
|
196
|
+
|
|
197
|
+
### Non-interactive credentials (CI, service principals, containers)
|
|
198
|
+
|
|
199
|
+
There is no browser to sign in with, so hand the server a bearer token
|
|
200
|
+
directly:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
PILOTSWARM_API_TOKEN=<token> npx -y -p pilotswarm pilotswarm-mcp \
|
|
204
|
+
--api-url https://portal.example.com
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Remote / shared MCP over HTTP
|
|
208
|
+
|
|
209
|
+
For a shared endpoint rather than a per-user child process, run the server with
|
|
210
|
+
the HTTP transport and a bearer key clients must present:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
PILOTSWARM_MCP_KEY=your-secret-key npx -y -p pilotswarm pilotswarm-mcp \
|
|
214
|
+
--transport http --port 3100 --api-url https://portal.example.com
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Clients then point at `http://your-host:3100/mcp` with an
|
|
218
|
+
`Authorization: Bearer ${PILOTSWARM_MCP_KEY}` header. Read the
|
|
219
|
+
[security model](https://github.com/affandar/pilotswarm/blob/main/packages/app/mcp/README.md#security-model)
|
|
220
|
+
before exposing this beyond localhost: the key is shared, and every client
|
|
221
|
+
behind it has the full scope of the deployment.
|
|
222
|
+
|
|
223
|
+
Full tool catalog, resources, and every flag:
|
|
224
|
+
[MCP server README](https://github.com/affandar/pilotswarm/blob/main/packages/app/mcp/README.md).
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Other surfaces
|
|
229
|
+
|
|
230
|
+
**Run everything locally** (embedded workers, no deployment, no auth) — the fast
|
|
231
|
+
way to try PilotSwarm or develop a plugin:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
pilotswarm local # bare `pilotswarm` does the same
|
|
235
|
+
pilotswarm local -p ./plugin -n 4
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Host a portal** — serves the browser UI and the Web API that every client
|
|
239
|
+
above rides on. Needs worker-side env (`DATABASE_URL`, model providers, …):
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
pilotswarm-web --plugin ./plugin
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Library surfaces** (used by the shipped UIs; importable for custom hosts):
|
|
26
246
|
|
|
27
247
|
- `pilotswarm/ui-core` — framework-free UI controller/state/selectors
|
|
28
248
|
- `pilotswarm/ui-react` — the shared React composition (Ink + DOM)
|
|
@@ -33,7 +253,10 @@ Building an app or service instead of a UI? You want
|
|
|
33
253
|
[`pilotswarm-sdk`](https://www.npmjs.com/package/pilotswarm-sdk) — including
|
|
34
254
|
its zero-dependency wire client at `pilotswarm-sdk/api`.
|
|
35
255
|
|
|
256
|
+
---
|
|
257
|
+
|
|
36
258
|
Docs: [Quick Start](https://github.com/affandar/pilotswarm/blob/main/docs/quickstart/docker.md) ·
|
|
37
259
|
[User Guide](https://github.com/affandar/pilotswarm/blob/main/docs/user-guide/README.md) ·
|
|
260
|
+
[MCP Setup](https://github.com/affandar/pilotswarm/blob/main/docs/user-guide/mcp-local-setup.md) ·
|
|
38
261
|
[Web API Reference](https://github.com/affandar/pilotswarm/blob/main/docs/api/reference.md) ·
|
|
39
262
|
[Architecture / Layering](https://github.com/affandar/pilotswarm/blob/main/docs/architecture/layering.md)
|
package/mcp/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Each client below shows both **Stdio** (local, recommended) and **HTTP** (remote
|
|
|
39
39
|
|
|
40
40
|
### GitHub Copilot CLI
|
|
41
41
|
|
|
42
|
-
Add to
|
|
42
|
+
Add to `.copilot/mcp-config.json` (repo-scoped) or `~/.copilot/mcp-config.json` (global):
|
|
43
43
|
|
|
44
44
|
**Stdio (local):**
|
|
45
45
|
|
|
@@ -380,6 +380,12 @@ with `get_capabilities` to see the shape of this server.
|
|
|
380
380
|
| `list_sessions` | Discovery — list all sessions with status, model, agent info, and parent/child relationships; keyset pagination via `limit`/`cursor`/`include_deleted` |
|
|
381
381
|
| `get_session_detail` | Discovery — get detailed info for a session including status, context usage, cron state, and pending questions |
|
|
382
382
|
| `get_session_events` | Discovery — CMS event stream with `after_seq` forward paging, `before_seq` history paging, `event_types` server-side filter, and long-poll support |
|
|
383
|
+
| `get_session_access` | Effective caller access, visibility, relation, and owner for one session tree |
|
|
384
|
+
| `set_session_visibility` | Set `private`, `shared_read`, or `shared_write` on an owned session tree |
|
|
385
|
+
| `grant_session_share` / `revoke_session_share` | Owner/admin targeted read/write grant management |
|
|
386
|
+
| `list_session_shares` | Owner/admin listing of targeted grants on a session tree |
|
|
387
|
+
| `list_known_users` | Bounded member directory used to resolve a grantee; helper only, not an allowlist |
|
|
388
|
+
| `list_authz_audit` | Owner audit for one session or admin fleet-wide authorization audit |
|
|
383
389
|
|
|
384
390
|
### Turn & Queue Control
|
|
385
391
|
|
|
@@ -464,6 +470,12 @@ External clients **cannot** spawn, message, or cancel a sub-agent. Calling a rem
|
|
|
464
470
|
|
|
465
471
|
Top-level session control (`create_session`, `send_message`, `delete_session`, etc.) is unaffected by this boundary — those tools remain on the external surface.
|
|
466
472
|
|
|
473
|
+
Session visibility still applies to every MCP operation. A server running with
|
|
474
|
+
`--api-url` acts as the cached Entra principal from `pilotswarm auth login` (or
|
|
475
|
+
the supplied bearer token): unreadable sessions are absent/not-found, writes
|
|
476
|
+
require owner/admin, `shared_write`, or a targeted write grant, and sharing
|
|
477
|
+
metadata is owner/admin only.
|
|
478
|
+
|
|
467
479
|
### Agent Management
|
|
468
480
|
|
|
469
481
|
| Tool | Description |
|
|
@@ -34,6 +34,19 @@ export interface ServerContext {
|
|
|
34
34
|
* [admin]-tagged tools register iff true.
|
|
35
35
|
*/
|
|
36
36
|
admin: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The caller's normalized role (`admin` | `user` | `anonymous` | null),
|
|
39
|
+
* and the deployment's ownership/visibility posture. Web mode reads these
|
|
40
|
+
* from /auth/me and /bootstrap; direct mode is privileged (`admin`) with
|
|
41
|
+
* enforcement off. Surfaced by get_capabilities so an agent can explain a
|
|
42
|
+
* refusal instead of retrying blindly.
|
|
43
|
+
*/
|
|
44
|
+
role: string | null;
|
|
45
|
+
authz: {
|
|
46
|
+
ownershipEnforced: boolean;
|
|
47
|
+
defaultVisibility: string;
|
|
48
|
+
systemVisibility: string;
|
|
49
|
+
};
|
|
37
50
|
/** True when running over the Web API (`--api-url`); false in direct mode. */
|
|
38
51
|
webMode: boolean;
|
|
39
52
|
models: ModelProviderRegistry | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,0BAA0B,EAQ1B,qBAAqB,EAErB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,0BAA0B,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE;;;;;;OAMG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,0BAA0B,EAQ1B,qBAAqB,EAErB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,0BAA0B,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE;QAAE,iBAAiB,EAAE,OAAO,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE;;;;;;OAMG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiMtF"}
|
package/mcp/dist/src/context.js
CHANGED
|
@@ -8,6 +8,8 @@ export async function createContext(opts) {
|
|
|
8
8
|
let graph = null;
|
|
9
9
|
let api = null;
|
|
10
10
|
let admin = false;
|
|
11
|
+
let ctxRole = null;
|
|
12
|
+
let ctxAuthz = { ownershipEnforced: false, defaultVisibility: "private", systemVisibility: "read" };
|
|
11
13
|
let webAgents = null;
|
|
12
14
|
if (opts.apiUrl) {
|
|
13
15
|
// Web API mode (supported): no database credentials in this process.
|
|
@@ -34,10 +36,25 @@ export async function createContext(opts) {
|
|
|
34
36
|
const me = await api.getAuthContext();
|
|
35
37
|
const role = me?.authorization?.role;
|
|
36
38
|
admin = role === "admin" || role === "anonymous";
|
|
39
|
+
ctxRole = typeof role === "string" ? role : null;
|
|
37
40
|
}
|
|
38
41
|
catch {
|
|
39
42
|
admin = false;
|
|
40
43
|
}
|
|
44
|
+
// Ownership/visibility posture from /bootstrap (security model).
|
|
45
|
+
try {
|
|
46
|
+
const boot = await api.getBootstrap();
|
|
47
|
+
if (boot?.authz && typeof boot.authz === "object") {
|
|
48
|
+
ctxAuthz = {
|
|
49
|
+
ownershipEnforced: Boolean(boot.authz.ownershipEnforced),
|
|
50
|
+
defaultVisibility: String(boot.authz.defaultVisibility || "private"),
|
|
51
|
+
systemVisibility: String(boot.authz.systemVisibility || "read"),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// leave defaults
|
|
57
|
+
}
|
|
41
58
|
// Registered agents: the deployment's creatable-agent catalog is the
|
|
42
59
|
// truth in web mode — local plugin dirs may diverge from what
|
|
43
60
|
// createSessionForAgent will accept.
|
|
@@ -61,6 +78,7 @@ export async function createContext(opts) {
|
|
|
61
78
|
// Direct mode (internal/testing): straight to the datastore. A
|
|
62
79
|
// process holding DATABASE_URL is definitionally privileged.
|
|
63
80
|
admin = true;
|
|
81
|
+
ctxRole = "admin";
|
|
64
82
|
client = new PilotSwarmClient({ store: opts.store });
|
|
65
83
|
await client.start();
|
|
66
84
|
mgmt = new PilotSwarmManagementClient({ store: opts.store });
|
|
@@ -166,6 +184,8 @@ export async function createContext(opts) {
|
|
|
166
184
|
graph,
|
|
167
185
|
api,
|
|
168
186
|
admin,
|
|
187
|
+
role: ctxRole,
|
|
188
|
+
authz: ctxAuthz,
|
|
169
189
|
webMode: Boolean(opts.apiUrl),
|
|
170
190
|
models,
|
|
171
191
|
skills,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,0BAA0B,EAC1B,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAElB,UAAU,EACV,cAAc,GAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,9 @@ import type { ServerContext } from "../context.js";
|
|
|
12
12
|
export declare function buildCapabilities(ctx: ServerContext): {
|
|
13
13
|
mode: string;
|
|
14
14
|
admin: boolean;
|
|
15
|
+
role: string | null;
|
|
16
|
+
ownership_enforced: boolean;
|
|
17
|
+
default_visibility: string;
|
|
15
18
|
facts: {
|
|
16
19
|
search: boolean;
|
|
17
20
|
embedder: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa;;;;;;;;;;;;;;;;EAyBnD;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QA0C5E"}
|
|
@@ -12,6 +12,14 @@ export function buildCapabilities(ctx) {
|
|
|
12
12
|
return {
|
|
13
13
|
mode: ctx.webMode ? "web" : "direct",
|
|
14
14
|
admin: ctx.admin,
|
|
15
|
+
// Ownership/visibility posture (security model): the caller's role and
|
|
16
|
+
// whether the deployment enforces per-user session access. When
|
|
17
|
+
// ownership_enforced is true, list_sessions returns only sessions you
|
|
18
|
+
// can read and a send/read to another user's private session is
|
|
19
|
+
// refused with the reason in the error.
|
|
20
|
+
role: ctx.role ?? null,
|
|
21
|
+
ownership_enforced: ctx.authz?.ownershipEnforced ?? false,
|
|
22
|
+
default_visibility: ctx.authz?.defaultVisibility ?? "private",
|
|
15
23
|
facts: {
|
|
16
24
|
search: Boolean(ctx.enhancedFacts?.capabilities.search),
|
|
17
25
|
embedder: Boolean(ctx.enhancedFacts?.capabilities.embedder),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAkB;IAChD,OAAO;QACH,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;QACpC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE;YACH,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,MAAM,CAAC;YACvD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,QAAQ,CAAC;SAC9D;QACD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB,qEAAqE;QACrE,8BAA8B;QAC9B,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAQ,GAAG,CAAC,KAAa,CAAC,mBAAmB,KAAK,UAAU,CAAC;QACpG,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAQ,GAAG,CAAC,KAAa,CAAC,UAAU,KAAK,UAAU,CAAC;QACtF,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO;QACrD,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;QACjC,iBAAiB,EAAE,GAAG,CAAC,gBAAgB,CAAC,MAAM;KACjD,CAAC;AACN,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,GAAkB;IACzE,MAAM,CAAC,YAAY,CACf,kBAAkB,EAClB;QACI,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACP,oGAAoG;cAClG,sGAAsG;cACtG,qGAAqG;cACrG,gDAAgD;QACtD,WAAW,EAAE,EAAE;KAClB,EACD,cAAc,CAAC,KAAK,IAAI,EAAE;QACtB,gEAAgE;QAChE,iEAAiE;QACjE,+DAA+D;QAC/D,kEAAkE;QAClE,iDAAiD;QACjD,IAAI,eAAe,GAAkB,IAAI,CAAC;QAC1C,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,IAAI,CAAC;gBACD,MAAM,CAAC,GAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBACpD,eAAe,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;YACnF,CAAC;YAAC,MAAM,CAAC;gBACL,eAAe,GAAG,IAAI,CAAC;YAC3B,CAAC;QACL,CAAC;QACD,IAAI,YAAY,GAAkB,IAAI,CAAC;QACvC,IAAI,CAAC;YACD,YAAY,GAAG,GAAG,CAAC,MAAM;gBACrB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC;gBACnC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACL,YAAY,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,OAAO,UAAU,CAAC;YACd,GAAG,iBAAiB,CAAC,GAAG,CAAC;YACzB,gBAAgB,EAAE,eAAe;YACjC,aAAa,EAAE,YAAY;SAC9B,CAAC,CAAC;IACP,CAAC,CAAC,CACL,CAAC;AACN,CAAC"}
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/tools/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAOnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/tools/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAOnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QAmzBzE"}
|
|
@@ -334,6 +334,120 @@ export function registerSessionTools(server, ctx) {
|
|
|
334
334
|
};
|
|
335
335
|
}
|
|
336
336
|
});
|
|
337
|
+
// ── Session sharing (security model) ─────────────────────────────
|
|
338
|
+
// Owner-or-admin operations; the server enforces and returns the authz
|
|
339
|
+
// reason in the error when refused. Registered for all callers.
|
|
340
|
+
// Web mode: dispatch through the API (server enforces). Direct mode
|
|
341
|
+
// (admin/test-only): call the management client with POSITIONAL args —
|
|
342
|
+
// its signatures are (sessionId, …), not a single params object.
|
|
343
|
+
const callShare = async (op, params, positional) => {
|
|
344
|
+
if (ctx.api)
|
|
345
|
+
return ctx.api.call(op, params);
|
|
346
|
+
return ctx.mgmt[op]?.(...positional);
|
|
347
|
+
};
|
|
348
|
+
const shareError = (err, session_id) => ({
|
|
349
|
+
content: [{ type: "text", text: JSON.stringify({ error: err instanceof Error ? err.message : String(err), session_id }) }],
|
|
350
|
+
isError: true,
|
|
351
|
+
});
|
|
352
|
+
server.registerTool("set_session_visibility", {
|
|
353
|
+
title: "Set Session Visibility",
|
|
354
|
+
description: "Set the sharing level of a session's tree (owner or admin only): "
|
|
355
|
+
+ "'private' (only owner + admins), 'shared_read' (every user can view), "
|
|
356
|
+
+ "'shared_write' (every user can view and send). Applies to the whole sub-agent tree.",
|
|
357
|
+
inputSchema: {
|
|
358
|
+
session_id: sessionIdShape().describe("Session whose tree visibility to set"),
|
|
359
|
+
visibility: z.enum(["private", "shared_read", "shared_write"]).describe("New visibility level"),
|
|
360
|
+
},
|
|
361
|
+
}, async ({ session_id, visibility }) => {
|
|
362
|
+
try {
|
|
363
|
+
await callShare("setSessionVisibility", { sessionId: session_id, visibility }, [session_id, visibility]);
|
|
364
|
+
return { content: [{ type: "text", text: JSON.stringify({ session_id, visibility }) }] };
|
|
365
|
+
}
|
|
366
|
+
catch (err) {
|
|
367
|
+
return shareError(err, session_id);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
server.registerTool("grant_session_share", {
|
|
371
|
+
title: "Grant Session Share",
|
|
372
|
+
description: "Grant a specific user read or write access to a session's tree (owner or admin only). "
|
|
373
|
+
+ "Refused with the reason in the error if you are not the owner/admin, or on a system session. "
|
|
374
|
+
+ "The grantee does NOT need to have signed in yet: list_known_users is only a lookup helper. "
|
|
375
|
+
+ "If the grantee's stable subject is unknown, pass their EMAIL as the subject — the grant "
|
|
376
|
+
+ "binds automatically the first time they sign in.",
|
|
377
|
+
inputSchema: {
|
|
378
|
+
session_id: sessionIdShape().describe("Session whose tree to share"),
|
|
379
|
+
provider: z.string().describe("Grantee auth provider (e.g. 'entra', 'dev')"),
|
|
380
|
+
subject: z.string().describe("Grantee stable subject id, or their email if they have never signed in"),
|
|
381
|
+
access: z.enum(["read", "write"]).describe("Access level to grant"),
|
|
382
|
+
email: z.string().nullish().describe("Optional grantee email for display"),
|
|
383
|
+
display_name: z.string().nullish().describe("Optional grantee display name"),
|
|
384
|
+
},
|
|
385
|
+
}, async ({ session_id, provider, subject, access, email, display_name }) => {
|
|
386
|
+
try {
|
|
387
|
+
const grantee = { provider, subject, email: email ?? null, displayName: display_name ?? null };
|
|
388
|
+
await callShare("grantSessionShare", { sessionId: session_id, user: grantee, access }, [session_id, grantee, access]);
|
|
389
|
+
return { content: [{ type: "text", text: JSON.stringify({ session_id, granted: { provider, subject, access } }) }] };
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
return shareError(err, session_id);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
server.registerTool("revoke_session_share", {
|
|
396
|
+
title: "Revoke Session Share",
|
|
397
|
+
description: "Revoke a user's targeted share on a session's tree (owner or admin only).",
|
|
398
|
+
inputSchema: {
|
|
399
|
+
session_id: sessionIdShape().describe("Session whose share to revoke"),
|
|
400
|
+
provider: z.string().describe("Grantee auth provider"),
|
|
401
|
+
subject: z.string().describe("Grantee stable subject id"),
|
|
402
|
+
},
|
|
403
|
+
}, async ({ session_id, provider, subject }) => {
|
|
404
|
+
try {
|
|
405
|
+
await callShare("revokeSessionShare", { sessionId: session_id, user: { provider, subject } }, [session_id, { provider, subject }]);
|
|
406
|
+
return { content: [{ type: "text", text: JSON.stringify({ session_id, revoked: { provider, subject } }) }] };
|
|
407
|
+
}
|
|
408
|
+
catch (err) {
|
|
409
|
+
return shareError(err, session_id);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
server.registerTool("list_session_shares", {
|
|
413
|
+
title: "List Session Shares",
|
|
414
|
+
description: "List the targeted user grants on a session's tree (owner or admin only).",
|
|
415
|
+
inputSchema: {
|
|
416
|
+
session_id: sessionIdShape().describe("Session whose shares to list"),
|
|
417
|
+
},
|
|
418
|
+
}, async ({ session_id }) => {
|
|
419
|
+
try {
|
|
420
|
+
const shares = await callShare("listSessionShares", { sessionId: session_id }, [session_id]);
|
|
421
|
+
return { content: [{ type: "text", text: JSON.stringify({ session_id, shares: shares ?? [] }) }] };
|
|
422
|
+
}
|
|
423
|
+
catch (err) {
|
|
424
|
+
return shareError(err, session_id);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
server.registerTool("list_known_users", {
|
|
428
|
+
title: "List Known Users",
|
|
429
|
+
description: "Directory of users who have signed in at least once (provider, subject, email, display name) — "
|
|
430
|
+
+ "a HELPER for resolving a grantee's stable subject by name/email before grant_session_share. "
|
|
431
|
+
+ "It is NOT an allowlist: grants may target someone who is not in this directory — even someone "
|
|
432
|
+
+ "who has never signed in. For such users pass their email as the subject; the grant binds "
|
|
433
|
+
+ "automatically when they first sign in.",
|
|
434
|
+
inputSchema: {
|
|
435
|
+
limit: z.number().int().min(1).max(2000).nullish().describe("Max entries to return (default 500)"),
|
|
436
|
+
},
|
|
437
|
+
}, async ({ limit }) => {
|
|
438
|
+
try {
|
|
439
|
+
const users = ctx.api
|
|
440
|
+
? await ctx.api.call("listKnownUsers", limit != null ? { limit } : {})
|
|
441
|
+
: await ctx.mgmt.listKnownUsers?.(limit != null ? { limit } : undefined);
|
|
442
|
+
return { content: [{ type: "text", text: JSON.stringify({ users: users ?? [] }) }] };
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
return {
|
|
446
|
+
content: [{ type: "text", text: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }) }],
|
|
447
|
+
isError: true,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
});
|
|
337
451
|
// 7. list_sessions — List all sessions with status
|
|
338
452
|
server.registerTool("list_sessions", {
|
|
339
453
|
title: "List Sessions",
|