MCP server
Bordio speaks the Model Context Protocol (MCP), so an AI assistant can read and change your work directly instead of you copying things back and forth.
https://api.bordio.com/mcpAuthentication is OAuth — you approve the connection in the browser and never paste a key anywhere. API keys are for server-side integrations; they do not work here.
Before you start
Section titled “Before you start”Three things decide whether the connection will work at all. Check them first — most failed setups are one of these, not a problem with the client.
- A team workspace. Personal workspaces have no integrations on any plan, and cannot be connected.
- A paid plan or an active trial. A trial works in full, with no card required. On a free plan, or after payments stop, the connection is made but every tool call is refused.
- Membership, not guest access. Guests cannot authorise an app for a workspace. Ask an admin to make you a member.
The rules are checked on every call, not only when you connect — see plan and workspace requirements.
Connect
Section titled “Connect”Every client below talks to the same URL. You never copy a token: the client opens a browser, you sign in to Bordio and approve access, and it stores the result itself.
Claude Desktop
Section titled “Claude Desktop”Settings → Connectors → Add custom connector → paste the URL. Approve in the browser window that opens.
Claude Code
Section titled “Claude Code”claude mcp add --transport http bordio https://api.bordio.com/mcpThen run /mcp, pick bordio and choose Authenticate. To sign in without opening a session, run claude mcp login bordio.
Cursor
Section titled “Cursor”Add the server to ~/.cursor/mcp.json (available everywhere) or .cursor/mcp.json (this project only):
{ "mcpServers": { "bordio": { "url": "https://api.bordio.com/mcp" } }}Cursor picks up the change and starts the browser sign-in on first use.
VS Code
Section titled “VS Code”Add the server to .vscode/mcp.json:
{ "servers": { "bordio": { "type": "http", "url": "https://api.bordio.com/mcp" } }}codex mcp add bordio --url https://api.bordio.com/mcpcodex mcp login bordiologin opens the browser and stores the result. Codex registers itself with Bordio on the fly, so
there is no client id to obtain first; if your version asks how to register, choose dynamic client
registration (--oauth-client-registration dcr).
Older builds route URL-based servers through the previous MCP stack, where the OAuth sign-in doesn’t
run. If login fails or the server never connects, add this to ~/.codex/config.toml and try again:
experimental_use_rmcp_client = trueThe equivalent entry in ~/.codex/config.toml, if you prefer editing the file:
[mcp_servers.bordio]url = "https://api.bordio.com/mcp"Other assistants
Section titled “Other assistants”Anything that supports remote MCP servers over HTTP and can run the OAuth sign-in — Windsurf, Zed, and the rest — works the same way: give it the URL and approve in the browser.
Automations: use the REST API instead
Section titled “Automations: use the REST API instead”n8n, Make, Zapier and your own scripts are a different case, and MCP is the wrong tool for them.
Signing in here means a person approving access in a browser, and the resulting token belongs to that person. An automation that runs at 3 a.m. has nobody to open a browser, and there is no way to issue it a standing MCP credential — Bordio does not hand out OAuth client credentials for self-service use.
For automations, use the REST API with a secret API key: it is built for exactly this — a long-lived credential, no browser, no expiry to babysit. Everything an assistant can do over MCP is available there.
Building your own MCP client
Section titled “Building your own MCP client”If you are writing a client rather than using one, there is nothing to register by hand. Bordio implements the discovery chain the MCP specification defines, so a compliant client finds everything from the endpoint URL alone:
- Protected resource metadata at
/.well-known/oauth-protected-resource/mcp— points to the authorization server; - Authorization server metadata at
/.well-known/oauth-authorization-server— endpoints, scopes, and supported methods; - Client ID Metadata Documents (the method the specification now prefers): host a JSON document describing your client and pass its HTTPS URL as
client_id. We fetch it, check that theclient_idinside matches the URL it came from, and validate your redirect URIs against it; - Dynamic client registration at
/oauth/registeras a fallback for clients that do not support the above.
PKCE is required, S256 only. Loopback redirect URIs (http://127.0.0.1/... and http://localhost/...) are accepted with any port, as native clients need.
Whichever route you take, the approval screen shows the person the domain their authorization code will return to — that is the one claim about your app they can verify, so make it a domain they recognise. See approving an app.
What your assistant can do
Section titled “What your assistant can do”Once connected, ask in plain language: “what’s on my plate today”, “create a task to renew the SSL certificate, due Friday”, “what did the team close last week”.
| Area | What the assistant can do |
|---|---|
| Tasks | List and filter, read one task with its subtasks and comments, create, update, close, delete |
| Subtasks | List, create, update, delete |
| Events | List and read calendar events, create and update them, manage participants |
| Trash | See what was deleted and bring a task or an event back — deleting is not final |
| Agenda | Everything in a date window — meetings, deadlines and planned work — as one ordered list |
| Summary | Counts for a period, by status and by assignee, without listing every record |
| Comments | Read and write comments on tasks and events |
| Time logs | Read and record logged time |
| Projects, members, tags | Read the workspace structure; archive and unarchive projects; manage tags |
| Definitions | Task statuses, task types, event types, project statuses, custom fields |
Everything an assistant can reach through MCP, it reaches with your permissions. It can never see a project you cannot see.
Nothing an assistant does here is permanent. Deleting a task or an event moves it to the trash, where it can be restored for 30 days; projects are archived rather than deleted. There is no tool that destroys a record outright — see deleting and restoring.
Ready-made prompts
Section titled “Ready-made prompts”The server ships three prompts. In Claude Desktop they show up as commands you can pick, so you do not have to invent the phrasing:
| Prompt | What it does |
|---|---|
| What do I have today | Meetings, deadlines and planned work for today, in one ordered list, with what deserves attention first |
| Sort out what is overdue | Groups overdue tasks and proposes a new date for each — nothing changes until you confirm |
| Wrap up my week | What got finished, what slipped, what is waiting next week |
Each takes an optional project name to narrow things down.
Attaching a specific record
Section titled “Attaching a specific record”Some clients let you attach a resource to the conversation instead of asking the assistant to search for it. Bordio exposes four:
bordio://workspacebordio://project/{project_id}bordio://task/{task_id}bordio://event/{event_id}Use them when you already know which record you mean — the assistant then works from it directly instead of hunting for it. Lists stay on the tool side, where filters and pagination belong.
Permissions
Section titled “Permissions”The approval screen shows exactly what the app is asking for, and you grant it per workspace. If you belong to several workspaces, you pick one during approval; a connection never spans more than the workspace you chose.
An assistant only sees the tools its permissions cover: if a connection was approved for reading only, writing tools are not merely rejected, they are not offered at all.
| Permission | What it covers |
|---|---|
tasks:read / tasks:write |
Tasks, subtasks, and comments on them |
events:read / events:write |
Calendar events, their participants, and comments on them |
projects:read / projects:write |
Projects and their configuration — statuses, types, custom fields |
time_logs:read / time_logs:write |
Logged time |
tags:read / tags:write |
Tags |
members:read |
Other people in the workspace, including their email addresses |
profile:read |
Your own name and email address |
offline_access |
Stay connected without asking you again every hour |
profile:read is worth requesting even for a read-only assistant: without it nothing can answer “what’s on my plate”, because the assistant does not know which member of the workspace you are.
A client that asks for a permission it cannot have does not get an error — the permission is dropped and the rest is granted, and the approval screen shows what will actually be given. Read the granted list back from the token response rather than assuming you received everything you asked for.
You can review and revoke connections at any time in Profile → Integrations → Apps with access to Bordio. Revoking takes effect immediately.
Plan and workspace requirements
Section titled “Plan and workspace requirements”Connecting is open to anyone: the approval screen appears for any workspace you are a member of, whatever the plan. Using the connection is what the plan gates — every tool call is checked, not just the first one.
| Situation | What happens |
|---|---|
| Team workspace on a plan with integrations | Everything works |
| Team workspace on a trial | Everything works — no card required |
| Team workspace where a payment failed but the provider is still retrying | Keeps working: a card that didn’t go through on the first attempt is not a decision to stop |
| Team workspace on a free plan, or once payments have stopped for good | The connection stays, but each tool call returns workspace_plan_required until the plan is sorted out |
| Personal workspace | Cannot be connected at all: integrations_unavailable, on any plan |
| You are a guest in the workspace | You cannot authorise an app for it: guest_access_denied. Ask an admin to make you a member |
The check runs on every call by design: an approval granted while the plan was active does not keep working after it lapses. The reverse is true too — once the plan is back, the existing connection resumes without reconnecting anything.
One connection covers one workspace. You choose the workspace on the approval screen, and the connection never reaches beyond it. To work with a different workspace, revoke the connection in Profile → Integrations → Apps with access to Bordio and authorise again, picking the other one.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Tool calls, reading | 180 / minute |
| Tool calls, writing | 60 / minute |
| Requests to the endpoint (including protocol messages) | 300 / minute |
| Single tool call | 30 seconds |
| Single response | 128 KB |
Protocol messages — connecting, listing tools — do not consume the tool-call budget. Reading is more generous than the REST API because one question usually turns into a short chain of calls.
If a response would exceed the size limit, the call is rejected with a hint to narrow the request rather than silently truncated: an assistant working from a cut-off list would draw conclusions from data it does not know is incomplete.
When something doesn’t work
Section titled “When something doesn’t work”| What you see | What it means |
|---|---|
| The client keeps asking you to authenticate, and the approval succeeds each time | The token is being refused after it’s issued. Check that the connection isn’t revoked or blocked in Profile → Integrations → Apps with access to Bordio, then remove the server from the client and add it again. |
workspace_plan_required on every call |
The workspace is on a free plan, or payments have stopped. The connection itself is fine and resumes as soon as the plan does. |
integrations_unavailable |
The workspace you approved is a personal one. Connect a team workspace instead. |
guest_access_denied |
You’re a guest there. Guests can’t authorise apps — ask an admin to make you a member. |
connection_blocked |
An admin stopped this connection. It’s reversible; ask them to restore it. Re-approving won’t help while the block stands. |
| The assistant says a task doesn’t exist, but you can see it | The connection acts with your permissions in one workspace. A record in another workspace, or in a project you aren’t in, is genuinely out of reach for it. |
| A write tool isn’t offered at all | The connection was approved without that permission. Revoke and approve again, this time granting it. |
| Tool calls start failing after a burst of activity | You’ve hit the per-minute limit. The error says how long to wait. |
Approving an app
Section titled “Approving an app”Any app can connect: MCP lets an application register itself, and we do not gate that. Nothing is quietly withheld either — an app gets exactly the permissions the person approved, and no more.
What the approval screen shows is what can actually be checked:
| Shown | Why it can be trusted |
|---|---|
| The app’s name and logo | Sent by the app itself for a self-registered client, or taken from the metadata document on your domain. |
| The domain the code returns to | Cannot be faked without controlling that domain. For desktop and editor clients the screen says the code returns to the person’s own machine instead. |
| The list of permissions | Exactly what will be granted. |
There is no review queue and nothing to apply for: an app that publishes a metadata document on its own domain simply shows up under that domain. Well-known clients — Claude, Slack, Cursor, Codex and VS Code among them — additionally get their name and logo from us, so they are recognisable at a glance.
Errors
Section titled “Errors”The assistant sees failures as normal answers, so it can correct itself and try again — a task it cannot reach comes back as “not found”, not as a broken server.
| Situation | What happens |
|---|---|
| Not signed in, or the approval expired | The client prompts you to authenticate again |
| App lacks a permission | The call is rejected, and the client is told which permission is missing |
| Rate limit reached | The call is rejected with the time to wait |
| Record not found, or outside your access | The assistant is told the record is not available |
Related
Section titled “Related”- Authentication — API keys for server-side integrations
- Rate limits — limits on the REST API
- Errors — the full error catalog