pi-mcp-adapter 1.3.0 → 1.4.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/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.4.1] - 2026-01-19
9
+
10
+ ### Changed
11
+
12
+ - Status bar shows server count instead of tool count ("MCP: 5 servers")
13
+
14
+ ## [1.4.0] - 2026-01-19
15
+
16
+ ### Changed
17
+
18
+ - **Non-blocking startup** - Pi starts immediately, MCP servers connect in background. First MCP call waits only if init isn't done yet.
19
+
20
+ ### Fixed
21
+
22
+ - Tool metadata now includes `inputSchema` after `/mcp reconnect` (was missing, breaking describe and error hints)
23
+
8
24
  ## [1.3.0] - 2026-01-19
9
25
 
10
26
  ### Changed
package/README.md CHANGED
@@ -6,11 +6,11 @@ https://github.com/user-attachments/assets/4b7c66ff-e27e-4639-b195-22c3db406a5a
6
6
 
7
7
  ## Why This Exists
8
8
 
9
- Mario (Pi's creator) wrote about [why you might not need MCP](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/). The core issue: MCP servers ship dozens of tools with verbose descriptions. Playwright MCP has 21 tools eating 13.7k tokens. Chrome DevTools MCP has 26 tools eating 18k tokens. Connect a few servers and you've burned 30-50k tokens before the conversation starts. That's context bloat, slower responses, higher costs, and confused agents drowning in tool options.
9
+ Mario wrote about [why you might not need MCP](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/). The problem: each MCP server dumps dozens of tools into your context. Playwright alone eats 13k tokens. Connect a few servers and you've burned half your context window before the conversation starts.
10
10
 
11
- His solution: skip MCP, write simple CLI tools.
11
+ His take: skip MCP entirely, write simple CLI tools instead.
12
12
 
13
- But there's an active ecosystem of well-maintained MCP servers for databases, browsers, APIs, file systems, and more. This adapter lets you tap into that ecosystem without the context cost. One proxy tool (~200 tokens) instead of hundreds of individual tool definitions. The LLM discovers what it needs on-demand.
13
+ But the MCP ecosystem has useful stuff - databases, browsers, APIs. This adapter gives you access without the bloat. One proxy tool (~200 tokens) instead of hundreds. The agent discovers what it needs on-demand.
14
14
 
15
15
  ## Install
16
16
 
package/index.ts CHANGED
@@ -55,25 +55,34 @@ export default function mcpAdapter(pi: ExtensionAPI) {
55
55
  });
56
56
 
57
57
  pi.on("session_start", async (_event, ctx) => {
58
+ // Non-blocking init - Pi starts immediately, MCP connects in background
58
59
  initPromise = initializeMcp(pi, ctx);
59
- state = await initPromise;
60
- initPromise = null;
61
60
 
62
- // Set up callback for auto-reconnect to update metadata
63
- state.lifecycle.setReconnectCallback((serverName) => {
64
- if (state) {
65
- updateServerMetadata(state, serverName);
61
+ initPromise.then(s => {
62
+ state = s;
63
+ initPromise = null;
64
+
65
+ // Set up callback for auto-reconnect to update metadata
66
+ s.lifecycle.setReconnectCallback((serverName) => {
67
+ if (state) {
68
+ updateServerMetadata(state, serverName);
69
+ }
70
+ });
71
+
72
+ // Update status bar when ready
73
+ if (ctx.hasUI) {
74
+ const serverCount = s.registeredTools.size;
75
+ if (serverCount > 0) {
76
+ const label = serverCount === 1 ? "server" : "servers";
77
+ ctx.ui.setStatus("mcp", ctx.ui.theme.fg("accent", `MCP: ${serverCount} ${label}`));
78
+ } else {
79
+ ctx.ui.setStatus("mcp", "");
80
+ }
66
81
  }
82
+ }).catch(err => {
83
+ console.error("MCP initialization failed:", err);
84
+ initPromise = null;
67
85
  });
68
-
69
- if (ctx.hasUI) {
70
- const totalTools = [...state.registeredTools.values()].flat().length;
71
- if (totalTools > 0) {
72
- ctx.ui.setStatus("mcp", ctx.ui.theme.fg("accent", `MCP: ${totalTools} tools`));
73
- } else {
74
- ctx.ui.setStatus("mcp", "");
75
- }
76
- }
77
86
  });
78
87
 
79
88
  pi.on("session_shutdown", async () => {
@@ -95,6 +104,15 @@ export default function mcpAdapter(pi: ExtensionAPI) {
95
104
  pi.registerCommand("mcp", {
96
105
  description: "Show MCP server status",
97
106
  handler: async (args, ctx) => {
107
+ // Wait for init if still in progress
108
+ if (!state && initPromise) {
109
+ try {
110
+ state = await initPromise;
111
+ } catch {
112
+ if (ctx.hasUI) ctx.ui.notify("MCP initialization failed", "error");
113
+ return;
114
+ }
115
+ }
98
116
  if (!state) {
99
117
  if (ctx.hasUI) ctx.ui.notify("MCP not initialized", "error");
100
118
  return;
@@ -128,6 +146,15 @@ export default function mcpAdapter(pi: ExtensionAPI) {
128
146
  return;
129
147
  }
130
148
 
149
+ // Wait for init if still in progress
150
+ if (!state && initPromise) {
151
+ try {
152
+ state = await initPromise;
153
+ } catch {
154
+ if (ctx.hasUI) ctx.ui.notify("MCP initialization failed", "error");
155
+ return;
156
+ }
157
+ }
131
158
  if (!state) {
132
159
  if (ctx.hasUI) ctx.ui.notify("MCP not initialized", "error");
133
160
  return;
@@ -173,6 +200,17 @@ Mode: tool (call) > describe > search > server (list) > nothing (status)`,
173
200
  includeSchemas?: boolean;
174
201
  server?: string;
175
202
  }) {
203
+ // Wait for init if still in progress
204
+ if (!state && initPromise) {
205
+ try {
206
+ state = await initPromise;
207
+ } catch {
208
+ return {
209
+ content: [{ type: "text", text: "MCP initialization failed" }],
210
+ details: { error: "init_failed" },
211
+ };
212
+ }
213
+ }
176
214
  if (!state) {
177
215
  return {
178
216
  content: [{ type: "text", text: "MCP not initialized" }],
@@ -827,11 +865,12 @@ async function reconnectServers(
827
865
 
828
866
  state.registeredTools.set(name, toolNames);
829
867
 
830
- // Update tool metadata for searching
868
+ // Update tool metadata for searching (include inputSchema for describe/errors)
831
869
  const metadata: ToolMetadata[] = connection.tools.map(tool => ({
832
870
  name: formatToolName(tool.name, name, prefix),
833
871
  originalName: tool.name,
834
872
  description: tool.description ?? "",
873
+ inputSchema: tool.inputSchema,
835
874
  }));
836
875
  for (const resource of connection.resources) {
837
876
  if (definition.exposeResources !== false) {
@@ -863,11 +902,12 @@ async function reconnectServers(
863
902
  }
864
903
  }
865
904
 
866
- // Update status bar with new tool count
905
+ // Update status bar with server count
867
906
  if (ctx.hasUI) {
868
- const totalTools = [...state.registeredTools.values()].flat().length;
869
- if (totalTools > 0) {
870
- ctx.ui.setStatus("mcp", ctx.ui.theme.fg("accent", `MCP: ${totalTools} tools`));
907
+ const serverCount = state.registeredTools.size;
908
+ if (serverCount > 0) {
909
+ const label = serverCount === 1 ? "server" : "servers";
910
+ ctx.ui.setStatus("mcp", ctx.ui.theme.fg("accent", `MCP: ${serverCount} ${label}`));
871
911
  } else {
872
912
  ctx.ui.setStatus("mcp", "");
873
913
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-mcp-adapter",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "MCP (Model Context Protocol) adapter extension for Pi coding agent",
5
5
  "type": "module",
6
6
  "license": "MIT",