pi-mcp-client 0.6.0 → 0.8.0
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 +12 -13
- package/dist/index.js +88 -35
- package/docs/authentication.md +1 -1
- package/docs/behavior.md +5 -5
- package/docs/commands.md +24 -21
- package/docs/configuration.md +2 -2
- package/docs/tool-reference.md +13 -13
- package/docs/troubleshooting.md +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# 🔌 Pi MCP Client
|
|
2
2
|
|
|
3
|
-
Connect Pi to MCP servers
|
|
4
|
-
|
|
5
|
-
TypeScript SDK. You can also select, preview, and use server-provided prompts.
|
|
6
|
-
No bridge process or invocation proxy.
|
|
3
|
+
Connect Pi to MCP servers so the model can use their tools and read their
|
|
4
|
+
resources. You can also browse, preview, and use server-provided prompts.
|
|
7
5
|
|
|
8
6
|
## 🚀 Installation
|
|
9
7
|
|
|
@@ -23,17 +21,17 @@ This server doesn't require credentials. Ask Pi:
|
|
|
23
21
|
|
|
24
22
|
> Search Cloudflare's documentation for how to deploy a Worker.
|
|
25
23
|
|
|
26
|
-
You configure servers and
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
You configure servers and sign in when needed. The model finds and uses
|
|
25
|
+
relevant tools and resources—you don't need to select tools before asking a
|
|
26
|
+
question.
|
|
29
27
|
|
|
30
28
|
Use these commands in Pi to manage your connections:
|
|
31
29
|
|
|
32
30
|
| Command | Purpose |
|
|
33
31
|
| --- | --- |
|
|
34
|
-
| `/mcp` |
|
|
32
|
+
| `/mcp` | Check connection status, available-tool counts, and tools loaded for the model when troubleshooting or checking your setup. |
|
|
35
33
|
| `/mcp login <server>` | Sign in to an HTTP server. Only this command opens the login browser. |
|
|
36
|
-
| `/mcp
|
|
34
|
+
| `/mcp prompt <server> [name] [argument=value ...]` | Browse prompts or open one by name, then review a preview before using it. |
|
|
37
35
|
| `/mcp reload` | Apply changes after editing your MCP configuration files. |
|
|
38
36
|
|
|
39
37
|
Only configure servers you trust: local servers and secret commands run with your
|
|
@@ -46,7 +44,7 @@ Store server definitions in `~/.pi/agent/mcp.json` or a trusted project's
|
|
|
46
44
|
`.mcp.json`. Project definitions replace same-named global definitions in full.
|
|
47
45
|
You can edit these files or use `/mcp add` and `/mcp remove`. To reuse a
|
|
48
46
|
Claude/Cursor JSON or Codex TOML file, run `/mcp import --scope global <path>` and
|
|
49
|
-
review the selected connections before saving.
|
|
47
|
+
review the selected connections before saving.
|
|
50
48
|
|
|
51
49
|
Detailed guides:
|
|
52
50
|
|
|
@@ -57,14 +55,15 @@ Detailed guides:
|
|
|
57
55
|
- [Commands](docs/commands.md): Server management, tool browsing, prompt selection,
|
|
58
56
|
and resource watches. These are commands **you** run in Pi.
|
|
59
57
|
- [Tool reference](docs/tool-reference.md): Discovery, activation, resource reads,
|
|
60
|
-
and argument completions. This is the **
|
|
61
|
-
- [Behavior](docs/behavior.md):
|
|
58
|
+
and argument completions. This is the **model's** interface, not a user API.
|
|
59
|
+
- [Behavior](docs/behavior.md): When servers connect, when tools become available,
|
|
60
|
+
and what permissions they have.
|
|
62
61
|
- [Troubleshooting](docs/troubleshooting.md): Error codes, recovery, and large
|
|
63
62
|
results.
|
|
64
63
|
|
|
65
64
|
## 🧰 Requirements
|
|
66
65
|
|
|
67
|
-
- Pi 0.85.1 or later
|
|
66
|
+
- Pi 0.85.1 or later.
|
|
68
67
|
- Node.js 22 or later.
|
|
69
68
|
- The server executable for stdio connections.
|
|
70
69
|
- An available OS credential store for OAuth. Linux requires a working Secret
|
package/dist/index.js
CHANGED
|
@@ -2814,10 +2814,10 @@ function promptSelector(title, choices, theme, keys, done, render) {
|
|
|
2814
2814
|
// src/prompt-command.ts
|
|
2815
2815
|
var PromptCommandError = class extends Error {
|
|
2816
2816
|
};
|
|
2817
|
-
var PROMPT_USAGE = "Use /mcp
|
|
2817
|
+
var PROMPT_USAGE = "Use /mcp prompt <server> [name] [argument=value ...].";
|
|
2818
2818
|
function parsePromptCommand(input) {
|
|
2819
2819
|
const [action, server, name, ...words] = commandWords(input);
|
|
2820
|
-
if (
|
|
2820
|
+
if (action !== "prompt" || !server) throw new PromptCommandError(PROMPT_USAGE);
|
|
2821
2821
|
const args = /* @__PURE__ */ Object.create(null);
|
|
2822
2822
|
for (const word of words) {
|
|
2823
2823
|
const equals = word.indexOf("=");
|
|
@@ -4541,33 +4541,61 @@ async function authenticate(identity, open2, signal, store, options = {}) {
|
|
|
4541
4541
|
}
|
|
4542
4542
|
|
|
4543
4543
|
// src/management.ts
|
|
4544
|
-
import { truncateToWidth as truncateToWidth2 } from "@earendil-works/pi-tui";
|
|
4544
|
+
import { truncateToWidth as truncateToWidth2, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
4545
4545
|
var serverStates = {
|
|
4546
|
-
disconnected: { glyph: "\u25CB", label: "idle" },
|
|
4547
|
-
connected: { glyph: "\u25CF", label: "connected" },
|
|
4548
|
-
connecting: { glyph: "\u25B6\uFE0E", label: "connecting" },
|
|
4549
|
-
failed: { glyph: "\u2718\uFE0E", label: "error" },
|
|
4550
|
-
disabled: { glyph: "\u25CB", label: "disabled" }
|
|
4546
|
+
disconnected: { glyph: "\u25CB", label: "idle", color: "muted" },
|
|
4547
|
+
connected: { glyph: "\u25CF", label: "connected", color: "success" },
|
|
4548
|
+
connecting: { glyph: "\u25B6\uFE0E", label: "connecting", color: "warning" },
|
|
4549
|
+
failed: { glyph: "\u2718\uFE0E", label: "error", color: "error" },
|
|
4550
|
+
disabled: { glyph: "\u25CB", label: "disabled", color: "dim" }
|
|
4551
4551
|
};
|
|
4552
|
-
function serverMatrix(servers, loaded, width = 80) {
|
|
4552
|
+
function serverMatrix(servers, loaded, width = 80, theme) {
|
|
4553
4553
|
if (width <= 0) return "";
|
|
4554
|
-
const
|
|
4555
|
-
|
|
4556
|
-
const
|
|
4557
|
-
|
|
4558
|
-
|
|
4554
|
+
const fg = (color, text) => theme ? theme.fg(color, text) : text;
|
|
4555
|
+
const bold = (text) => theme ? theme.bold(text) : text;
|
|
4556
|
+
const fit = (text) => {
|
|
4557
|
+
const fitted = truncateToWidth2(text, width, "\u2026");
|
|
4558
|
+
return theme ? fitted : plain(fitted);
|
|
4559
|
+
};
|
|
4560
|
+
const wrap = (text) => wrapTextWithAnsi(text, width).map(fit);
|
|
4561
|
+
const rows = [];
|
|
4562
|
+
if (!servers.length) return wrap(fg("muted", "No MCP servers configured.")).join("\n");
|
|
4563
|
+
const toolsWidth = Math.max(5, ...servers.map((server) => String(server.catalogSize ?? "\u2014").length));
|
|
4564
|
+
const loadedWidth = Math.max(6, ...servers.map((server) => String(loaded.get(server.name) ?? 0).length));
|
|
4565
|
+
const fixedWidth = 18 + toolsWidth + loadedWidth;
|
|
4566
|
+
const compact = width < fixedWidth + 12;
|
|
4567
|
+
const nameWidth = Math.max(0, Math.min(
|
|
4568
|
+
40,
|
|
4569
|
+
width - fixedWidth,
|
|
4570
|
+
Math.max(6, ...servers.map(({ name }) => visibleWidth(line(name))))
|
|
4571
|
+
));
|
|
4572
|
+
const padName = (name) => {
|
|
4573
|
+
const text = plain(truncateToWidth2(line(name), nameWidth, "\u2026"));
|
|
4574
|
+
return text + " ".repeat(Math.max(0, nameWidth - visibleWidth(text)));
|
|
4575
|
+
};
|
|
4576
|
+
if (!compact) rows.push(fg("muted", bold(
|
|
4577
|
+
` ${"Server".padEnd(nameWidth)} ${"State".padEnd(10)} ${"Tools".padStart(toolsWidth)} ${"Loaded".padStart(loadedWidth)}`
|
|
4578
|
+
)));
|
|
4579
|
+
for (const server of servers) {
|
|
4559
4580
|
const state = serverStates[server.state];
|
|
4560
|
-
const
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4581
|
+
const count = loaded.get(server.name) ?? 0;
|
|
4582
|
+
const tools = String(server.catalogSize ?? "\u2014");
|
|
4583
|
+
const name = fg(server.state === "disabled" ? "dim" : "text", bold(compact ? line(server.name) : padName(server.name)));
|
|
4584
|
+
const glyph = fg(state.color, state.glyph);
|
|
4585
|
+
if (compact) {
|
|
4586
|
+
rows.push(...wrap(`${glyph} ${name}`));
|
|
4587
|
+
rows.push(...wrap(` ${fg(state.color, state.label)} \xB7 ${fg("muted", `${tools} tools \xB7 ${count} loaded`)}`));
|
|
4588
|
+
} else {
|
|
4589
|
+
rows.push(`${glyph} ${name} ${fg(state.color, state.label.padEnd(10))} ` + fg(server.catalogSize === void 0 ? "dim" : "text", tools.padStart(toolsWidth)) + " " + fg(count ? "accent" : "dim", String(count).padStart(loadedWidth)));
|
|
4590
|
+
}
|
|
4591
|
+
}
|
|
4592
|
+
rows.push("", ...wrap(fg("dim", "Connections open on demand. \u2014 = catalog not fetched.")));
|
|
4593
|
+
const errors = servers.filter((server) => server.state === "failed" && server.error);
|
|
4594
|
+
if (errors.length) rows.push("");
|
|
4595
|
+
for (const server of errors) {
|
|
4596
|
+
rows.push(...wrap(fg("error", `\u2718\uFE0E ${line(server.name)}: [${line(server.error.code)}]`) + fg("muted", ` ${line(server.error.message)}`)));
|
|
4597
|
+
}
|
|
4598
|
+
return rows.map(fit).join("\n");
|
|
4571
4599
|
}
|
|
4572
4600
|
function toolPickerLabel(tool, index, columns = 80) {
|
|
4573
4601
|
const width = Math.max(0, columns - 4);
|
|
@@ -5913,6 +5941,23 @@ function renderResult(result, options, theme, isError) {
|
|
|
5913
5941
|
};
|
|
5914
5942
|
}
|
|
5915
5943
|
|
|
5944
|
+
// src/status-panel.ts
|
|
5945
|
+
var STATUS_ENTRY = "mcp-status";
|
|
5946
|
+
function statusPanel(snapshot, theme) {
|
|
5947
|
+
const loaded = new Map(snapshot.loaded);
|
|
5948
|
+
return {
|
|
5949
|
+
render(width) {
|
|
5950
|
+
if (width <= 0) return [];
|
|
5951
|
+
const padding = width > 2 ? 1 : 0;
|
|
5952
|
+
const prefix = " ".repeat(padding);
|
|
5953
|
+
return serverMatrix(snapshot.servers, loaded, width - padding * 2, theme).split("\n").map((row) => prefix + row);
|
|
5954
|
+
},
|
|
5955
|
+
// Styling and layout are recomputed on every render, including theme changes.
|
|
5956
|
+
invalidate() {
|
|
5957
|
+
}
|
|
5958
|
+
};
|
|
5959
|
+
}
|
|
5960
|
+
|
|
5916
5961
|
// src/index.ts
|
|
5917
5962
|
var CommandUsageError = class extends Error {
|
|
5918
5963
|
};
|
|
@@ -5941,6 +5986,10 @@ function mcpClient(pi, options = {}) {
|
|
|
5941
5986
|
let loginController;
|
|
5942
5987
|
let promptController;
|
|
5943
5988
|
let importController;
|
|
5989
|
+
pi.registerEntryRenderer(
|
|
5990
|
+
STATUS_ENTRY,
|
|
5991
|
+
(entry, _options, theme) => statusPanel(entry.data ?? { servers: [], loaded: [] }, theme)
|
|
5992
|
+
);
|
|
5944
5993
|
pi.registerMessageRenderer("mcp-prompt", (message, { expanded, outputPad }, theme) => {
|
|
5945
5994
|
const details = object(message.details) ? message.details : {};
|
|
5946
5995
|
const count = Number(details.count ?? 0);
|
|
@@ -6331,15 +6380,15 @@ Variables: ${(candidate.variables ?? []).join(", ") || "none"}. Supply known val
|
|
|
6331
6380
|
}
|
|
6332
6381
|
});
|
|
6333
6382
|
pi.registerCommand("mcp", {
|
|
6334
|
-
description: "
|
|
6383
|
+
description: "Show MCP server status; manage servers: add|remove|import --scope global|project, reload, enable|disable|get|tools|login|logout|reconnect|refresh <server>; prompt <server> [name] [argument=value ...]; subscriptions; subscribe|unsubscribe <server> <uri>",
|
|
6335
6384
|
getArgumentCompletions(prefix) {
|
|
6336
|
-
const serverActions = ["enable", "disable", "get", "tools", "
|
|
6385
|
+
const serverActions = ["enable", "disable", "get", "tools", "prompt", "login", "logout", "reconnect", "refresh", "subscribe", "unsubscribe"];
|
|
6337
6386
|
const input = prefix.trimStart();
|
|
6338
6387
|
const configuration = configCommandCompletions(input, Object.keys(config));
|
|
6339
6388
|
if (configuration !== void 0) return configuration;
|
|
6340
6389
|
const match = /^(\S+)\s+(.*)$/s.exec(input);
|
|
6341
6390
|
if (!match) {
|
|
6342
|
-
return ["
|
|
6391
|
+
return ["reload", "subscriptions", "add", "remove", "import", ...serverActions].filter((action2) => action2.startsWith(input)).map((action2) => ({ value: action2, label: action2 }));
|
|
6343
6392
|
}
|
|
6344
6393
|
const [, action, partialServer] = match;
|
|
6345
6394
|
if (action === "login") {
|
|
@@ -6355,7 +6404,7 @@ Variables: ${(candidate.variables ?? []).join(", ") || "none"}. Supply known val
|
|
|
6355
6404
|
async handler(args, ctx) {
|
|
6356
6405
|
const generation = sessionGeneration;
|
|
6357
6406
|
await ctx.waitForIdle();
|
|
6358
|
-
let [action = "
|
|
6407
|
+
let [action = "", server, ...extra] = args.trim().split(/\s+/).filter(Boolean);
|
|
6359
6408
|
try {
|
|
6360
6409
|
if (generation !== sessionGeneration)
|
|
6361
6410
|
throw new CommandUsageError("The Pi session changed while waiting for idle.");
|
|
@@ -6382,7 +6431,7 @@ Variables: ${(candidate.variables ?? []).join(", ") || "none"}. Supply known val
|
|
|
6382
6431
|
}
|
|
6383
6432
|
return;
|
|
6384
6433
|
}
|
|
6385
|
-
if (action === "prompt"
|
|
6434
|
+
if (action === "prompt") {
|
|
6386
6435
|
if (promptController) throw new PromptCommandError("A prompt selection is already open.");
|
|
6387
6436
|
const activeRuntime = current();
|
|
6388
6437
|
const controller = new AbortController();
|
|
@@ -6495,19 +6544,23 @@ ${snapshot.body}`,
|
|
|
6495
6544
|
);
|
|
6496
6545
|
return;
|
|
6497
6546
|
}
|
|
6498
|
-
if (
|
|
6547
|
+
if (!action) {
|
|
6499
6548
|
const statuses = current().serverStatuses();
|
|
6500
6549
|
const loaded = /* @__PURE__ */ new Map();
|
|
6501
6550
|
for (const name of pi.getActiveTools()) {
|
|
6502
6551
|
const tool = exposure.definitions.get(name);
|
|
6503
6552
|
if (tool) loaded.set(tool.server, (loaded.get(tool.server) ?? 0) + 1);
|
|
6504
6553
|
}
|
|
6505
|
-
if (ctx.
|
|
6554
|
+
if (ctx.mode === "tui") {
|
|
6555
|
+
pi.appendEntry(STATUS_ENTRY, { servers: statuses, loaded: [...loaded] });
|
|
6556
|
+
} else if (ctx.hasUI) {
|
|
6557
|
+
ctx.ui.notify(serverMatrix(statuses, loaded), "info");
|
|
6558
|
+
}
|
|
6506
6559
|
return;
|
|
6507
6560
|
}
|
|
6508
6561
|
if (!server || extra.length > 0 && !(action === "login" && extra.length === 1 && extra[0] === "--no-browser") || !Object.hasOwn(config, server) || config[server].disabled)
|
|
6509
6562
|
throw new CommandUsageError(
|
|
6510
|
-
"Usage: /mcp
|
|
6563
|
+
"Usage: /mcp, /mcp reload, /mcp enable|disable|get|tools|login|logout|reconnect|refresh <server>, or /mcp add|remove|import --scope global|project ... . Disabled servers accept enable, disable, get, logout, and scoped removal."
|
|
6511
6564
|
);
|
|
6512
6565
|
if (action === "tools") {
|
|
6513
6566
|
if (!ctx.hasUI)
|
|
@@ -6618,7 +6671,7 @@ Opening browser. Esc to cancel.`
|
|
|
6618
6671
|
await current().promptCatalog(server, ctx.signal, true);
|
|
6619
6672
|
} else
|
|
6620
6673
|
throw new CommandUsageError(
|
|
6621
|
-
"Unknown MCP command. Use /mcp
|
|
6674
|
+
"Unknown MCP command. Use /mcp, /mcp reload, or /mcp enable|disable|get|tools|login|logout|reconnect|refresh <server>, or /mcp add|remove|import --scope global|project ... ."
|
|
6622
6675
|
);
|
|
6623
6676
|
if (ctx.hasUI)
|
|
6624
6677
|
ctx.ui.notify(
|
|
@@ -6629,7 +6682,7 @@ Opening browser. Esc to cancel.`
|
|
|
6629
6682
|
const message = error instanceof CommandUsageError || error instanceof ConfigMutationError || error instanceof PromptCommandError ? error.message : formatDiagnostic(
|
|
6630
6683
|
diagnose(error, {
|
|
6631
6684
|
server,
|
|
6632
|
-
operation: ["reload", "get", "enable", "disable", "add", "remove", "import"].includes(action) ? "configuration" :
|
|
6685
|
+
operation: ["reload", "get", "enable", "disable", "add", "remove", "import"].includes(action) ? "configuration" : action === "tools" ? "search" : action === "prompt" ? "prompt" : ["login", "logout"].includes(action) ? "auth" : ["subscribe", "unsubscribe"].includes(action) ? "subscribe" : action === "refresh" ? "refresh" : "reconnect",
|
|
6633
6686
|
oauth: usesOAuth(config[server]),
|
|
6634
6687
|
signal: ctx.signal
|
|
6635
6688
|
})
|
package/docs/authentication.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[Back to the README](../README.md)
|
|
4
4
|
|
|
5
|
-
You manage authentication through `/mcp login` and `/mcp logout`. The
|
|
5
|
+
You manage authentication through `/mcp login` and `/mcp logout`. The model
|
|
6
6
|
can't initiate an OAuth login: only your explicit login command opens the browser.
|
|
7
7
|
For externally managed bearer tokens, use
|
|
8
8
|
[headers and secret commands](configuration.md#secret-commands) instead.
|
package/docs/behavior.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[Back to the README](../README.md)
|
|
4
4
|
|
|
5
5
|
This page explains how the extension manages state and displays results. For the
|
|
6
|
-
|
|
6
|
+
model's tool-call interface, see the [tool reference](tool-reference.md).
|
|
7
7
|
|
|
8
8
|
## Sessions
|
|
9
9
|
|
|
@@ -15,7 +15,7 @@ assistant's tool-call interface, see the [tool reference](tool-reference.md).
|
|
|
15
15
|
Other providers receive the expanded tool list normally.
|
|
16
16
|
- Discovery respects server filters; activation also respects Pi's tool exclusions.
|
|
17
17
|
An explicit tool allowlist must include both `mcp_tools` and the native tools
|
|
18
|
-
the
|
|
18
|
+
the model needs to load.
|
|
19
19
|
|
|
20
20
|
## Resource snapshots
|
|
21
21
|
|
|
@@ -33,7 +33,7 @@ contain sensitive data and aren't automatically deleted.
|
|
|
33
33
|
## Prompt snapshots
|
|
34
34
|
|
|
35
35
|
Prompt discovery fetches metadata only. You explicitly enter arguments and fetch a
|
|
36
|
-
preview through `/mcp
|
|
36
|
+
preview through `/mcp prompt`. Only **Use prompt** adds the
|
|
37
37
|
reviewed snapshot to the conversation and starts a model turn. Cancelling a
|
|
38
38
|
preview adds no message and doesn't write a spill file. Arguments already sent to
|
|
39
39
|
the server can't be recalled.
|
|
@@ -88,7 +88,7 @@ reconnection or configuration reload.
|
|
|
88
88
|
When a connected server reports a tool-list change, the extension invalidates its
|
|
89
89
|
memory and disk catalogs. The next discovery or activation fetches the current
|
|
90
90
|
list, including new or removed tools. Notifications don't replace active tool
|
|
91
|
-
definitions: the
|
|
91
|
+
definitions: the model must activate changed schemas again before use. Calls
|
|
92
92
|
validate the live catalog before execution and refuse removed or changed tools.
|
|
93
93
|
Disconnected, cache-only searches can't receive notifications and still use the
|
|
94
94
|
24-hour disk-cache expiry.
|
|
@@ -115,7 +115,7 @@ indentation and syntax highlighting. Explicit JSON resource MIME types (includin
|
|
|
115
115
|
`application/*+json`) and structured content identify JSON without guessing.
|
|
116
116
|
Other explicit MIME types stay plain text; unlabeled text is checked for JSON.
|
|
117
117
|
|
|
118
|
-
Formatting changes only the display, not the response sent to the
|
|
118
|
+
Formatting changes only the display, not the response sent to the model.
|
|
119
119
|
Invalid or truncated JSON stays plain text. Results that would exceed formatting
|
|
120
120
|
limits also stay plain text. Resource-link MIME types describe the linked content,
|
|
121
121
|
not the displayed link label. Supported images use the existing result display;
|
package/docs/commands.md
CHANGED
|
@@ -2,22 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
[Back to the README](../README.md)
|
|
4
4
|
|
|
5
|
-
These are commands **you run in Pi**, not tools the
|
|
6
|
-
manage servers, inspect capabilities, use prompts, and watch resource changes.
|
|
7
|
-
separate interface is documented in the [tool reference](tool-reference.md).
|
|
5
|
+
These are commands **you run in Pi**, not tools the model calls. Use them to
|
|
6
|
+
manage servers, inspect capabilities, use prompts, and watch resource changes.
|
|
7
|
+
The model's separate interface is documented in the [tool reference](tool-reference.md).
|
|
8
8
|
|
|
9
9
|
## Command reference
|
|
10
10
|
|
|
11
11
|
| Command | Purpose |
|
|
12
12
|
| --- | --- |
|
|
13
|
-
| `/mcp
|
|
13
|
+
| `/mcp` | Check server status, catalog tool counts, and tools loaded for the model. |
|
|
14
14
|
| `/mcp add --scope <scope> [options] <server> <url>` | Save an HTTP server without connecting. For stdio, use `<server> -- <command> [args...]`. |
|
|
15
15
|
| `/mcp remove --scope <scope> <server>` | Remove a definition from the selected scope, retaining credentials. |
|
|
16
16
|
| `/mcp import --scope <scope> <path>` | Preview and select servers from Claude/Cursor JSON or Codex TOML, then confirm a scoped import. |
|
|
17
17
|
| `/mcp get <server>` | Inspect status and configuration, including disabled servers. Connection values are hidden. |
|
|
18
18
|
| `/mcp tools <server>` | Browse the server's tools and inspect descriptions without activating tools. |
|
|
19
|
-
| `/mcp
|
|
20
|
-
| `/mcp prompt <server> <name> [argument=value ...]` | Open a named prompt with prefilled arguments, then fetch and review a preview. |
|
|
19
|
+
| `/mcp prompt <server> [name] [argument=value ...]` | Browse prompts or open a named prompt with prefilled arguments, then fetch and review a preview. |
|
|
21
20
|
| `/mcp reload` | Apply configuration changes without restarting Pi. |
|
|
22
21
|
| `/mcp enable <server>` | Enable a server in its effective configuration file. |
|
|
23
22
|
| `/mcp disable <server>` | Disable a server, close its connection, and deactivate its tools. |
|
|
@@ -34,11 +33,16 @@ See [Authentication](authentication.md) for login and logout procedures, and
|
|
|
34
33
|
|
|
35
34
|
## Inspect servers and tools
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
Use `/mcp` to check your setup or investigate a connection problem. It reports
|
|
37
|
+
whether each server is idle, connected, connecting, disabled, or in an error
|
|
38
|
+
state, along with catalog tool counts and tools loaded for the model.
|
|
39
|
+
|
|
40
|
+
Idle is normal: connections open on demand. A dash (`—`) means the catalog hasn't
|
|
41
|
+
been fetched, not that the server has no tools. **Loaded** counts tools currently
|
|
42
|
+
active for the model.
|
|
43
|
+
|
|
44
|
+
Checking status doesn't open connections or send information to the model.
|
|
45
|
+
The result stays in your transcript; run the command again for updated status.
|
|
42
46
|
|
|
43
47
|
Use `/mcp get <server>` to check the effective transport, protocol, filters,
|
|
44
48
|
and connection status without connecting or running secret commands. Connection
|
|
@@ -49,15 +53,14 @@ unavailable credential store is reported separately from missing tokens. Header
|
|
|
49
53
|
and stdio credentials are identified as externally managed; inspection never
|
|
50
54
|
executes them.
|
|
51
55
|
|
|
52
|
-
Use `/mcp tools <server>` to
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
context. This command requires an interactive UI.
|
|
56
|
+
Use `/mcp tools <server>` to find out what a server can do. It fetches the current
|
|
57
|
+
catalog so you can inspect tool descriptions, parameters, and required inputs.
|
|
58
|
+
Browsing respects your include and exclude filters and doesn't activate tools
|
|
59
|
+
or add their schemas to the model's context. This command requires an
|
|
60
|
+
interactive UI.
|
|
58
61
|
|
|
59
62
|
Refreshing a catalog doesn't replace active tool definitions. After a schema
|
|
60
|
-
change, ask the
|
|
63
|
+
change, ask the model to activate the exact tool again. See
|
|
61
64
|
[tool changes and caching](behavior.md#discovery-and-caching). Failed tool calls
|
|
62
65
|
aren't retried automatically; verify whether an interrupted operation completed
|
|
63
66
|
before trying again.
|
|
@@ -68,7 +71,7 @@ Prompts are server-maintained task instructions that **you** choose to use. For
|
|
|
68
71
|
server that provides an `explain` prompt, browse or open it directly:
|
|
69
72
|
|
|
70
73
|
```text
|
|
71
|
-
/mcp
|
|
74
|
+
/mcp prompt docs
|
|
72
75
|
/mcp prompt docs explain topic="OAuth flows"
|
|
73
76
|
```
|
|
74
77
|
|
|
@@ -109,7 +112,7 @@ Both commands wait for active agent work to finish, then
|
|
|
109
112
|
[apply the configuration](configuration.md#apply-changes).
|
|
110
113
|
|
|
111
114
|
Disabling removes the server from discovery and deactivates its tools. Enabling
|
|
112
|
-
doesn't connect, authenticate, or load tools; ask the
|
|
115
|
+
doesn't connect, authenticate, or load tools; ask the model to discover the
|
|
113
116
|
capabilities you need.
|
|
114
117
|
|
|
115
118
|
## Add and remove servers
|
|
@@ -283,7 +286,7 @@ streams. It never opens the URI as a file or generic URL.
|
|
|
283
286
|
An update marks the watch as changed (`↻`) and shows a UI notification. Repeated
|
|
284
287
|
updates coalesce into that marker until you unsubscribe. No content is fetched,
|
|
285
288
|
no model turn starts, and existing resource results remain unchanged. Ask the
|
|
286
|
-
|
|
289
|
+
model to read the resource for a new snapshot; unsubscribe and subscribe again
|
|
287
290
|
to reset the change marker.
|
|
288
291
|
|
|
289
292
|
Watches are memory-only, limited to 50 per server connection, and require an
|
package/docs/configuration.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[Back to the README](../README.md)
|
|
4
4
|
|
|
5
|
-
You configure which servers the
|
|
5
|
+
You configure which servers the model can access. Add connections to
|
|
6
6
|
`~/.pi/agent/mcp.json`, or `.mcp.json` in a trusted project. For command-based
|
|
7
7
|
setup, see [Add and remove servers](commands.md#add-and-remove-servers). To reuse
|
|
8
8
|
an existing Claude/Cursor JSON or Codex TOML file, see
|
|
@@ -119,7 +119,7 @@ server definition:
|
|
|
119
119
|
|
|
120
120
|
| Field | Purpose |
|
|
121
121
|
| --- | --- |
|
|
122
|
-
| `description` | Short capability description for the
|
|
122
|
+
| `description` | Short capability description for the model's server directory. |
|
|
123
123
|
| `oauthClientId` | Optional pre-registered public client ID. Supports `${ENV_VAR}` interpolation, not secret commands. |
|
|
124
124
|
| `oauthScopes` | Optional array of 1–100 unique OAuth scope tokens to request at login. Omitted scopes use SDK/server defaults. Values are literal, without interpolation. |
|
|
125
125
|
| `oauthCallbackPort` | Optional loopback callback port, from 1 to 65535. Defaults to `19847`. |
|
package/docs/tool-reference.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Model tool reference
|
|
2
2
|
|
|
3
3
|
[Back to the README](../README.md)
|
|
4
4
|
|
|
5
|
-
This page documents **the
|
|
6
|
-
calls the
|
|
5
|
+
This page documents **the model's interface**. The examples illustrate tool
|
|
6
|
+
calls the model makes; they aren't slash commands or JavaScript for you to
|
|
7
7
|
run. Describe your task in natural language. For operations you control directly,
|
|
8
8
|
see [Commands](commands.md).
|
|
9
9
|
|
|
10
10
|
The `mcp_tools` tool supports four mutually exclusive operations:
|
|
11
11
|
|
|
12
|
-
| Operation | What the
|
|
12
|
+
| Operation | What the model can do | What it doesn't do |
|
|
13
13
|
| --- | --- | --- |
|
|
14
14
|
| `query` | Discover tool, resource, and prompt metadata. | Read content or activate tools. |
|
|
15
15
|
| `activate` | Load full schemas for exact tool identifiers. | Invoke tools. |
|
|
16
16
|
| `read` | Fetch one resource as conversation context. | Activate tools or follow links automatically. |
|
|
17
17
|
| `complete` | Request server suggestions for a template variable. | Read resources, activate tools, or select a value. |
|
|
18
18
|
|
|
19
|
-
The
|
|
19
|
+
The model passes exactly one of `query`, `activate`, `read`, or `complete`.
|
|
20
20
|
The optional `kind`, `server`, and `limit` fields are query-only; reads and
|
|
21
21
|
completions carry their server inside their respective objects.
|
|
22
22
|
|
|
@@ -40,7 +40,7 @@ content type when supplied. Concrete resources and tools include exact next-call
|
|
|
40
40
|
arguments; templates include a read-call shape and variable names.
|
|
41
41
|
|
|
42
42
|
Prompt candidates show the owning server, name, description, argument metadata,
|
|
43
|
-
and a user-only command such as `/mcp prompt docs explain`. The
|
|
43
|
+
and a user-only command such as `/mcp prompt docs explain`. The model can
|
|
44
44
|
recommend this command but can't retrieve or run prompts through `mcp_tools`.
|
|
45
45
|
Only you can [select, preview, and use a prompt](commands.md#use-server-prompts).
|
|
46
46
|
|
|
@@ -62,7 +62,7 @@ mcp_tools({ activate: ["linear.list_teams", "linear.get_team"] })
|
|
|
62
62
|
|
|
63
63
|
Activation accepts 1–50 exact `server.tool` or `mcp__server__tool` identifiers,
|
|
64
64
|
ignores duplicates, and works without a prior search. Typos never activate fuzzy
|
|
65
|
-
matches: failures list nearby catalog names when available so the
|
|
65
|
+
matches: failures list nearby catalog names when available so the model can
|
|
66
66
|
retry with an exact identifier. Each identifier reports `loaded`, `already loaded`,
|
|
67
67
|
or `not loaded` with a reason. Partial success keeps the tools that loaded.
|
|
68
68
|
|
|
@@ -74,7 +74,7 @@ tool. There is no invocation proxy. Previously loaded tools remain available;
|
|
|
74
74
|
## Read resources as context
|
|
75
75
|
|
|
76
76
|
For a request such as “Use the authentication guide to explain this API,” the
|
|
77
|
-
|
|
77
|
+
model can discover and read relevant context:
|
|
78
78
|
|
|
79
79
|
```js
|
|
80
80
|
mcp_tools({ query: "authentication guide", kind: "resources" })
|
|
@@ -87,7 +87,7 @@ request, even for `file:` or `https:` URIs. There is no fallback when the server
|
|
|
87
87
|
can't read the URI. The server still controls which data it returns.
|
|
88
88
|
|
|
89
89
|
Tool-returned resource links include an exact `mcp_tools({read: ...})` call. The
|
|
90
|
-
|
|
90
|
+
model can read such links directly, without prior discovery or activation;
|
|
91
91
|
linked resources don't have to appear in the catalog.
|
|
92
92
|
|
|
93
93
|
Reading attaches content as the tool result itself, not as a second message. The
|
|
@@ -100,7 +100,7 @@ limits and private spill files.
|
|
|
100
100
|
|
|
101
101
|
Discovery also lists URI templates, such as `schema://tables/{table}`, without
|
|
102
102
|
enumerating every possible table. Templates have a `[template]` label, variable
|
|
103
|
-
names, and a read-call shape. The
|
|
103
|
+
names, and a read-call shape. The model supplies known argument values:
|
|
104
104
|
|
|
105
105
|
```js
|
|
106
106
|
mcp_tools({ query: "table schema", server: "warehouse", kind: "resources" })
|
|
@@ -117,7 +117,7 @@ The `read` object accepts either `uri` or `template` plus `arguments`, never bot
|
|
|
117
117
|
The selected server must advertise the exact template. The official SDK expands
|
|
118
118
|
strings or string arrays into a concrete URI, then reads it through that same
|
|
119
119
|
server. Template variables aren't an input schema: no required fields or allowed
|
|
120
|
-
values are inferred. The
|
|
120
|
+
values are inferred. The model should use values from your request or prior
|
|
121
121
|
results and ask you when a needed value is unknown rather than inventing an
|
|
122
122
|
identifier.
|
|
123
123
|
|
|
@@ -128,7 +128,7 @@ content; see [result display](behavior.md#result-display).
|
|
|
128
128
|
|
|
129
129
|
## Complete resource arguments
|
|
130
130
|
|
|
131
|
-
The
|
|
131
|
+
The model can ask a server for suggested values for one advertised template
|
|
132
132
|
variable:
|
|
133
133
|
|
|
134
134
|
```js
|
|
@@ -142,7 +142,7 @@ mcp_tools({
|
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
`value` is the current prefix and can be empty. For dependent suggestions, the
|
|
145
|
-
|
|
145
|
+
model can add `arguments: { knownVariable: "value" }` inside `complete`.
|
|
146
146
|
These context values must be strings, not arrays. The server must advertise
|
|
147
147
|
completion support and the exact template; the variable must occur in that
|
|
148
148
|
template.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -27,16 +27,16 @@ unavailable server isn't an empty catalog.
|
|
|
27
27
|
| `connection_failed` | Server executable, working directory, endpoint, network, and TLS configuration. |
|
|
28
28
|
| `timeout` | Server responsiveness and the applicable request, secret-command, or OAuth time limit. |
|
|
29
29
|
| `protocol_error` | Server compatibility and the `protocol` setting. |
|
|
30
|
-
| `tool_changed` | Check server filters and ask the
|
|
30
|
+
| `tool_changed` | Check server filters and ask the model to activate the exact tool again for its current schema. Run `/mcp reload` if connection configuration changed. |
|
|
31
31
|
| `tool_error` | The server's tool result and inputs; verify the outcome before retrying. |
|
|
32
|
-
| `resource_invalid` | The
|
|
32
|
+
| `resource_invalid` | The model needs an exact absolute resource URI from discovery or a tool-returned link. |
|
|
33
33
|
| `resource_not_found` | Refresh resource metadata or obtain a new link. |
|
|
34
|
-
| `resources_unsupported` | Ask the
|
|
35
|
-
| `completions_unsupported` | Supply known template values; the
|
|
36
|
-
| `completion_invalid` | The
|
|
37
|
-
| `subscriptions_unsupported` | Choose a server with subscription support, or ask the
|
|
34
|
+
| `resources_unsupported` | Ask the model to use the server's tools instead, or choose a resource-capable server. |
|
|
35
|
+
| `completions_unsupported` | Supply known template values; the model should ask you if a value is missing. |
|
|
36
|
+
| `completion_invalid` | The model needs an advertised template variable and a string prefix. |
|
|
37
|
+
| `subscriptions_unsupported` | Choose a server with subscription support, or ask the model to read when needed. |
|
|
38
38
|
| `subscription_limit` | Remove a watch before adding another; the limit is 50 per connection. |
|
|
39
|
-
| `catalog_changed` | Ask the
|
|
39
|
+
| `catalog_changed` | Ask the model to retry discovery after the server catalog settles. |
|
|
40
40
|
| `oauth_failed` | An unclassified OAuth failure. Check the service's requirements and `/mcp get <server>` for the client type, scopes, and callback URL. Only public/PKCE clients are supported, not clients requiring a secret. |
|
|
41
41
|
| `oauth_client_required` | The server doesn't support dynamic registration. Configure `oauthClientId` for a registered public/PKCE client and register the exact callback URL. Reload, then log in again. |
|
|
42
42
|
| `oauth_registration_rejected` | The server rejected dynamic registration. Check public/native client eligibility and the callback URL, or configure an approved public client ID. |
|