SO

schuyler/otterwiki-mcp

Developer tools
5 stars 5 forks Quality 79 Trend 33MIT

MCP for using Otterwiki as a research database

Overview

An MCP server that lets Claude read, write, search, and navigate an An Otter Wiki instance over Streamable HTTP. It sits between Claude (or any MCP client) and Otterwiki's REST API, translating tool calls into HTTP requests. It does not run inside Otterwiki — it's a standalone service. The included docker-compose.yml brings up Otterwiki (with API and semantic search plugins), ChromaDB, and the MCP server: The MCP endpoint will be at http://localhost:8090/mcp. The server supports two authentication methods: - (primary) — Used by Claude.ai. The server acts as its own OAuth authorization server, handling Dynamic Client Registration, PKCE, and token management. When both PLATFORM_DOMAIN and CONSENT_URL are set, SQLiteOAuthProvider is used: OAuth state is persisted to SQLite and a custom consent page handles user approval. When either variable is absent, the server falls back to InMemoryOAuthProvider: OAuth state is in-memory and a server restart requires re-authentication.

README

otterwiki-mcp

An MCP server that lets Claude read, write, search, and navigate an An Otter Wiki instance over Streamable HTTP.

It sits between Claude (or any MCP client) and Otterwiki’s REST API, translating tool calls into HTTP requests. It does not run inside Otterwiki — it’s a standalone service.

Tools

Tool What it does
read_note Read a page (optionally at a specific revision)
write_note Create or update a page with markdown + YAML frontmatter
delete_note Delete a page
list_notes List pages with optional filters (prefix, category, tag, date)
search_notes Full-text keyword search
semantic_search Vector similarity search via ChromaDB
get_links Show incoming/outgoing WikiLinks for a page
get_history Show revision history for a page
get_recent_changes Show recent edits across the wiki
find_orphaned_notes Find pages not linked from any index page

Running

The included docker-compose.yml brings up Otterwiki (with API and semantic search plugins), ChromaDB, and the MCP server:

cp .env.example .env   # fill in your secrets
docker compose up

The MCP endpoint will be at http://localhost:8090/mcp.

Configuration

All via environment variables:

Variable Required Default Description
OTTERWIKI_API_URL yes Base URL of the Otterwiki instance
OTTERWIKI_API_KEY yes API key for authenticating with Otterwiki
MCP_BASE_URL yes Externally-reachable URL of this MCP server (e.g. https://mcp.example.com). Used for OAuth discovery endpoints.
MCP_AUTH_TOKEN no Optional bearer token for Claude Code access. If set, clients can authenticate with Authorization: Bearer in addition to OAuth.
MCP_PORT no 8090 Port the MCP server listens on
PLATFORM_DOMAIN no Domain of the multi-tenant platform (e.g. robot.wtf). When set together with CONSENT_URL, enables SQLiteOAuthProvider with a persistent OAuth store and custom consent flow. When unset, the server falls back to InMemoryOAuthProvider (suitable for standalone/development use).
CONSENT_URL no Full URL of the OAuth consent page used when PLATFORM_DOMAIN is set (e.g. https://robot.wtf/auth/oauth/consent). Has no effect when PLATFORM_DOMAIN is unset.
SIGNING_KEY_PATH no /srv/data/signing_key.pem Path to the PEM signing key used to verify approval tokens in the consent flow. Only required when PLATFORM_DOMAIN and CONSENT_URL are set.

Authentication

The server supports two authentication methods:

  • OAuth 2.1 (primary) — Used by Claude.ai. The server acts as its own OAuth authorization server, handling Dynamic Client Registration, PKCE, and token management. When both PLATFORM_DOMAIN and CONSENT_URL are set, SQLiteOAuthProvider is used: OAuth state is persisted to SQLite and a custom consent page handles user approval. When either variable is absent, the server falls back to InMemoryOAuthProvider: OAuth state is in-memory and a server restart requires re-authentication.
  • Bearer token (optional) — Used by Claude Code. Enabled when MCP_AUTH_TOKEN is set. Clients send Authorization: Bearer in HTTP headers.

Connecting from Claude.ai

  1. In Claude.ai, go to Settings > Connectors > Add custom connector
  2. Enter the server URL (e.g. https://mcp.example.com/mcp)
  3. Leave Client ID and Client Secret blank — Dynamic Client Registration handles it
  4. Click Add

Connecting from Claude Code

Add to your MCP server configuration with the bearer token in headers:

{
  "mcpServers": {
    "otterwiki": {
      "type": "streamable-http",
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_MCP_AUTH_TOKEN"
      }
    }
  }
}

Deployment

Terminate TLS in front of the MCP server (nginx, Caddy, etc.) so tokens aren’t sent in cleartext.

Dependencies

Requires the otterwiki-api plugin installed in the Otterwiki instance. The otterwiki-semantic-search plugin is needed for the semantic_search tool.

Development

pip install -e ".[dev]"
pytest

License

MIT. See LICENSE for details.

View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "otterwiki": { "type": "streamable-http", "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer YOUR_MCP_AUTH_TOKEN" } } } }