Developer

Model Context Protocol

Capacities Pro

Overview

Build your own app, agent, or bot and integrate it with a Capacities space by implementing a custom MCP client using the Model Context Protocol (MCP) open standard. We host a server that provides secure access to a selected Capacities space via OAuth 2.1 (including PKCE, Dynamic Client Registration, and refresh tokens).

Supported tools

You can connect the Capacities MCP server to all AI tools that support the MCP protocol and connection via oAuth.

  • If you want to use an existing AI chat app (no custom development), see AI Chat Connectors.
  • If you want to build your own integration, continue below.

Available tools

Permissions access: read

Searches across your space via keywords. Results include:

  • Object ID
  • Object title
  • Object Type
  • Properties and content snippet

Search uses both title search and semantic search to find and rank the best results.

Example prompt: "Find all Painting objects related to Claude Monet."

getObjectContent

Permissions access: read

Retrieves all content and properties from a specific object in markdown format.

Example prompt: "Read my highlights on The Happiness Hypothesis in Capacities and summarize the most important concepts."

Permissions access: read

Generates a valid URL to access a specific object.

Example prompt: "Give me a link to my Cheesecake recipe in Capacities."

saveToDailyNote

Permissions access: write

Stores text within today's daily note.

Example prompt: "Send your conclusions about why folder structures don't work to my Capacities daily note."

createPage

Permissions access: write

Creates a simple Page object with a title and markdown content.

Example prompt: "Create a Capacities page titled 'Weekly review template' with my checklist as markdown."

createTask

Permissions access: write

Creates a Task object with a title, status, priority, date, deadline, and markdown body content.

Example prompt: "Add a high-priority Capacities task to finish the MCP docs by Friday."

appendMdToObject

Permissions access: write

Appends markdown content to an existing object.

Example prompt: "Append a summary of this conversation to my meeting note about the product launch in Capacities."

createObjectViaMd

Permissions access: write

Creates an object of any object type. Content is matched against the type's writable properties; anything else is placed in the body. Call getObjectTypeShape first to see which properties are available. Frontmatter structures are recommended for mapping properties.

Example prompt: "Create a new Book object in Capacities for 'Thinking, Fast and Slow' with author and status in the frontmatter."

updateObjectViaMD

Permissions access: write

Updates writable properties on an existing object from YAML frontmatter in a Markdown string. Only keys listed in the frontmatter are changed; other properties stay as they are. A title key renames the object. Any Markdown body after the closing --- is ignored; use appendMdToObject to add content. If the string has no --- delimiters, the entire input is treated as bare YAML key-value pairs. Only object types that support PATCH /object can be updated this way.

Example prompt: "Set the status on my Capacities Book object for 'Deep Work' to finished."

getObjectTypeShape

Permissions access: read

Returns information about an object type's properties so you can create new objects with the right structure.

Example prompt: "What properties does my Meeting type have so you can log today's standup in Capacities?"

Creation limits

createPage, createTask, and createObjectViaMd share a per-user creation quota. The hard limit is 5,000 objects. Once you reach it, we increase the hard limit by 100 objects each month.

Known limitations

The Capacities MCP server works best for single-object operations in your space. Instead, LLM models can use search to find objects that match keywords via a search term. Retrieving a complete set of objects in your space, like retrieving all objects of a given type, is not officially supported at this point in time. After an object is identified, the LLM model can utilize another tool to read or modify it.

Prompts that require analyzing or counting across every object of a type are not officially supported. Example prompt: "Study all my Trip objects and tell me how many flights I've documented this year".

Prompts that act on a single object are supported. For example:

  • "Add a new Trip object with all this planned route"
  • "Read my Japan Trip object and give me a bullet point list of all the monuments I visited"

Build a custom MCP client

If you are building a custom implementation or a private tool and would like to integrate it with our MCP server, please follow this guide:

1. Start from the MCP URL

This is the resource your token must be valid for.

  • Canonical MCP resource URL: https://api.capacities.io/mcp
  • Transport: Streamable HTTP on /mcp
  • Do not configure Server-Sent Events (SSE) for Capacities MCP

2. Discover protected resource metadata (RFC 9728)

It tells you which authorization server to use.

  • Fetch: https://api.capacities.io/.well-known/oauth-protected-resource/mcp
  • Fallback: read WWW-Authenticate: Bearer resource_metadata="..."
  • Store:
    • resource
    • authorization_servers

3. Discover authorization server metadata (RFC 8414)

You need endpoints and capabilities before auth starts.

  • Fetch: https://api.capacities.io/.well-known/oauth-authorization-server
  • Confirm:
    • authorization_endpoint
    • token_endpoint
    • registration_endpoint
    • code_challenge_methods_supported includes S256 (SHA-256)

4. Generate Proof Key for Code Exchange (PKCE) parameters

PKCE protects public clients from code interception.

Before redirect:

  1. Generate high-entropy code_verifier
  2. Derive code_challenge using SHA-256 (S256)
  3. Generate random state
  4. Store code_verifier and state securely until callback

5. Register the client dynamically (RFC 7591)

Dynamic Client Registration (DCR) gives your app a valid client_id.

POST to registration_endpoint with:

  1. client_name
  2. redirect_uris
  3. grant_types: authorization_code, refresh_token
  4. response_types: code
  5. token_endpoint_auth_method: none

Persist:

  • client_id

Custom clients you build will almost always register as native, public clients (token_endpoint_auth_method: none, PKCE, no client secret) using a loopback redirect_uris. Hosted HTTPS callbacks and custom URI schemes are not accepted via DCR. See Redirect URI policy to have those pre-registered. A client_secret is only issued to specific pre-arranged web-based partner integrations.

Pick a distinct client_name. Names of well-known clients (such as "Claude", "ChatGPT", "Cursor", or "Capacities") are reserved and will be rejected unless your registration proves ownership.

Recommended optional fields: software_id (a stable UUID identical across all installs of your client), software_version, client_uri, and contacts. These help us identify and support your integration.

6. Start authorization code flow

This is the user consent and authorization step.

Redirect users to authorization_endpoint with:

  1. response_type=code
  2. client_id
  3. redirect_uri
  4. scope (request only needed scopes: mcp:read, mcp:write)
  5. state
  6. code_challenge
  7. code_challenge_method=S256
  8. resource=https://api.capacities.io/mcp

7. Handle OAuth callback safely

Callback validation prevents Cross-Site Request Forgery (CSRF) and flow confusion.

On callback:

  1. Validate state exactly
  2. Read code
  3. If error exists, stop and surface provider error

8. Exchange code for tokens

This returns the access token used for MCP calls.

POST to token_endpoint with:

  1. grant_type=authorization_code
  2. code
  3. redirect_uri
  4. code_verifier
  5. client_id
  6. client_secret (non-native/web-based clients only)

Persist securely:

  • access_token
  • refresh_token
  • expiry metadata

9. Call MCP with bearer auth

Tokens are sent as standard OAuth bearer credentials.

  • Header: Authorization: Bearer <access_token>
  • Use Streamable HTTP transport

10. Implement refresh token handling

Refresh keeps sessions working without constant re-login.

Before token expiry:

  1. Call token endpoint with grant_type=refresh_token
  2. Save new refresh token if rotation returns one
  3. On invalid_grant, require full re-auth

11. Follow security baseline

OAuth integrations fail safely only when these baseline controls are in place.

  1. Use Hypertext Transfer Protocol Secure (HTTPS) in production
  2. Validate callback state on every auth response
  3. Store tokens in secure backend storage or OS keystore
  4. Request minimum scopes needed
  5. Treat refresh tokens as long-lived credentials

Redirect URI policy

To keep every user's space secure, we don't accept arbitrary redirect URIs. What you need depends on your client's callback type.

Loopback redirects work automatically, with no contact needed.

If your client receives the authorization code on a loopback address, it registers via DCR (step 5) and completes OAuth with no manual step from us:

  • http://127.0.0.1 (any port, any path)
  • http://localhost (any port, any path)

This is the RFC 8252 native-app path, and it's the recommended option for CLIs and local desktop tools. Only http on these hosts is accepted. https://127.0.0.1 and IPv6 http://[::1] are not.

Hosted HTTPS callbacks and custom URI schemes require pre-registration.

A public web callback (https://yourapp.com/callback) or a custom scheme (yourapp://callback) cannot be self-registered via DCR. Your registration will fail with invalid redirect_uris. These are where authorization-code interception and impersonation risks concentrate, so we register the client on our side first.

Email [email protected] with:

  1. A brief description of your project/client (include your public repository, if available).
  2. The exact redirect URI(s) and your DCR client_name.
  3. Whether the callback is a hosted HTTPS URL or a custom URI scheme.
  4. A public URL to your application's icon (for example, your favicon.ico).

We'll confirm once your client is registered.

Using a pre-registered client ID

Some tools can't use Dynamic Client Registration (for example, clients whose callback is a custom URI scheme). For those, we issue a fixed public client_id that you set in the tool's MCP config instead of registering dynamically. This is how clients like Cursor connect today. If your client falls in this category, contact us. Pre-registered clients are public (PKCE, no secret).

Roadmap for the Capacities MCP Server

We do not envision the MCP to be a tool to "automate knowledge work", but rather a tool to help you to be more productive and creative.

The Capacities MCP server will be developed in conjunction with the Capacities API. We'll fine-tune API routes for AI usage so the Capacities MCP server is a powerful companion when working with AI.

If the official MCP is not enough for your needs, you'll be able to derive your own MCP server from the Capacities API.

Are you missing something in the documentation?

Ask a question! - The Docs Assistant knows everything about the documentation, and the ideas and feature requests from other users.

Create a ticket on our feedback board. - Let us know if you have an idea for a feature, improvement or think there is something missing.

Request additions to the documentation. - If your questions are not getting answered, let us know and we will extend the documentation.