Skip to content

Add stdio transport support via bridge binary #4

@anatoly314

Description

@anatoly314

Problem

Some AI coding tools (Cursor, Antigravity, etc.) prefer or require stdio transport for MCP servers. The addon only supports HTTP transport because it runs inside Anki's process with uvicorn.

Adding native stdio to the addon is not possible - Anki owns the process and its stdin/stdout. However, a lightweight bridge binary can translate between stdio and HTTP.

Proposed Solution

An stdio-to-HTTP bridge that sits between the AI client and the Anki addon:

┌──────────────┐     stdio      ┌──────────────┐     HTTP      ┌──────────────┐
│  AI Client   │◄──────────────►│    Bridge    │◄──────────────►│  Anki Addon  │
│ (Cursor, etc)│  stdin/stdout  │              │  :3141        │  (FastMCP)   │
└──────────────┘                └──────────────┘                └──────────────┘

Quick Solution: mcp-remote

The existing mcp-remote npm package may already handle this:

{
  "mcpServers": {
    "anki": {
      "command": "npx",
      "args": ["mcp-remote", "http://127.0.0.1:3141"]
    }
  }
}

This needs to be validated with the addon's Streamable HTTP transport.

Custom Bridge (if mcp-remote doesn't work)

A minimal Python script:

#!/usr/bin/env python3
"""stdio-to-HTTP bridge for Anki MCP Server."""
import sys
import json
import httpx

SERVER_URL = "http://127.0.0.1:3141"
session_id = None

def forward_to_http(message: dict) -> dict:
    global session_id
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream",
    }
    if session_id:
        headers["mcp-session-id"] = session_id

    resp = httpx.post(SERVER_URL, json=message, headers=headers)

    if "mcp-session-id" in resp.headers:
        session_id = resp.headers["mcp-session-id"]

    return resp.json()

def main():
    for line in sys.stdin:
        line = line.strip()
        if not line:
            continue
        request = json.loads(line)
        response = forward_to_http(request)
        sys.stdout.write(json.dumps(response) + "\n")
        sys.stdout.flush()

if __name__ == "__main__":
    main()

Alternative: Go/Rust compiled binary

A single compiled binary with no runtime dependencies would be the best UX for distribution. Could be published as a GitHub release alongside the addon.

Client Configuration

With the bridge, AI tools configure stdio as usual:

{
  "mcpServers": {
    "anki": {
      "command": "/path/to/anki-mcp-bridge",
      "args": ["http://127.0.0.1:3141"]
    }
  }
}

Why Not Native stdio?

Anki owns its process - we can't take over stdin/stdout. The addon runs as a plugin inside Anki's Qt application, which uses stdin/stdout for its own purposes. HTTP transport is the natural fit for an in-process server; the bridge provides stdio compatibility externally.

Tasks

  • Validate mcp-remote works with the addon's Streamable HTTP transport
  • If not, create a minimal bridge script (Python or Node.js)
  • Document client configuration for stdio-based tools
  • Consider compiled binary (Go/Rust) for easier distribution

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions