Blame

780380 Claude (Dev) 2026-03-13 01:50:34
[mcp] Port original PRD MCP section to wiki
1
---
2
category: reference
3
tags: [meta, design, prd, mcp]
4
last_updated: 2026-03-12
5
confidence: high
6
---
7
8
# Original PRD MCP
9
10
> This page is part of the original single-tenant PRD, split across five wiki pages:
ada4de Claude (MCP) 2026-03-13 17:49:50
[mcp] Normalize spaces to underscores
11
> [[Design/Research_Wiki]] | [[Design/Rest Api]] | [[Design/Semantic_Search]] | [[Design/Mcp Server]] | [[Design/Note_Schema]]
780380 Claude (Dev) 2026-03-13 01:50:34
[mcp] Port original PRD MCP section to wiki
12
13
---
14
15
## Component 3: MCP Server
16
17
### Goal
18
19
Expose the wiki API as MCP tools over SSE so that Claude.ai can read, write, search, and navigate the wiki during conversations.
20
21
### Implementation
22
23
A standalone Python service using [FastMCP](https://github.com/jlowin/fastmcp) that translates MCP tool calls into HTTP requests to the Otterwiki REST API.
24
25
### Tools
26
27
| Tool Name | Description | Maps to API |
28
|-----------|-------------|-------------|
29
| `read_note` | Read a wiki page by path. Returns frontmatter + content + links. | `GET /api/v1/pages/<path>` |
30
| `write_note` | Create or update a wiki page. Accepts path, content, commit message. | `PUT /api/v1/pages/<path>` |
31
| `list_notes` | List pages. Optional filters: `prefix`, `category`, `tag`, `updated_since`. Filters compose with AND. | `GET /api/v1/pages?...` |
32
| `search_notes` | Full-text keyword search. | `GET /api/v1/search?q=...` |
33
| `semantic_search` | Semantic similarity search via Chroma. | `GET /api/v1/semantic-search?q=...&n=...` |
34
| `get_links` | Get incoming and outgoing WikiLinks for a page. | `GET /api/v1/links/<path>` |
35
| `get_recent_changes` | Get recent changelog entries. | `GET /api/v1/changelog?limit=...` |
36
| `delete_note` | Delete a wiki page. | `DELETE /api/v1/pages/<path>` |
37
| `find_orphaned_notes` | List pages not referenced in any index page. Used during gardening sessions to catch notes that fell through the cracks. | `GET /api/v1/pages` minus pages linked from any page with `category: index`. Implemented in the MCP server, not the API — it calls `list_notes` and `read_note` on index pages, then diffs. |
38
39
### Configuration
40
41
Environment variables:
42
43
- `OTTERWIKI_API_URL` — internal URL of Otterwiki (e.g., `http://otterwiki:80`)
44
- `OTTERWIKI_API_KEY` — API key for authentication
45
- `MCP_PORT` — port for SSE endpoint (default: 8090)
46
47
### Tool return format and error handling
48
49
MCP tools return plain text (not JSON) to Claude.ai, since the AI assistant is the consumer and reads text more efficiently than structured data. The MCP server is responsible for translating API JSON responses into readable text.
50
51
**Successful `read_note` return:**
52
53
```
54
# Iran Attrition Strategy
55
Path: Trends/Iran Attrition Strategy
56
Category: trend | Tags: military, p2-interceptor-race, p3-infrastructure
57
Confidence: high | Last updated: 2026-03-08
58
Links to: Variables/Interceptor Stockpiles, Propositions/Iran Rationing Ballistic Missiles, Actors/Iran, Trends/Desalination Targeting Ratchet
59
Linked from: Actors/Iran, Propositions/Iran Rationing Ballistic Missiles
60
61
---
62
[full markdown content here, including frontmatter]
63
```
64
65
**Successful `list_notes` return (with `category=proposition`):**
66
67
```
68
Found 2 notes matching category=proposition:
69
70
- Propositions/Iran Rationing Ballistic Missiles (proposition, 487 words, updated 2026-03-08)
71
- Propositions/Fertilizer Supply Chain Disruption (proposition, 312 words, updated 2026-03-07)
72
```
73
74
**Successful `list_notes` return (with `tag=p2-interceptor-race`):**
75
76
```
77
Found 4 notes matching tag=p2-interceptor-race:
78
79
- Trends/Iran Attrition Strategy (trend, 487 words, updated 2026-03-08)
80
- Variables/Interceptor Stockpiles (variable, 342 words, updated 2026-03-08)
81
- Propositions/Iran Rationing Ballistic Missiles (proposition, 487 words, updated 2026-03-08)
82
- Actors/Gulf States (actor, 523 words, updated 2026-03-07)
83
```
84
85
**Successful `list_notes` return (with `updated_since=2026-03-08`):**
86
87
```
88
Found 5 notes updated since 2026-03-08:
89
90
- Events/2026-03-08 New Iranian Supreme Leader Selected (event, 189 words, updated 2026-03-08)
91
- Events/2026-03-08 Russia Providing Targeting Intelligence (event, 234 words, updated 2026-03-08)
92
- Trends/Iran Attrition Strategy (trend, 487 words, updated 2026-03-08)
93
- Variables/WTI Oil Price (variable, 156 words, updated 2026-03-08)
94
- Variables/Interceptor Stockpiles (variable, 342 words, updated 2026-03-08)
95
```
96
97
**Successful `semantic_search` return:**
98
99
```
100
3 results for "strategy for depleting Gulf air defenses":
101
102
1. Trends/Iran Attrition Strategy (distance: 0.34)
103
Iran is executing a multi-phase attrition campaign designed to degrade Gulf state and US defensive capacity...
104
105
2. Variables/Interceptor Stockpiles (distance: 0.41)
106
Tracking estimated remaining interceptor inventories across Gulf state Patriot and THAAD batteries...
107
108
3. Propositions/Iran Rationing Ballistic Missiles (distance: 0.48)
109
The 86% drop in ballistic missile launch rates reflects deliberate rationing, not destroyed capability...
110
```
111
112
**Error handling:**
113
114
Tools should return **clear, actionable error messages** — never raw exceptions or stack traces. The MCP server catches HTTP errors from the API and translates them:
115
116
| API status | MCP tool returns |
117
|------------|------------------|
118
| 404 | `Page not found: Actors/Iran. Use write_note to create it, or list_notes to see available pages.` |
119
| 401 | `Authentication failed. The API key may be misconfigured.` |
120
| 409 | `Conflict: the page was modified since last read. Read the page again to get the current version, then retry.` |
121
| 422 | `Invalid request: [detail from API error message]` |
122
| 500 / timeout | `The wiki API is not responding. It may be restarting. Try again in a few seconds.` |
123
124
The guiding principle: errors should help Claude (the AI) take a useful next action, not just report what went wrong.
125
126
### SSE endpoint
127
128
The MCP server exposes an SSE endpoint at `https://<host>/mcp` (behind reverse proxy with TLS). This URL is added to Claude.ai's MCP server connections.