# 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=<sock>`.
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 <generated.json> --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" }
```
