Claude connector (MCP)
CompassDocs ships a built-in MCP server at
/api/mcp. Connect it to the Claude desktop app and Claude can search your
knowledge base, read documents, create new articles as markdown, and
revise existing ones — all as you, with your CompassDocs role and your
workspace’s approval rules.
Typical flow: brainstorm and draft an article with Claude in the desktop app, then say “save that to CompassDocs in the Engineering space” — done. Later: “pull up the runbook we wrote last week and tighten the intro”.
Connect Claude — one click
Section titled “Connect Claude — one click”In the Claude desktop app (or on claude.ai with a paid plan):
- Settings → Connectors → Add custom connector
- Paste your CompassDocs MCP URL:
https://YOUR-COMPASSDOCS-HOST/api/mcp - Click Add, then Connect — your browser opens CompassDocs, you sign in (if you weren’t already), and click Approve.
That’s it. CompassDocs ships its own OAuth authorization server, so Claude registers itself, you approve once in the browser, and tokens are issued and refreshed automatically — nothing to copy, no config files. Manage or disconnect apps anytime under Manage account → API tokens → Connected apps.
Alternative: personal API token (any MCP client)
Section titled “Alternative: personal API token (any MCP client)”For MCP clients without the one-click flow, use a personal token instead:
- In CompassDocs: Manage account → API tokens → create a token (shown once; the page includes a ready-made config snippet).
- In Claude Desktop’s
claude_desktop_config.json(requires Node.js fornpx):
{ "mcpServers": { "compassdocs": { "command": "npx", "args": [ "-y", "mcp-remote", "https://YOUR-COMPASSDOCS-HOST/api/mcp", "--header", "Authorization: Bearer cdk_YOUR_TOKEN" ] } }}What Claude can do
Section titled “What Claude can do”| Tool | Who can use it | What it does |
|---|---|---|
list_spaces |
everyone | Spaces with slugs, to file new docs correctly |
list_docs / search_docs |
everyone | Browse or full-text search (viewers see published only) |
read_doc |
everyone | Full markdown body plus metadata — including path, sub-pages, and backlinks when nested pages & backlinks are enabled |
writing_guide |
everyone | The full authoring reference — every rich block with exact syntax |
list_templates |
everyone | The workspace’s document templates with their full scaffolds |
create_doc |
editor + | New document from markdown — drafts by default; pass template to use a template’s structure, type, and tags |
update_doc |
editor + | Replace body / metadata, change type, move spaces, or publish — with a version note |
add_image |
editor + | Put an image on a document — fetched from a URL, copied from another attachment, or base64 — and optionally place it in the body in the same call |
request_upload |
editor + | Mint a single-use link a person can drop an image file into, for a picture Claude can’t send itself |
create_training_deck |
training manager | Turn a published doc into a training deck (enterprise training entitlement) |
assign_training |
training manager | Assign a deck by usernames or to everyone — assignees are notified |
training_status |
training manager | Deck list with completion counts, or one deck’s per-person status incl. quiz scores |
Claude writes with the full editor toolbox
Section titled “Claude writes with the full editor toolbox”The connector isn’t limited to plain markdown. The writing_guide tool hands
Claude the same block vocabulary the in-app editor offers — callouts, tabs,
accordions, interactive checklists, Mermaid and PlantUML diagrams, decision
trees, video and website embeds, and auto-filterable tables — with exact
syntax, and the server instructions tell Claude to consult it before writing.
Ask Claude for a runbook with a decision tree and platform tabs, and the
document it saves renders those blocks interactively in the app, just as if
it had been written in the editor.
Images & screenshots
Section titled “Images & screenshots”Getting a picture into a document is the one thing an assistant is worst at, and the reason is worth knowing: Claude usually cannot send you the bytes.
A screenshot you paste into a conversation reaches Claude as an image it can see, not as a file it holds. There is no byte-level copy for it to re-emit, so asking it to “upload that screenshot” cannot work no matter how the request is phrased. Separately, base64 encoding inflates a file by a third, so even a file Claude can read is usually far too large to fit inside a single tool argument — a 300 KB screenshot becomes ~400,000 characters.
From 1.1 there are four ways in, and Claude picks between them:
| Route | When it’s used |
|---|---|
source_url |
The image has a public address. Your server fetches it, so size stops mattering. This is the best route whenever it applies. |
from_attachment_id |
The image is already attached to a document in this workspace. It’s copied onto the new document, so deleting the original never blanks the copy. |
request_upload |
The picture only exists as something you can see or have on disk. Claude gives you a link to drop it into (below). |
data |
Raw base64. Still supported, still fine for small files. |
PNG, JPEG, GIF, and WebP are accepted — the type is sniffed from the bytes, so
a mislabelled .png is refused rather than rendering broken, and SVG is
rejected. The image is stored as a normal document
attachment, capped by the workspace attachment size
limit.
Placing it, in the same call
Section titled “Placing it, in the same call”add_image takes an insert option: "append" puts the image at the end of
the document, "top" at the beginning, and "none" (the default) returns just
the markdown snippet for Claude to place itself. Appending edits only the text
around the image, so it is safe against someone editing the same document at
the same time.
Ask for “add this to the runbook” and you get the image in the runbook, not an attachment you then have to ask about again.
Drop links
Section titled “Drop links”When Claude can’t produce the file — the screenshot-in-the-chat case — it calls
request_upload and hands you a link like
https://docs.example.com/upload/mBvR…. Open it, drag the file in (or paste it,
or browse for it), and the image is attached to the document and placed in the
body automatically. Nothing further to ask Claude for.
The page needs no sign-in on purpose: the screenshot is usually on your phone while Claude is running on your laptop. Each link is:
- single-use and tied to one document
- valid for one hour
- image-only, through the same type check as every other route
- minted only by someone who already had edit rights on that document — and the upload is recorded in the audit log as that person
If a link is expired or already used, the page says so plainly rather than accepting a file that would go nowhere. Ask Claude for a new one.
Approvals still apply
Section titled “Approvals still apply”The connector goes through exactly the same rules as the app:
- Creating: new docs are drafts unless you ask Claude to publish and your role (or open approval mode) allows it — otherwise they stay drafts.
- Editing a published doc as an editor in strict mode files a change request into the review queue instead of touching the live page. Claude is told this and will relay it.
- Publishing a draft (
update_docwith publish) works the same way: approvers and admins publish immediately; an editor’s publish request is queued for review in strict mode. - Adding an image (
add_image,request_upload) requires edit rights on the document’s space, exactly like editing it — and every upload is audited, including images that arrive through a drop link. - Every action lands in the audit log, marked as coming via the connector.
- The token travels in an
Authorizationheader over HTTPS — use a proper HTTPS deployment (see Custom domain & HTTPS if you haven’t set that up). - One-click connections use short-lived OAuth tokens with automatic rotation; personal tokens are long-lived — one per device/app is good hygiene. Both are listed (with last-used times) and revocable on the tokens page.
- The same endpoint works with any MCP client, not just Claude Desktop.
Troubleshooting: “Authorization failed”
Section titled “Troubleshooting: “Authorization failed””If the one-click connector fails at the sign-in step with a generic
“Authorization with … failed”, “unable to connect to the sign-in
service” (or an ofid_… reference), the OAuth handshake couldn’t complete.
Claude’s servers reach your server over the public internet, fetch its
discovery documents, and complete the token exchange — so the usual cause is
that the discovery metadata advertises URLs Claude can’t use.
Start with the built-in check: Settings → System → Diagnostics has a
Claude connector (MCP) row that shows exactly which sign-in URL your
install advertises, probes it from the server, and says what to fix — a plain
http:// issuer, a stale custom domain, or a reverse proxy that isn’t
forwarding X-Forwarded-Proto.
To verify from the outside too, run this from any machine outside your network:
curl https://YOUR-COMPASSDOCS-HOST/.well-known/oauth-authorization-serverEvery URL in the JSON (issuer, authorization_endpoint, token_endpoint,
registration_endpoint) must start with https:// and your real public
host. If they show http://, a LAN address, or the wrong host, that’s the
problem:
- Set your domain in the app. Under Settings → Domain & HTTPS, make sure the custom domain is filled in. As of 0.59.1, when a custom domain is configured CompassDocs advertises its OAuth endpoints over HTTPS at that domain regardless of what your proxy forwards — which fixes the most common case on its own.
- Behind your own reverse proxy? If the metadata still shows
http://, your proxy isn’t forwardingX-Forwarded-Proto: https. See Behind your own reverse proxy. - Reachability & TLS. The host must be reachable from the public internet
over HTTPS with a valid (CA-signed) certificate. A self-signed cert, a
LAN/VPN-only address, or
localhostwill fail — Claude’s servers dial the endpoint directly. - Public DNS, not just internal DNS. The hostname must resolve on the
public internet. If your browser opens the site but Claude reports it
can’t connect, check from outside your network:
nslookup YOUR-HOST 8.8.8.8. An install that only exists in internal DNS (split-horizon) is invisible to Claude’s servers — see below. - “Your account was authorized, but the integration rejected the
credentials it just issued.” Sign-in completed, but the follow-up MCP
call — the only request that carries its credentials in an
Authorization: Bearerheader rather than the request body — bounced with a 401. Something between Claude and the app is intercepting that header or the call itself. The usual suspects: Cloudflare’s orange-cloud proxy (switch the record to DNS-only, or exempt/api/mcpand/api/oauth/*from WAF/bot rules), an IIS site with Windows or Basic authentication enabled (use Anonymous only), or a reverse proxy that clears theAuthorizationheader. To confirm: a request with a personal API token against/api/mcpsucceeds directly on the server but fails through the proxy.
Internal-only installs (no public DNS)
Section titled “Internal-only installs (no public DNS)”The one-click connector runs from Anthropic’s servers, so it can only reach installs with a public DNS name. If your CompassDocs deliberately lives on internal DNS or behind a VPN, pick one of these:
Option A — expose the hostname publicly (recommended). Add a public DNS record for the same hostname, terminate TLS with a CA-signed certificate at your reverse proxy, and (if you want to stay locked down) restrict inbound traffic at the proxy or firewall. Users keep signing in exactly as before; the connector just becomes reachable.
Option B — a local bridge in Claude Desktop. Claude Desktop can run a local MCP process on each user’s machine, inside your network, where internal DNS works. Each user creates a personal token under your name → API tokens, then adds this to Claude Desktop’s MCP settings:
{ "mcpServers": { "compassdocs": { "command": "npx", "args": [ "-y", "mcp-remote", "https://docs.internal.example.com/api/mcp", "--header", "Authorization: Bearer YOUR-PERSONAL-TOKEN" ] } }}This works only in the desktop app (claude.ai on the web still connects from the cloud), needs per-machine setup, and the token acts with that user’s role — revocable anytime from the same API tokens page.
