Docs · MCP
Connect your AI
A reference for plugging an MCP-speaking agent into writespace. Setup, client configs, every tool, and the format details that matter when an agent is reading or writing your docs.
Setup
Three steps. Two minutes.
-
01
Create a personal access token
Sign in to app.writespace.io, open Settings → API tokens, click Create token, and copy it. Tokens are shown once. Revoke any time from the same screen.
-
02
MCP endpoint
One hosted endpoint for all writespace.io accounts:
https://app.writespace.io/mcp -
03
Wire it into your client
Drop the endpoint and a
Bearertoken into your client's MCP config. Snippets for the major clients below.
Client configs
All four use HTTP MCP + Bearer auth — only the config file location differs.
{
"mcpServers": {
"writespace": {
"type": "http",
"url": "https://app.writespace.io/mcp",
"headers": {
"Authorization": "Bearer ws_pat_…"
}
}
}
}
claude mcp add --transport http writespace \
https://app.writespace.io/mcp \
--header "Authorization: Bearer ws_pat_…"
// Type: HTTP
// URL: https://app.writespace.io/mcp
// Header: Authorization: Bearer ws_pat_…
{
"mcpServers": {
"writespace": {
"httpUrl": "https://app.writespace.io/mcp",
"headers": {
"Authorization": "Bearer ws_pat_…"
}
}
}
}
Tool reference
Every tool except list_workspaces
takes a workspace_id — call
list_workspaces first to discover them.
folder_id scope. Returns metadata on every row.
<<match>> snippets. Use as RAG retrieval directly.
@>). e.g. { status: "accepted" }.
content (Tiptap JSON) or content_markdown. Lean response by default.
null deletes a key. Open editors reload.
folder_id: null to send it to root.
parent_id for nesting.
Things to know
Content format
Reads return both content
(lossless Tiptap JSON) and
content_markdown
(convenience). Writes accept either.
Markdown round-trips for everything the editor supports — headings, bold/italic/strike/code, links, lists, task lists, blockquotes, fenced code with language, tables, horizontal rules, mermaid diagrams.
Lean write responses
create_doc,
update_doc,
upsert_doc,
append_to_doc, and
move_doc return only
metadata by default. Saves 80–95% of the payload on long docs.
Pass include_content: true
to echo the body back.
Structured metadata
Every doc has a JSONB metadata
field. Read, write, and query as first-class structured data.
Write:
metadata: { status: "draft" };
shallow-merge on update; null deletes.
Query: query_docs
with where: { status: "accepted" }.
Cross-doc links
Reference docs by stable ID, not by title:
[Container diagram](writespace://doc/3873bc94-…)
The editor routes clicks internally. IDs survive renames and moves.
Live editing
MCP writes broadcast a reload over Realtime. Open editors refetch in the same tab. Last write wins — no merge between an in-progress live edit and a concurrent MCP write.
If the broadcast is dropped, refreshing picks up the change.
Markdown gotchas
Bare-URL autolinking is off.
CLAUDE.md stays as plain text.
Use [label](url) or
<https://…>.
Raw HTML is ignored.
Images aren't a supported node yet — image
syntax drops to its alt text.
Troubleshooting
401 invalid or missing personal access token
Token is wrong, revoked, or the
Authorization header
isn't being sent. Format:
Authorization: Bearer ws_pat_….
Tokens are shown once at creation — regenerate if lost.
-32000 error from a tool call
The underlying Postgres call failed; the error message has the
cause. Most commonly: the
workspace_id
doesn't belong to you, or the doc/folder ID doesn't exist.
Tool changes don't appear in the open editor
The Realtime broadcast was dropped. Refreshing picks up the change. MCP writes never block — they just notify.