@pi-unipi/mcp 2.5.0 → 2.6.1

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 CHANGED
@@ -39,6 +39,10 @@ MCP input properties are cloned and recursively canonicalized before registratio
39
39
 
40
40
  Pi 0.80 cannot remove dynamically registered tools. Enabling, disabling, deleting, or changing MCP servers is therefore applied on the next Pi restart rather than mutating the tool list mid-session. This prevents stale schemas and makes the restart an explicit cache-epoch boundary.
41
41
 
42
+ ### Bounded Results
43
+
44
+ MCP text results are model-visible up to a hard 64 KiB ceiling. A larger result keeps a bounded head/tail preview and, when the raw result is at most 16 MiB, writes the complete text to a private mode-0600 artifact under `~/.unipi/tool-results/`. Existing result directories are tightened to mode 0700. The returned result includes the path and directs the agent to use `read` with offset/limit. Results above the raw safety cap or filesystem write failures still return a bounded preview with an explicit non-retention warning. MCP image bytes are not written by this text bridge; image blocks remain represented by MIME metadata as before.
45
+
42
46
  Example tool calls:
43
47
  ```
44
48
  github__search_code({ query: "authentication middleware" })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/mcp",
3
- "version": "2.5.0",
3
+ "version": "2.6.1",
4
4
  "description": "MCP server management extension for Pi coding agent — browse, add, configure, and use MCP servers",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -30,7 +30,7 @@
30
30
  "test": "npx tsx --test tests/**/*.test.ts"
31
31
  },
32
32
  "dependencies": {
33
- "@pi-unipi/core": "2.5.0"
33
+ "@pi-unipi/core": "2.6.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@earendil-works/pi-coding-agent": "^0.80.0",
@@ -5,7 +5,7 @@
5
5
  * Naming convention: {serverName}__{toolName}
6
6
  */
7
7
 
8
- import { MCP_DEFAULTS } from "@pi-unipi/core";
8
+ import { MCP_DEFAULTS, boundModelOutput } from "@pi-unipi/core";
9
9
  import type { McpTool, McpToolResult } from "../types.js";
10
10
  import type { McpClient } from "./client.js";
11
11
 
@@ -170,21 +170,28 @@ export function translateMcpTool(
170
170
  }
171
171
  }
172
172
 
173
- if (result.isError) {
174
- const errorText = blocks.map((b) => b.text).join("\n") || "Unknown error";
175
- return {
176
- content: [{ type: "text", text: `MCP tool error from ${serverName}: ${errorText}` }],
177
- details: { error: true, server: serverName, tool: mcpTool.name },
178
- };
179
- }
180
-
181
173
  if (blocks.length === 0) {
182
- blocks.push({ type: "text", text: "(no output)" });
174
+ blocks.push({ type: "text", text: result.isError ? "Unknown error" : "(no output)" });
183
175
  }
184
176
 
177
+ const rawText = blocks.map((block) => block.text).join("\n");
178
+ const wrapper = result.isError ? `MCP tool error from ${serverName}: ` : "";
179
+ const output = boundModelOutput(rawText, {
180
+ maxBytes: Math.max(1024, MCP_DEFAULTS.MAX_MODEL_OUTPUT_BYTES - Buffer.byteLength(wrapper, "utf8")),
181
+ artifactPrefix: `mcp-${serverName}-${mcpTool.name}`,
182
+ });
183
+ const visibleText = `${wrapper}${output.text}`;
184
+
185
185
  return {
186
- content: blocks,
187
- details: { server: serverName, tool: mcpTool.name },
186
+ content: [{ type: "text", text: visibleText }],
187
+ details: {
188
+ error: result.isError || undefined,
189
+ server: serverName,
190
+ tool: mcpTool.name,
191
+ truncated: output.truncated,
192
+ originalBytes: output.originalBytes,
193
+ artifactPath: output.artifactPath,
194
+ },
188
195
  };
189
196
  } catch (err) {
190
197
  const message = err instanceof Error ? err.message : String(err);