@ikuma.cloud/pix-mcp 0.0.7 → 0.0.9
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 +121 -39
- package/mcp.schema.json +1 -1
- package/package.json +6 -2
- package/src/catalog.ts +1 -1
- package/src/client.ts +335 -9
- package/src/command.ts +69 -0
- package/src/config.ts +1 -1
- package/src/index.ts +416 -23
- package/src/output.ts +85 -5
- package/src/prompt-picker.ts +120 -0
- package/src/prompts.ts +41 -77
- package/src/resource-picker.ts +157 -0
- package/src/resources.ts +769 -0
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @ikuma.cloud/pix-mcp
|
|
2
2
|
|
|
3
3
|
A small Pi MCP adapter: discover tools, load their schemas on demand, call
|
|
4
|
-
those tools natively, and
|
|
5
|
-
model-provider-specific API is required.
|
|
4
|
+
those tools natively, and use user-selected MCP prompts and resources. No
|
|
5
|
+
scripting engine or model-provider-specific API is required.
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
@@ -13,9 +13,18 @@ pi -e /absolute/path/to/pix/packages/pix-mcp
|
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Disable any other MCP adapter that would collide with the `mcp` tool,
|
|
16
|
-
`/mcp-prompt`
|
|
17
|
-
enabled. Review the configuration and automatic
|
|
18
|
-
connecting servers.
|
|
16
|
+
`/mcp-prompt` or `/mcp-resource` commands, or flags, but keep any
|
|
17
|
+
permission-control extensions enabled. Review the configuration and automatic
|
|
18
|
+
startup behavior below before connecting servers.
|
|
19
|
+
|
|
20
|
+
From this repository, the included configuration launches the pinned MCP
|
|
21
|
+
Everything server for manual prompt and resource testing:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
mise run mcp:dev --mcp-config pix-mcp-test.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Review the file first; `npx` downloads and runs the pinned package.
|
|
19
28
|
|
|
20
29
|
## Configuration
|
|
21
30
|
|
|
@@ -83,7 +92,7 @@ URLs, and HTTP headers.
|
|
|
83
92
|
| `type` | `stdio`, `http`, or `streamable-http` (alias of `http`); only stdio is inferred, when `command` is present |
|
|
84
93
|
| `command`, `args`, `env` | Stdio only; executable and argument array, not a shell command |
|
|
85
94
|
| `url`, `headers` | Streamable HTTP only; explicit `type` required; no legacy SSE fallback or redirect following |
|
|
86
|
-
| `timeout` | Hard deadline for each tool invocation
|
|
95
|
+
| `timeout` | Hard deadline for each tool invocation, prompt retrieval, or resource read, in milliseconds; default 30000 |
|
|
87
96
|
| `cwd` | Stdio extension: working directory relative to the config directory |
|
|
88
97
|
| `description` | Discovery extension: optional summary, truncated to 500 characters |
|
|
89
98
|
| `startupTimeoutMs` | pix extension: complete connection/initialization handshake deadline; default 30000 |
|
|
@@ -117,9 +126,9 @@ as failed connections. Correct the file and reload Pi to retry.
|
|
|
117
126
|
|
|
118
127
|
All three deadline fields accept integers from 1 through 2,147,483,647 milliseconds
|
|
119
128
|
(Node's timer-safe maximum). Each defaults independently to 30 seconds. Setting
|
|
120
|
-
`"timeout": 960000` permits a 16-minute tool call
|
|
121
|
-
lengthening startup or discovery. The invocation clock starts after
|
|
122
|
-
startup; progress does not reset it. Catalog deadlines cover all pages of one
|
|
129
|
+
`"timeout": 960000` permits a 16-minute tool call, prompt retrieval, or resource
|
|
130
|
+
read without lengthening startup or discovery. The invocation clock starts after
|
|
131
|
+
connection startup; progress does not reset it. Catalog deadlines cover all pages of one
|
|
123
132
|
snapshot; a subsequent list-change refresh starts a new deadline.
|
|
124
133
|
|
|
125
134
|
HTTP deadlines cover response headers and bodies, including JSON and SSE. MCP
|
|
@@ -130,8 +139,9 @@ Upstream proxies and servers may still impose their own limits.
|
|
|
130
139
|
|
|
131
140
|
**Breaking changes from 0.0.1:**
|
|
132
141
|
|
|
133
|
-
- Replace `timeoutMs` with `timeout` for tool calls
|
|
134
|
-
`catalogTimeoutMs` separately if
|
|
142
|
+
- Replace `timeoutMs` with `timeout` for tool calls, prompt retrievals, and
|
|
143
|
+
resource reads. Set `startupTimeoutMs` and `catalogTimeoutMs` separately if
|
|
144
|
+
their defaults are unsuitable. The removed
|
|
135
145
|
field produces a migration diagnostic; it is not an alias.
|
|
136
146
|
- Add `"type": "http"` to remote entries that previously specified only `url`.
|
|
137
147
|
- Connection strings now expand environment references beyond `env` and `headers`.
|
|
@@ -159,10 +169,9 @@ credentials; debug a failing server separately in a trusted environment.
|
|
|
159
169
|
## Discovery and execution
|
|
160
170
|
|
|
161
171
|
At session startup, the adapter connects to enabled servers and fetches their
|
|
162
|
-
advertised paginated tool and
|
|
163
|
-
connection, or discovery failure does not hide healthy
|
|
164
|
-
servers.
|
|
165
|
-
Full schemas stay out of model context until selected. **Schema exposure is lazy;
|
|
172
|
+
advertised paginated tool, prompt, resource, and resource-template catalogs. A
|
|
173
|
+
server's configuration, connection, or discovery failure does not hide healthy
|
|
174
|
+
features from other servers. Full schemas stay out of model context until selected. **Schema exposure is lazy;
|
|
166
175
|
initial connections and metadata discovery are not.**
|
|
167
176
|
|
|
168
177
|
The agent uses the `mcp` tool:
|
|
@@ -198,8 +207,8 @@ exceptions, schema contents, invalid tool names, and dialect URLs are not expose
|
|
|
198
207
|
|
|
199
208
|
An unsupported output schema still fails that server's tool discovery rather than
|
|
200
209
|
producing a per-tool rejection. Losing an established HTTP notification stream
|
|
201
|
-
withdraws tool and
|
|
202
|
-
servers that decline the optional stream with HTTP 405 remain usable. Reload Pi
|
|
210
|
+
withdraws tool, prompt, and resource catalogs rather than silently keeping stale
|
|
211
|
+
metadata; servers that decline the optional stream with HTTP 405 remain usable. Reload Pi
|
|
203
212
|
to reconnect a failed server or reread configuration.
|
|
204
213
|
|
|
205
214
|
Pi handles provider compatibility. Some providers support transcript-anchored
|
|
@@ -266,17 +275,28 @@ the stable `/mcp-prompt` command so catalog changes do not leave stale slash
|
|
|
266
275
|
commands behind:
|
|
267
276
|
|
|
268
277
|
```text
|
|
278
|
+
/mcp-prompt
|
|
269
279
|
/mcp-prompt list [server]
|
|
270
280
|
/mcp-prompt run <server> <prompt> [name=value ...]
|
|
271
281
|
```
|
|
272
282
|
|
|
283
|
+
In TUI mode, `/mcp-prompt` without arguments opens a native prompt selector
|
|
284
|
+
that shows the focused prompt's title and description, followed by native input
|
|
285
|
+
dialogs. Required and optional arguments are requested in declaration order;
|
|
286
|
+
leaving an optional input empty omits it. The rendered prompt is placed in Pi's
|
|
287
|
+
editor so you can review or modify it before sending. Image blocks are stored in
|
|
288
|
+
private temporary files and inserted as `@` references. Escape cancels without
|
|
289
|
+
retrieving the prompt. The explicit `list` and `run` forms remain available in
|
|
290
|
+
every mode; `run` submits immediately and can pass an intentional empty value as
|
|
291
|
+
`name=`.
|
|
292
|
+
|
|
273
293
|
Arguments use shell-style quoting. Positional values map to the prompt's declared
|
|
274
|
-
argument order; `name=value` selects a declared argument explicitly. Quote or
|
|
275
|
-
an equals sign in a positional value (for example, `"a=b"` or `a\=b`) to
|
|
276
|
-
assignment parsing. Argument names containing `=` work when the name is quoted,
|
|
294
|
+
argument order; `name=value` selects a declared argument explicitly. Quote or
|
|
295
|
+
escape an equals sign in a positional value (for example, `"a=b"` or `a\=b`) to
|
|
296
|
+
avoid assignment parsing. Argument names containing `=` work when the name is quoted,
|
|
277
297
|
as in `"x=y"=value`. The adapter checks required arguments before sending
|
|
278
|
-
`prompts/get`. Prompt retrieval uses the
|
|
279
|
-
|
|
298
|
+
`prompts/get`. Prompt retrieval uses the server's `timeout`; prompt discovery uses
|
|
299
|
+
`catalogTimeoutMs` and follows pagination.
|
|
280
300
|
Prompt list-change notifications atomically replace that server's prompt catalog.
|
|
281
301
|
Duplicate or invalid prompt metadata fails only that server's prompt catalog. A
|
|
282
302
|
prompt discovery failure does not hide healthy tools, and a tool discovery failure
|
|
@@ -294,6 +314,60 @@ Prompt metadata and bodies are untrusted server content. Catalog metadata stays
|
|
|
294
314
|
in command UI; a prompt body enters model context only after the user explicitly
|
|
295
315
|
runs it. Review configured servers and selected prompts accordingly.
|
|
296
316
|
|
|
317
|
+
## Resources
|
|
318
|
+
|
|
319
|
+
MCP resources are application-controlled and are not exposed as model-callable
|
|
320
|
+
tools. Use the stable `/mcp-resource` command:
|
|
321
|
+
|
|
322
|
+
```text
|
|
323
|
+
/mcp-resource
|
|
324
|
+
/mcp-resource list [server]
|
|
325
|
+
/mcp-resource read <server> <uri-or-template> [name=value ...]
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
In TUI mode, the bare command opens a native selector for direct resources and
|
|
329
|
+
resource templates. Focusing an item shows its bounded metadata but does not read
|
|
330
|
+
it. Selecting a template requests every variable in declaration order and expands
|
|
331
|
+
it according to [RFC 6570 Level 4](https://www.rfc-editor.org/rfc/rfc6570).
|
|
332
|
+
Escape cancels without reading. The result is placed in Pi's editor for review;
|
|
333
|
+
image contents use private temporary `@` references that are removed at session
|
|
334
|
+
shutdown.
|
|
335
|
+
|
|
336
|
+
The explicit `list` and `read` forms work in every mode. `read` immediately sends
|
|
337
|
+
the resource contents as a user message and starts or queues a model turn; Pi
|
|
338
|
+
commands do not provide a raw structured-result channel. A concrete URI need not
|
|
339
|
+
appear in the catalog, allowing known or optional-template URIs to be read
|
|
340
|
+
explicitly. Arguments are accepted only when the target exactly matches a
|
|
341
|
+
cataloged template. Template variables use the same shell-style positional and
|
|
342
|
+
`name=value` syntax as prompt arguments. MCP does not mark template variables as
|
|
343
|
+
required: omitted variables use RFC 6570's undefined-variable behavior, leaving a
|
|
344
|
+
picker input empty omits it, and explicit `name=` supplies an intentional empty
|
|
345
|
+
value. The expanded result must still be a valid absolute URI. MCP completion
|
|
346
|
+
requests for variable values are not supported.
|
|
347
|
+
|
|
348
|
+
Each returned content item gets a server/URI source marker because one read can
|
|
349
|
+
return multiple resources. Text and supported images are retained in order.
|
|
350
|
+
Non-image blobs and oversized or unsupported content are omitted from the preview
|
|
351
|
+
and preserved in the private full-result artifact. Unsafe terminal and
|
|
352
|
+
bidirectional controls are removed from displayed or editable text; the original
|
|
353
|
+
content remains in the artifact when sanitization changes it, while `_meta` is
|
|
354
|
+
excluded.
|
|
355
|
+
|
|
356
|
+
Direct resources and templates are discovered independently from tools and
|
|
357
|
+
prompts, but committed together as one atomic per-server resource snapshot.
|
|
358
|
+
Resource list-change notifications refresh both catalogs. Duplicate, malformed,
|
|
359
|
+
or oversized metadata fails only that server's resource catalog. Picker
|
|
360
|
+
selections are rejected if any catalog refresh replaces the selected entry while
|
|
361
|
+
variables are being collected, content is being read or formatted, or the editor
|
|
362
|
+
is being updated.
|
|
363
|
+
|
|
364
|
+
Resource metadata, URIs, template values, and bodies are untrusted server content.
|
|
365
|
+
Icons are neither displayed nor fetched, `_meta` is not retained or included in
|
|
366
|
+
resource artifacts, and URIs containing userinfo credentials are rejected. A body
|
|
367
|
+
enters model context only after an explicit user selection or `read` command. Resource subscriptions
|
|
368
|
+
and update notifications are not supported, and resources are never reread or
|
|
369
|
+
injected automatically.
|
|
370
|
+
|
|
297
371
|
## Output and limits
|
|
298
372
|
|
|
299
373
|
Text, supported images, and structured content are retained. Long text gets a
|
|
@@ -303,22 +377,30 @@ content is explicitly omitted from the preview, not silently discarded. Pi's
|
|
|
303
377
|
error-result path is text-only, so images in MCP errors are preserved in a
|
|
304
378
|
full-result artifact rather than displayed inline.
|
|
305
379
|
|
|
306
|
-
When necessary, the full MCP tool or
|
|
380
|
+
When necessary, the full MCP tool, prompt, or resource result is written to
|
|
307
381
|
`pix-mcp-*/result.json` under the system temp directory (directory mode 0700,
|
|
308
|
-
file mode 0600). Pi can inspect it with `read
|
|
309
|
-
sensitive data and are **not deleted at session
|
|
382
|
+
file mode 0600). Pi can inspect it with `read`; resource artifacts omit `_meta`.
|
|
383
|
+
These artifacts may contain sensitive data and are **not deleted at session
|
|
384
|
+
shutdown**; remove them when no
|
|
310
385
|
longer needed. Output limits are not a complete memory or security sandbox.
|
|
311
386
|
|
|
312
387
|
Configuration is limited to 256 KiB and 32 servers. Startup connects at most four
|
|
313
388
|
servers concurrently. Each tool or prompt catalog is limited to 1000 entries,
|
|
314
|
-
100 pagination cursors, and 2 MiB of metadata
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
389
|
+
100 pagination cursors, and 2 MiB of metadata. Direct resources and templates
|
|
390
|
+
share a 1000-entry and 2 MiB limit, with up to 100 cursors for each endpoint.
|
|
391
|
+
Individual input/output schemas are limited to 64 KiB. Prompt arguments and
|
|
392
|
+
resource-template arguments are limited to 256 KiB per retrieval; prompt and
|
|
393
|
+
prompt-argument names are limited to 256 bytes, cannot contain Unicode control,
|
|
394
|
+
format, or line-separator characters, and each prompt can declare at most 100
|
|
395
|
+
arguments. Tool names must use 1–128 ASCII letters, digits, underscores, hyphens,
|
|
396
|
+
or periods. Tool and prompt descriptions, prompt-argument descriptions, and
|
|
397
|
+
prompt titles are limited to 16 KiB. Resource URIs, templates, names, titles, and
|
|
398
|
+
descriptions are limited to 16 KiB; MIME types and template-variable names are
|
|
399
|
+
limited to 256 bytes; templates may contain at most 100 unique variables, and
|
|
400
|
+
resource annotations may contain at most two audience hints. A resource read may
|
|
401
|
+
return at most 100 content items and 16 MiB of serialized data.
|
|
402
|
+
Stdio messages are limited to 16 MiB. HTTP JSON responses and individual SSE
|
|
403
|
+
events are streaming-limited to 16 MiB plus 64 KiB of protocol framing.
|
|
322
404
|
Schemas are syntax-checked before compilation; see [schema compatibility](#schema-compatibility)
|
|
323
405
|
for supported dialects and the draft-07 subset. Schema nesting is limited to 64
|
|
324
406
|
levels, including literal data. External schema references are unsupported, but
|
|
@@ -329,16 +411,16 @@ The adapter never automatically retries `tools/call`: a timeout or lost response
|
|
|
329
411
|
may occur after a mutating operation took effect. Cancellation or expiration
|
|
330
412
|
aborts only the affected HTTP request and sends a best-effort MCP cancellation
|
|
331
413
|
notification; concurrent sibling calls remain usable. Successful output is
|
|
332
|
-
validated against the schema captured when the call began; MCP error results are
|
|
333
|
-
from that success schema. Cancellation is best-effort at the server and does not
|
|
414
|
+
validated against the schema captured when the call began; MCP error results are
|
|
415
|
+
exempt from that success schema. Cancellation is best-effort at the server and does not
|
|
334
416
|
roll back effects.
|
|
335
417
|
|
|
336
418
|
## Deliberately out of scope
|
|
337
419
|
|
|
338
|
-
OAuth, legacy SSE transport,
|
|
339
|
-
sampling, elicitation, MCP apps, task execution,
|
|
340
|
-
config UI, and persistent catalog caching. Use a
|
|
341
|
-
capabilities are required.
|
|
420
|
+
OAuth, legacy SSE transport, resource subscriptions, MCP prompt/resource
|
|
421
|
+
argument-value completion, sampling, elicitation, MCP apps, task execution,
|
|
422
|
+
semantic search, scripting, config UI, and persistent catalog caching. Use a
|
|
423
|
+
fuller adapter when those capabilities are required.
|
|
342
424
|
|
|
343
425
|
## Contributing
|
|
344
426
|
|
package/mcp.schema.json
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"description": { "$ref": "#/$defs/text" },
|
|
34
34
|
"timeout": {
|
|
35
35
|
"$ref": "#/$defs/timeout",
|
|
36
|
-
"description": "Hard deadline for one tool invocation or
|
|
36
|
+
"description": "Hard deadline for one tool invocation, prompt retrieval, or resource read."
|
|
37
37
|
},
|
|
38
38
|
"startupTimeoutMs": {
|
|
39
39
|
"$ref": "#/$defs/timeout",
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikuma.cloud/pix-mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"type": "module",
|
|
8
|
-
"description": "MCP prompts and lazily activated native tools for Pi Coding Agent",
|
|
8
|
+
"description": "MCP resources, prompts, and lazily activated native tools for Pi Coding Agent",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"pi-package"
|
|
11
11
|
],
|
|
@@ -22,17 +22,21 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
25
|
+
"@std-uritemplate/std-uritemplate": "2.0.12",
|
|
25
26
|
"ajv": "8.20.0",
|
|
27
|
+
"fast-uri": "3.1.8",
|
|
26
28
|
"undici": "8.10.2"
|
|
27
29
|
},
|
|
28
30
|
"peerDependencies": {
|
|
29
31
|
"@earendil-works/pi-ai": "*",
|
|
30
32
|
"@earendil-works/pi-coding-agent": "*",
|
|
33
|
+
"@earendil-works/pi-tui": "*",
|
|
31
34
|
"typebox": "*"
|
|
32
35
|
},
|
|
33
36
|
"devDependencies": {
|
|
34
37
|
"@earendil-works/pi-ai": "0.87.1",
|
|
35
38
|
"@earendil-works/pi-coding-agent": "0.87.1",
|
|
39
|
+
"@earendil-works/pi-tui": "0.87.1",
|
|
36
40
|
"typebox": "1.3.27"
|
|
37
41
|
}
|
|
38
42
|
}
|
package/src/catalog.ts
CHANGED
|
@@ -78,7 +78,7 @@ export function summary(item: Entry) {
|
|
|
78
78
|
|
|
79
79
|
export function compact(value: string, limit: number): string {
|
|
80
80
|
const text = value
|
|
81
|
-
.replace(
|
|
81
|
+
.replace(/[\p{C}\p{Zl}\p{Zp}]/gu, " ")
|
|
82
82
|
.replace(/\s+/g, " ")
|
|
83
83
|
.trim();
|
|
84
84
|
return text.length <= limit ? text : `${text.slice(0, limit)}…`;
|