# pi-ask-mcp A minimal MCP stdio server that gives Claude **one** tool — `ask` — which routes structured questions back to pi's native ask UI instead of using Claude's built-in `AskUserQuestion`. This is **not** a regular pi extension. It is a subprocess of `claude`, which is itself a subprocess of the `chat-claude` extension. The pi-side counterpart is [`shared/pi-ask-bridge.ts`](../../shared/pi-ask-bridge.ts), which: 1. Opens a Unix-domain socket per chat session. 2. Generates an `--mcp-config` JSON pointing here, with `PI_ASK_SOCKET=`. 3. Translates `ask` requests off the socket into `askSingleQuestionWithInlineNote` / `askQuestionsWithTabs` calls and writes the result back. ## Architecture ``` pi └── chat-claude ├── pi-ask-bridge (UDS server, owns ui.custom) └── claude -p ... --mcp-config --disallowed-tools AskUserQuestion └── pi-ask-mcp/server.js (this file) ↳ on tools/call ask → connect $PI_ASK_SOCKET → ask → reply ``` ## Why a hand-written MCP server No `@modelcontextprotocol/sdk` dependency, no transpile step, no `node_modules`. The MCP stdio protocol is small enough (~6 method handlers) that writing it directly keeps the file self-contained and trivially portable. Claude CLI spawns it via `node server.js`. ## Wire format Stdio (with Claude): JSON-RPC 2.0 over newline-delimited JSON. Socket (with pi-ask-bridge): NDJSON, one request → one response, then close. ```jsonc // → pi { "id": "uuid", "type": "ask", "questions": [ { "id": "auth", "question": "Auth method?", "options": [{"label": "OAuth"}, {"label": "API key"}], "multi": false, "recommended": 0 } ] } // ← pi (success) { "id": "uuid", "type": "result", "results": [{ "id": "auth", "selectedOptions": ["OAuth"] }] } // ← pi (cancel / error) { "id": "uuid", "type": "error", "message": "cancelled" } ```