Skip to content

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”.

In the Claude desktop app (or on claude.ai with a paid plan):

  1. Settings → Connectors → Add custom connector
  2. Paste your CompassDocs MCP URL: https://YOUR-COMPASSDOCS-HOST/api/mcp
  3. 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:

  1. In CompassDocs: Manage accountAPI tokens → create a token (shown once; the page includes a ready-made config snippet).
  2. In Claude Desktop’s claude_desktop_config.json (requires Node.js for npx):
{
"mcpServers": {
"compassdocs": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://YOUR-COMPASSDOCS-HOST/api/mcp",
"--header",
"Authorization: Bearer cdk_YOUR_TOKEN"
]
}
}
}
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.

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.

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.

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.

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_doc with 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 Authorization header 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:

Terminal window
curl https://YOUR-COMPASSDOCS-HOST/.well-known/oauth-authorization-server

Every 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 forwarding X-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 localhost will 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: Bearer header 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/mcp and /api/oauth/* from WAF/bot rules), an IIS site with Windows or Basic authentication enabled (use Anonymous only), or a reverse proxy that clears the Authorization header. To confirm: a request with a personal API token against /api/mcp succeeds directly on the server but fails through the proxy.

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.