Commit 3c5a91
2026-03-15 06:15:32 Claude (MCP): [mcp] VS-2: Document persistent MCP OAuth implementation| /dev/null .. Dev/VS-2_MCP_OAuth_Summary.md | |
| @@ 0,0 1,60 @@ | |
| + | --- |
| + | category: reference |
| + | tags: |
| + | - vs-2 |
| + | - oauth |
| + | - mcp |
| + | - infrastructure |
| + | last_updated: 2026-03-15 |
| + | --- |
| + | |
| + | # VS-2: Persistent MCP OAuth for Claude.ai |
| + | |
| + | ## Problem |
| + | |
| + | The otterwiki-mcp server used FastMCP's `InMemoryOAuthProvider` for OAuth 2.1. All OAuth state (registered clients, authorization codes, access/refresh tokens) was lost on every server restart, forcing Claude.ai to re-authorize each time. |
| + | |
| + | ## Solution |
| + | |
| + | Replaced `InMemoryOAuthProvider` with `SQLiteOAuthProvider` — a drop-in persistent provider backed by a local SQLite database. |
| + | |
| + | ## Changes |
| + | |
| + | | File | Description | |
| + | |------|-------------| |
| + | | `otterwiki_mcp/oauth_store.py` | New SQLiteOAuthProvider implementing FastMCP's OAuthProvider interface | |
| + | | `otterwiki_mcp/server.py` | Swapped InMemoryOAuthProvider for SQLiteOAuthProvider | |
| + | | `otterwiki_mcp/config.py` | Added `MCP_OAUTH_DB` env var (default: `mcp_oauth.db`) | |
| + | | `tests/test_oauth_store.py` | 20 tests covering registration, auth flow, tokens, refresh, revocation, persistence | |
| + | | `tests/test_server_auth.py` | Updated to expect SQLiteOAuthProvider; uses `:memory:` DB for test isolation | |
| + | | `.gitignore` | Added `*.db` pattern | |
| + | |
| + | ## Configuration |
| + | |
| + | - **`MCP_OAUTH_DB`** — Path to the SQLite database file. Default: `mcp_oauth.db` in the working directory. Set to `:memory:` for ephemeral (test) usage. |
| + | |
| + | ## Token Lifetimes |
| + | |
| + | | Token Type | Expiry | |
| + | |------------|--------| |
| + | | Authorization code | 10 minutes | |
| + | | Access token | 1 hour | |
| + | | Refresh token | 30 days | |
| + | |
| + | ## Schema |
| + | |
| + | Three tables, auto-created on first use: |
| + | |
| + | - **oauth_clients** — Registered OAuth clients (client_id, full client JSON, created_at) |
| + | - **oauth_codes** — Authorization codes (code, client_id, redirect_uri, PKCE challenge, scopes, expiry, resource) |
| + | - **oauth_tokens** — Access and refresh tokens stored as paired rows (token, client_id, scopes, expiry, type, paired counterpart, resource) |
| + | |
| + | Token pairs are linked: revoking either token in a pair removes both. |
| + | |
| + | ## Branch |
| + | |
| + | `feat/persistent-oauth` on otterwiki-mcp repo. Not pushed, not merged. |
| + | |
| + | ## Test Results |
| + | |
| + | All 133 tests pass (20 new + 113 existing). |