Brault Developers
Guides

Use Brault from Claude.ai, Claude Code and Cursor

Connect Claude or any other MCP client to your brandspace, either by signing in to Brault or with an API key scoped to what the agent may do.

The Brault MCP server lets an AI agent work in your brandspace: search and read files, upload and import them, create folders, move, rename and tag assets, work with boards, comments and pages, manage shared links and send transfers.

No tool destroys content. Nothing deletes, trashes or restores a file, a version, a folder, a library, a board, a page, a comment, a reply or a shared link — there is no tool for any of that. Two tools cannot be undone, and they say so to your client, which may ask you to confirm them: remove_file_from_board takes a file off a board and discards the values that board holds for it, leaving the file itself untouched — members who could see the file only through that board lose access to it — and expire_transfer ends a transfer at once.

Some tools make content public. create_shared_link, update_shared_link, publish_page, create_transfer, complete_transfer and update_transfer create or change a link that works for anyone who holds it. Their descriptions tell the agent so, and the ones that create a link or widen who can reach it tell the agent to confirm with you first. Whether you are actually asked is up to your client. They need shares:write, pages:write or transfers:write: leave those scopes out of a connection that must not publish.

There are two ways to connect.

  • Sign in. Claude.ai and Claude Code send you to a Brault page where you pick one brandspace and approve what the client asked for. You never create or paste a key.
  • API key. Cursor, and any other client that takes a header, authenticates with a bsk_ key — see Get an API key.

Either way the address is the same, on the central host:

Centralapi.brault.app— this host is the same in every region
https://api.brault.app/mcp

Use that host. The server also answers on a regional host such as us.api.brault.app, but the discovery document a signing-in client reads always names the central host as the resource it protects, so a client that dialled a regional URL is handed a resource that does not match the URL it called and must refuse it (RFC 9728 § 3.3). A client using an API key reaches the same server on either host, and has no reason to write the other one.

1. Connect Claude.ai

In Claude's settings open Connectors, add a custom connector and paste the URL above. Claude registers itself and opens the Brault consent page in your browser. Sign in if you are not already, then:

  1. Pick the brandspace. One connection covers one brandspace. A brandspace whose plan has no API access, or whose billing is blocked, cannot be picked.
  2. Approve the scopes. The page lists the scopes the client asked for; you can approve fewer, never more.
  3. Allow. If your account has two-factor authentication, Brault asks for a fresh factor before it creates the connection.

The page names the client and the host it will send you back to — claude.ai or claude.com here — and never renders a logo the client supplied. The client's name is chosen by whoever registered it, so read the name and that host before you allow.

Claude then holds a connection that acts as you, in that one brandspace, limited to the scopes you approved.

2. Connect Claude Code

Claude Code can sign in the same way — no key, no header:

Centralapi.brault.app— this host is the same in every region
claude mcp add --transport http brault https://api.brault.app/mcp

Then run /mcp inside Claude Code and authenticate brault. The same consent page opens, and Claude Code is sent back to a loopback address on your own machine rather than to a public host — the consent page says so.

To use a key instead — a shared machine, a script, CI — pass it as a header:

Centralapi.brault.app— this host is the same in every region
claude mcp add --transport http brault https://api.brault.app/mcp \
  --header "Authorization: Bearer $BRAULT_API_KEY"

3. Connect Cursor

Cursor authenticates with an API key. Add to ~/.cursor/mcp.json:

Centralapi.brault.app— this host is the same in every region
{
  "mcpServers": {
    "brault": {
      "url": "https://api.brault.app/mcp",
      "headers": { "Authorization": "Bearer <your key>" }
    }
  }
}

What you are granting

A connection and a key both carry scopes, and they mean the same thing:

To let the agent…Scopes
Search, read and download filesfiles:read
Upload, import, move, rename and tag files, and create foldersfiles:write
Read or organize boards and propertiesboards:read (+ boards:write to change them)
Read or write commentscomments:read, comments:write
Read, write, publish or unpublish pagespages:read, pages:write
Read shared links, or create and change themshares:read, shares:write
Read transfers, or send, change and expire themtransfers:read, transfers:write
See who is in the brandspace and what each role may domembers:read

A write scope does not include the matching read scope, so keep both when the agent has to find something before it can change it. The agent only sees the tools its scopes allow.

A scope is a ceiling, not a grant. Every tool call is checked against your own live permissions at the moment it runs, intersected with the scopes. Approving files:write for a member who cannot write does not create write access; it creates a connection whose writes are refused. If your permissions change later, the connection follows them.

Those thirteen scopes are the whole list a consent can ask for: they are the scopes at least one MCP tool needs. webhooks:manage is never offered, so a connection can never hold it. An API key still can, for the REST API.

A client that asks for no scope in particular is offered all thirteen. The consent page shows one row per scope, and you can approve fewer.

The tools

79 tools, grouped by what they work on. get_context and get_usage need no scope; every other tool is shown to the agent only when its scope was granted.

AreaTools
Contextget_context, get_usage
Members and roleslist_members, get_member, list_roles
Libraries and folderslist_libraries, get_library, create_library, update_library, list_folders, get_folder, create_folder, update_folder, move_folder
Filessearch, list_files, get_file, find_similar_files, update_file, move_file, copy_file, set_file_property, list_file_boards
Versionslist_file_versions, activate_file_version
Uploads and importsstart_upload, get_upload_part_urls, complete_upload, abort_upload, import_file_from_url, get_import_status
Downloadsget_download_link, start_zip_download, get_zip_download
Boardslist_boards, get_board, query_board, create_board, update_board, list_board_members, add_files_to_board, remove_file_from_board, set_board_file_property
Propertieslist_properties, create_property, update_property, add_property_option, update_property_option, create_board_property, update_board_property, add_board_property_option, update_board_property_option
Commentslist_comments, get_comment, add_comment, update_comment, resolve_comment, reopen_comment, list_replies, reply_to_comment, update_reply
Pageslist_pages, get_page, create_page, append_page_blocks, publish_page, unpublish_page
Shared linkslist_shared_links, get_shared_link, create_shared_link, update_shared_link
Transferscreate_transfer, get_transfer_upload_part_urls, complete_transfer_upload, complete_transfer, list_transfers, get_transfer, update_transfer, expire_transfer

A few things the table does not show:

  • Moves and copies go one item per call. move_file, copy_file and move_folder each take one file or folder. There is no tool to restore from the trash, and none to manage webhooks.
  • People appear as user ids in comments, replies and list_board_members. The agent turns an id into a name with list_members or get_member, which need members:read.
  • list_board_members and list_file_boards show at most 200 entries. They cannot be paged; past 200 the answer says how many were left out.
  • Only reads and add_files_to_board are safe to repeat. Every other tool that changes something takes effect again each time it is called, even with the same arguments.

Uploading a file

The bytes of a file never pass through the MCP server. An upload is three steps:

  1. start_upload reserves the file and answers with a curl command that sends its bytes to storage.
  2. The client runs that command where the file is.
  3. complete_upload creates the file in your brandspace.

A large file is sent in parts: get_upload_part_urls hands out one command per part. abort_upload gives up an upload that was started. A transfer of files from your computer works the same way, with create_transfer, get_transfer_upload_part_urls, complete_transfer_upload and complete_transfer.

Step 2 needs a client that can run a command where the file is. Claude Code and Cursor can. Claude.ai and other hosted clients cannot reach a file on your computer: there, give the agent a public link to the file and it uses import_file_from_url.

The URL in that command allows writing that one file and nothing else, until the upload session expires. It is written into the conversation, so whoever can read the transcript can read the URL.

Disconnecting

  • Your own connections — Settings → Security → Connected apps lists every app you connected, in every brandspace, with its scopes and when it was last used. Disconnect kills its tokens immediately, and the client has to be authorized again before it can do anything.
  • Every connection in a brandspace — Developers → Connections lists them for all members, with who created each one. Disconnecting someone else's needs the developers.manage permission and, if your account has two-factor authentication, a fresh factor — the same step-up the consent page asks for. Disconnecting your own never asks for one.
  • A disconnected connection stays in both lists for 30 days, with the reason it ended, and then disappears.

Most reasons read plainly — you disconnected it, an admin did, or the client itself asked Brault to. Two are ours:

  • refresh_reuse — the client presented a refresh token it had already exchanged for a new one, so Brault ended the connection as a precaution.
  • code_reuse — the one-time code from the sign-in was presented twice, so Brault ended the connection as a precaution.

Both mean a credential was replayed, which is what a stolen one looks like. Nothing in your brandspace is affected: connect again.

A connection can also stop working without anyone pressing anything:

  • You leave the brandspace, or lose access to it. The connection is paused, and Brault emails the brandspace's owners and admins.
  • The plan loses API access, or billing is blocked. Calls are refused until that is fixed.
  • It goes unused for 30 days. The access token lives one hour and the client refreshes it silently; each refresh extends the connection by another 30 days. A connection that goes 30 days without one cannot be renewed — connect again. This is the one ending that shows nothing: the row stays active in both lists, with no reason beside it, for as long as it is listed. A connection that looks fine but has stopped working is usually this one.
  • The client's registration expires after 90 days. The first time you connect an app it registers itself with Brault. A registration that holds no live token and goes 90 days unused is expired, and later deleted. The app registers again by itself on the next attempt — you only have to approve the connection once more.

Limits

  • 20 active connections per member per brandspace — the default, and Brault can raise it. Disconnected ones do not count, even while they are still listed for their 30 days. Connections do not count against your plan's API-key limit and never appear in the API keys tab.

  • Every tool call is an ordinary API request made as you: it counts against the brandspace's rate limits and monthly quota, like any integration (see Plans and limits).

  • The MCP endpoint has three budgets a minute, charged in this order, and a request stops at the first one it exceeds:

    BudgetLimitCounts
    Per IP address3000every request, signed in or not
    Per credential300requests carrying a connection or a key
    Unauthenticated60requests carrying neither

    Past any of them the answer is 429 with Retry-After. One agent turn is several requests, so the per-credential 300 is the one an individual agent tends to meet.

    The per-IP budget is the one worth knowing about, because it is the only one you share. Claude.ai reaches Brault from Anthropic's egress addresses, which every Brault customer connected through Claude.ai comes from — so a 429 can land on a request you know was your first in a while. It is not your budget and nothing is wrong with your connection; wait out the Retry-After and carry on. It is per IP by design: budgeting only per credential would let a flood of made-up ones mint itself a fresh 300 every request.

  • In the Developers request log and its CSV export, MCP calls carry the user agent brault-mcp/<version> (<tool>), so you can tell which tool made each request, and a connection's requests are attributed to the member who approved it.

If you are writing your own MCP client

Nothing below is something a Claude.ai, Claude Code or Cursor user has to think about — those clients stay inside these bounds on their own. They matter if you are speaking the protocol yourself.

  • A request body is capped at 1.25 MB. Over that the answer is 413 with the JSON-RPC error -32600; a body that is not valid JSON is 400 with -32700. A single tool call carries about 1 MB at most in any case.
  • A batch carries at most 20 messages. A longer array is refused with 400 and -32600, before the credential is read and before any tool runs.
  • A 401 anywhere in a batch discards the whole batch. When a credential is dead or expired, the answer is the HTTP 401 challenge for the entire request rather than one message's result — it is what tells you to refresh — so it replaces the answers to every message in that batch, including the ones that had already succeeded. Re-authenticate and send the batch again. Replaying is only safe if the tools in it are, so batch reads freely and send writes one per request.

On this page