Skip to content

MCP & AI integrations

The Model Context Protocol (MCP) lets AI assistants read and (with the right API key scopes) update your team knowledge base through tools such as search, list documents, and create/update document.

Orimora ships two MCP transports:

  1. HTTP endpoint at /api/mcp — recommended for remote access. Uses the MCP Streamable HTTP transport. Authenticate with an API key as Bearer token.
  2. stdio server in the repository — for local development. You point your MCP client at yarn mcp.

Enabling MCP is a team-admin action. It is gated by the developer.mcp permission, which controls turning the MCP endpoint on or off and managing connected apps. By default only the Admins group has it — the Editors, Members, and Viewers groups do not.

So if you don’t see the MCP Server section under Settings → Developers, you’re missing this permission: ask a workspace admin to enable MCP, or to grant your group the developer.mcp capability under Settings → Groups.

  • A team admin (or the developer.mcp permission) to turn MCP on — see above.
  • For Cursor, Claude Desktop, or Obsidian: nothing more — these connect with a personal API key (kb_…) you create in Settings → Developers.
  • For the Claude mobile app or claude.ai custom connectors: your Orimora must be reachable at a public https:// address. Phones can’t reach localhost, and the OAuth login requires HTTPS. Self-hosters set this via APP_URL (see the caution below); on hosted Orimora it already is. Nothing else to configure — login and discovery are built in, with no key to copy.
  1. Turn MCP on. In the web app: Settings → Developers → MCP Server (HTTP) → toggle on. The page then shows your connection URL ({APP_URL}/api/mcp) and the copy buttons.
  2. Connect your client. Follow the matching section below:
  3. Verify and manage access. Once connected, your assistant can search and — with write access — edit documents. Apps connected via OAuth appear under Settings → Developers → Authorized Apps with their scope and last-used date; revoke any of them there to cut access immediately.
  • Same stack as Installation: Node.js, Yarn, PostgreSQL, and a working .env with at least DATABASE_URL (and the other required secrets described there).
  • An API key from the web app: Settings → Developers. Copy the full token once (format kb_…). The MCP server validates it against the database like the REST API.

The HTTP endpoint is available at {APP_URL}/api/mcp (for example https://your-domain.com/api/mcp) and must be enabled per team in Settings → Developers → MCP Server (HTTP). Only team admins can toggle MCP.

Authentication uses Bearer tokens — the same API keys from Settings → Developers.

  1. In the web app, go to Settings → Developers and turn on MCP Server (HTTP).
  2. Under API keys, create a key with the scopes you need (write if tools should create or edit documents). Copy the full token once — it starts with kb_.
  3. Use the Copy endpoint URL and Copy Cursor MCP JSON buttons on the same page (they appear when MCP is enabled). In the JSON, replace YOUR_API_KEY with your real kb_… token.
  4. Merge the mcpServers entry into Cursor’s MCP config:
    • All projects (user): ~/.cursor/mcp.json on macOS/Linux, or the path shown in Cursor Settings → MCP for your OS.
    • Single repository: .cursor/mcp.json at the repo root.
  5. Restart Cursor or use Reload MCP / restart the MCP host so the new server is picked up.
{
"mcpServers": {
"orimora": {
"url": "https://your-domain.com/api/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}

Replace https://your-domain.com with your instance URL and YOUR_API_KEY with the full kb_… key.

Claude Desktop (HTTP via mcp-remote bridge)

Section titled “Claude Desktop (HTTP via mcp-remote bridge)”

Claude Desktop’s claude_desktop_config.json only speaks stdio. To use the Orimora HTTP endpoint from the config file, route through the mcp-remote bridge — a small Node helper that translates between stdio (what Claude speaks) and HTTP+Bearer (what Orimora speaks).

Open Claude Desktop → Settings → Developer → Edit Config (or edit the file directly — on macOS at ~/Library/Application Support/Claude/claude_desktop_config.json) and merge:

{
"mcpServers": {
"orimora": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://your-domain.com/api/mcp",
"--header",
"Authorization:${AUTH}"
],
"env": {
"AUTH": "Bearer YOUR_API_KEY"
}
}
}
}

Notes:

  • Keep the token in env.AUTH and reference it via ${AUTH} in --header. That way the key is in the process environment, not in the command line (it won’t leak into ps).
  • Do not put a space between Authorization: and ${AUTH} — some mcp-remote versions drop everything after the first space in --header.
  • After editing, fully quit Claude Desktop (⌘Q on macOS) and relaunch. Closing only the window is not enough.
  • On macOS, Claude Desktop does not always inherit your shell PATH. If npx is not found, use an absolute path (which npx).

You can sanity-check the bridge before touching Claude’s config:

Terminal window
npx -y mcp-remote https://your-domain.com/api/mcp \
--header "Authorization:Bearer kb_…"

If that process starts cleanly (no 401), the same config will work in Claude Desktop.

Send standard MCP Streamable HTTP requests:

  • POST /api/mcp — MCP JSON-RPC messages
  • GET /api/mcp — SSE stream for server-initiated messages
  • DELETE /api/mcp — session cleanup

All requests require the Authorization: Bearer kb_… header.

The three flows above use a static kb_… API key — perfect for Cursor, Claude Desktop and Obsidian. The Claude mobile app and claude.ai Custom Connectors instead expect an OAuth 2.1 flow: you paste a URL, a browser opens, you log in and approve, and the app receives its own token. Orimora supports this out of the box — no API key to copy.

Setup:

  1. In Orimora, enable MCP for your team: Settings → Developers → MCP Server → toggle on.
  2. In the Claude app, add a custom connector and enter your Orimora MCP endpoint URL — it must include the /api/mcp path, e.g. https://wiki.example.com/api/mcp (the same endpoint as Option 1, just without an API key). Do not enter the bare domain (https://wiki.example.com) — that hits the homepage and returns 405, so OAuth never starts. From the 401 at /api/mcp the app discovers the OAuth flow automatically via /.well-known/oauth-protected-resource.
  3. Your browser opens an Orimora login → consent screen. Approve the requested access (read, or read + write).
  4. Done. The app holds a short-lived access token (auto-refreshed) scoped to your team.

Managing access: every connected app appears under Settings → Developers → Authorized Apps with its granted scope and last-used date. Revoke there to immediately invalidate its tokens — the app must re-authorize to reconnect.

Clients discover these automatically; listed here for operators and debugging. All are derived from APP_URL (the issuer):

EndpointPurpose
/.well-known/oauth-protected-resourceRFC 9728 protected-resource metadata
/.well-known/oauth-authorization-serverRFC 8414 authorization-server metadata
POST /oauth/registerDynamic Client Registration (RFC 7591)
GET/POST /oauth/authorizeAuthorization + consent (PKCE S256)
POST /oauth/tokenToken issue + refresh (rotation)
POST /oauth/revokeToken revocation (RFC 7009)

Full configuration (TTLs, CORS origins, allowed app schemes, rate limit, token secret) is in the Configuration reference → MCP OAuth.

Option 2: stdio server (local development)

Section titled “Option 2: stdio server (local development)”

For local development with direct database access, you can use the stdio transport:

Terminal window
export ORIMORA_API_KEY="kb_your_full_token_here"
yarn mcp

The process uses stdio — it is meant to be spawned by an MCP client, not browsed in a browser.

Under the hood this runs tsx with tsconfig.mcp.json and src/mcp-server/index.ts (see the mcp script in package.json).

{
"mcpServers": {
"orimora": {
"command": "yarn",
"args": ["mcp"],
"cwd": "/absolute/path/to/orimora-repo",
"env": {
"ORIMORA_API_KEY": "kb_…",
"DATABASE_URL": "postgresql://user:pass@host:5432/dbname"
}
}
}
}
  • cwd must be the Orimora repo root so dependencies and path aliases resolve.
  • If your client loads .env for you, you may omit duplicate variables — otherwise pass DATABASE_URL explicitly.

Use the same pattern: command + args + working directory + environment with ORIMORA_API_KEY and DATABASE_URL.

create_document, update_document, append_to_document, prepend_to_document, and insert_after_heading accept the document body as Markdown via the markdown parameter. The server converts it to the TipTap/ProseMirror JSON the editor needs (via markdown-it → HTML → the shared TipTap schema).

Do not send TipTap/ProseMirror JSON through MCP. The tools do not expose a content field. Sending raw editor JSON would require the client to know every extension and attribute in use, which drifts over time and silently strips unknown nodes.

get_document mirrors this and returns the body only as markdown (no TipTap JSON), keeping payloads small and forcing clients into the same format on both read and write.

Round-tripped (write and read): headings (H1–H6) including heading IDs (### Title {#anchor}), paragraphs, bold, italic, inline code, ~~strike~~, <u>underline</u>, highlight (==x==), subscript (~x~), superscript (^x^), footnotes ([^1] references + [^1]: text definitions), emoji shortcodes (:joy: → 😂, stored as Unicode), ordered lists (including custom start index), unordered lists, nested lists, task lists (- [ ] / - [x]), block quotes, fenced code blocks with language hint, horizontal rules, GFM tables, links, and images via external URLs.

Not currently supported via MCP (tracked in the internal backlog):

  • Definition lists (term / : def) — not yet rendered by the editor; avoid them on write for now (backlog Tier 3).
  • Inline base64 images in Markdown — rejected. Use the upload_image tool to attach an image to a document, or reference an externally reachable URL.

If you need the absolute Markdown source at any time, call get_document — it returns a markdown string that is byte-for-byte representative of what the editor will display.

For existing documents, prefer targeted edits over full rewrites:

  • append_to_document(id, markdown) — appends a Markdown fragment to the end of the body, separated by a blank line.
  • prepend_to_document(id, markdown) — inserts a fragment at the top.
  • insert_after_heading(id, heading, markdown) — inserts directly after the first heading whose text matches heading (case-insensitive, trimmed). Returns HEADING_NOT_FOUND if no match, in which case callers should fall back to append_to_document.

All three preserve existing content, require write scope and write access to the document, and run the same Markdown → TipTap conversion as create_document.

delete_document performs a soft delete (the document is moved to trash and can be restored from the app). It is a two-step action:

  1. Call without confirm — the server returns { status: "confirm_required", preview: { title, collectionName, bodyLength, … } } so the agent can present the user with what is about to be deleted.
  2. Call again with confirm: true — the server moves the document to trash and returns { status: "deleted", id, deletedAt }.

Hard deletes are not exposed through MCP. Empty the trash from the app when permanent removal is required.

API keys support:

  • Scopes: read, write, admin — MCP tools that mutate content require write where applicable.
  • Restricted mode: optional allowlists per collection and per-document overrides, configured in the app under Settings → Developers → Configure access. The same rules apply to MCP and to /api/v1/.

Read-only “Second Brain” vs. writable collections

Section titled “Read-only “Second Brain” vs. writable collections”

Typical agent setup: one collection acts as a read-only knowledge base for the AI, another collection is a scratchpad the AI is allowed to write into. A single API key is enough — restricted mode applies per-collection overrides, so one key can hold read on the knowledge base and read+write on the scratchpad.

Under Settings → Developers → Configure access for that key:

  1. Turn on Restricted mode.
  2. Set the knowledge-base collection to Read only.
  3. Set the working collection to Read + write.
  4. Set everything else to No access.

The MCP tools expose a canWrite flag on every collection returned from list_collections (and on each get_document response). Agents should inspect that flag before attempting create_document / update_document / append_to_document / delete_document rather than trial-and-erroring.

For a short maintainer checklist (dev server URL, health check, internal notes), see internal/dev-and-mcp.md in the repository.