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_DOMAINandCONSENT_URLare set,SQLiteOAuthProvideris used: OAuth state is persisted to SQLite and a custom consent page handles user approval. When either variable is absent, the server falls back toInMemoryOAuthProvider: OAuth state is in-memory and a server restart requires re-authentication. - Bearer token (optional) — Used by Claude Code. Enabled when
MCP_AUTH_TOKENis set. Clients sendAuthorization: Bearerin HTTP headers.
Connecting from Claude.ai
- In Claude.ai, go to Settings > Connectors > Add custom connector
- Enter the server URL (e.g.
https://mcp.example.com/mcp) - Leave Client ID and Client Secret blank — Dynamic Client Registration handles it
- 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.
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"
}
}
}
}