Skip to main content
Glama
README.md
# AIPI Bridge MCP

SSE-transport MCP server exposing a curated slice of Bot Army to external MCP
clients that only speak SSE — specifically [AIPI](https://aipi.com)'s "Custom
MCPs" skill config, which documents SSE as the only currently supported
format.

Deliberately narrow, not a generic `bridge.*` passthrough: this is meant to be
reachable from a third-party vendor's cloud (via ngrok), not a trusted local
dev session, so it exposes exactly three tools instead of letting a caller
invoke arbitrary bridge subjects. For local/trusted MCP clients that want the
full surface (any `bridge.*` subject, NATS observe, registry queries), use
[`tools/nats-gateway-mcp`](../nats-gateway-mcp) instead — stdio transport,
generic `bridge_request` tool.

## Tools

| Tool | Purpose |
|------|---------|
| **bridge_chat** | Ask Bot Army a question via the ChatResponder (tasks, bots, system status). |
| **gtd_task_list** | List GTD tasks. |
| **gtd_task_create** | Create a GTD task. Appends a `## Verification` block if the caller didn't include one (matches `.claude/skills/gtd/skill.md`). Only reports success if the bridge response includes a concrete `task_id` — a bare "ok" or empty reply is treated as a failure, not a success. |
| **gtd_task_complete** | Mark a task complete. |
| **gtd_task_search** | Search tasks by text, with optional status/context filters. |
| **internal_docs_query** | Semantic search over the internal docs corpus. |
| **random_roll** | Dice roll (`bridge.random.roll`) — pure novelty, stateless, no data exposure. |

**Deliberately not exposed:** `bridge.task.update` (a misheard voice command could silently mutate an existing task's fields with no confirmation screen — if wanted later, scope it to `status→completed` only, i.e. reuse `gtd_task_complete`'s shape rather than open-ended field updates) and `bridge.project.*` (`bridge.project.list` is a known-broken responder as of 2026-08-15 — returns empty despite tasks carrying project_ids).

## Setup

1. **Build** (from repo root or this directory):

   ```bash
   cd tools/aipi-bridge-mcp && npm install && npm run build
   ```

2. **Run**

   ```bash
   NATS_URL=nats://localhost:4222 \
   AIPI_BRIDGE_MCP_PORT=39895 \
   AIPI_BRIDGE_MCP_TOKEN=<pick-a-token> \
   npm start
   ```

   - `AIPI_BRIDGE_MCP_TOKEN` is required before tunneling this externally — without it the SSE endpoint is unauthenticated. Server logs a warning on startup if it's unset.
   - SSE endpoint: `GET /sse` (requires `Authorization: Bearer <token>`), message endpoint: `POST /messages?sessionId=...`, health check: `GET /health` (no auth).

3. **Expose it**

   Same pattern as everything else externally-reachable in this repo: tunnel via `air.ngrok` (reserve a port label, e.g. `surface-aipi-mcp`), point AIPI's Custom MCP config at the resulting HTTPS URL + `/sse`, with the bearer token in whatever auth field their SSE MCP config exposes.

## Requirements

- Node.js 18+
- NATS server reachable at `NATS_URL` — use prod (`nats://localhost:4222`) for real bridge responses; `bridge.chat` / `bridge.task.*` only have responders on the production cluster, not dev (`4223`).

## Development

- `npm run build` — compile TypeScript to `dist/`
- `npm run dev` — run with tsx (no build) for quick iteration
- Verified end-to-end against dev NATS (`4223`) with a throwaway MCP client: SSE handshake, `tools/list`, and `tools/call` all round-trip correctly; tool calls correctly report failure (NATS `503 no responders`) rather than fabricating a success, since nothing listens on `bridge.chat` / `bridge.task.list` on the dev cluster. Full happy-path verification needs a run against prod NATS.