Drive betool from Claude (MCP server)
betool exposes an MCP server (Model Context Protocol): an external MCP client — Claude Code, Claude Desktop, or any compatible application — can read your organisation's configuration and propose changes in natural language (create/edit a pipeline, a role, a mission, an evaluation…). It is like an assistant configuring betool with you, fully governed.
Two ways to connect, to the same endpoint https://platform.betool.ai/mcp:
- an MCP API key in the
Authorizationheader — simplest for Claude Code; - OAuth 2.1 + PKCE — for third-party applications, with no secret to handle.
Nothing is applied without an explicit approval. Every change goes through a proposal. With the Read + proposals scope, you approve it with an Accept button inside betool. With the Full scope, the application may resolve its own proposals after you agree in its own conversation — the machine equivalent of that button, restricted to this scope and audited like everything else. Pick Read + proposals if you want the approval to happen inside betool, and nowhere else.
What Claude can do
- Read: model inventory, a pipeline's graph and nodes, node configuration contracts, roles/missions, available tools, knowledge base.
- Read your data: your organization's no-code databases — databases, tables, columns and rows. The client discovers them on its own; a key cannot be restricted to a subset of databases.
- Propose: via the
proposals.createtool, a pending change proposal — you accept or reject it in the UI. - Write data (Full scope): create, update or claim a row in one of your databases, after your explicit agreement in the conversation. Unlike configuration, a data write is not versioned — it cannot be restored.
- Talk to your models (Full scope): hold a multi-turn conversation with a model you have explicitly opened to external agents — see below.
Claude discovers each node's exact contract (fields, allowed values) before proposing: no guessing, no invalid configuration.
Create an MCP key
Restricted to organisation administrators: a key carries authority over the whole organisation.
- In betool, open Settings → MCP.
- Name the key and pick its scope:
- Read only — reads configuration and the data in your databases, re-reads the threads opened through this channel, proposes nothing;
- Read + proposals (recommended) — reads and submits proposals, which you approve inside betool;
- Full — may also resolve its own proposals, write into your databases and converse with your models, after you agree in the client's conversation.
- The raw key is shown only once — copy it immediately (it can never be read again). You can revoke a key at any time.
The same three scopes exist for OAuth; there, you pick them on the consent screen.
Connect Claude Code
Add the betool MCP server to Claude Code (the key goes in the Authorization header):
claude mcp add betool \
--transport http \
--header "Authorization: Bearer <your-mcp-key>" \
https://platform.betool.ai/mcp
Then ask Claude, in natural language: "inspect my pipeline X and propose a step that summarises the ticket before sending". Claude reads the configuration, composes a proposal, and you validate it in betool.
Never paste secrets in clear text in the chat. Claude's reach is bounded by the key scope, and every tool call is logged under Settings → MCP → log (GDPR art. 15).
Talk to your models
Reading and proposing is how you configure betool. An external AI can also use it: hold a real conversation with one of your models, turn after turn, exactly like any visitor on your chat. Useful to have an assistant stress-tested by another AI, to put betool behind a partner agent, or to let an internal tool query one of your processes in plain language.
Four tools: conversation.open opens or resumes a thread, conversation.send sends a turn and returns the answer, conversation.poll picks up an answer that took a while, conversation.history re-reads the thread. That thread is a betool context like any other: it shows up in your conversations, the model sees the previous turns, and you can read everything in the UI.
The model grants access, never the key. You must declare the External agent receiver on the model's Start node: without it the call is refused, even with a Full scope key. Models created since this release declare it by default (the normal path is the easy path); older ones need it added, and any model can have it removed. So the model decides, never the key — and the receiver must be present in the published version, the one that runs. And because a turn can trigger real effects — an email sent, a record created — it consumes the organisation's credits and is audited like every tool call.
An answer is never lost: if the model works longer than the allowed wait, the call returns a ticket and the turn keeps running server-side — it even survives a redeployment. The application then reads the answer with conversation.poll. Re-sending the message speeds up nothing — and while the turn is running, sending is refused.
Finally, this channel only reads its own threads. A conversation id coming from another entry — public chat, phone, email — is not readable here: your customers' exchanges do not become browsable just because an MCP application is connected.
A model already in place works untouched. This channel posts the same keys as a chat: the message arrives in user_message and the event is an ordinary on_message — so your filters and your agents' selections keep working. If the target model was written for another entry point (it reads telegram.text, an objective, a page variable…), the application can supply those keys itself through variables: they enter the flow where the other entry point would have placed them. What it cannot forge is the identity of the turn — who spoke and through which channel: the server sets those keys, and any attempt is refused and reported in the response.
If the model stays silent, look at its routing. A model serving several channels usually branches on the entry (filter input.entry_kind == chat_widget…): a turn arriving with the external-agent entry then matches no branch, and nothing answers — without any error being raised. Pass as_entry_kind to be routed as that channel. It changes only the routing key: the channel descriptor and the audit trail still say the turn came from an external AI, and the channel's real capabilities still apply.
A thread handles one turn at a time. Until the previous turn has returned its answer, the next one is refused, naming the turn to read. This is not an arbitrary limit: an answer is tied to its question by its position in the thread, so two turns in flight would make attribution ambiguous — a clear refusal beats a plausible, wrong answer.
Connect a third-party application (OAuth 2.1)
A header key suits Claude Code. Other clients — Claude Desktop, ChatGPT, an editor, your own application — connect through OAuth 2.1 + PKCE, with nobody handling a secret. There is nothing to prepare: no client to declare, no identifier to request from us.
For the user, the journey is three screens:
- In the application, add the MCP server
https://platform.betool.ai/mcp. - Your browser opens a betool consent screen: it names the application requesting access, the organisation concerned, and where the return will happen. Check those three things — especially if you belong to several organisations.
- Choose the scope you grant, then Authorize. The application never receives more than you tick, even if it asked for more.
Only an organisation administrator can authorize an application. Connecting one creates lasting authority over the whole organisation — exactly what an MCP key is. A member with limited rights therefore cannot bypass their restrictions through this door.
For integrators, discovery is fully automatic and standards-compliant: an unauthenticated call to /mcp returns a 401 carrying the WWW-Authenticate header with the address of our metadata (RFC 9728), which in turn points to authorization, token exchange, dynamic client registration (RFC 7591) and revocation (RFC 7009). PKCE S256 is mandatory, access tokens last one hour, and the refresh token rotates on every use.
# What a client does on its own — handy to check from a terminal.
curl -i -X POST https://platform.betool.ai/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize"}'
# -> 401 + WWW-Authenticate: Bearer ... resource_metadata="..."
curl -s https://platform.betool.ai/.well-known/oauth-authorization-server
A token is only valid for betool: replayed elsewhere, it is refused (RFC 8707). And if an already-used refresh token is presented a second time — the signature of a stolen token — the whole session is revoked and the user must authorize again.
Connected applications: see and disconnect
In Settings → MCP, the Connected applications section lists what is plugged into your organisation: the application's name, the granted scope, who authorized it, and when it was last used. A Disconnect button cuts access immediately — every token of that application, for your organisation only.
The same application may be connected by several organisations: disconnecting it on your side affects nobody else. An application can also disconnect itself.
Scope & isolation
- By default a key operates only on your own organisation — the target org is forced server-side; you never pass an organisation id as an argument.
- Vendor keys (backoffice organisation) may target another organisation, under that org's explicit consent and with full audit — useful for a multi-tenant vendor use case.
Audit log
Every tool call (external via MCP and internal) writes an audit line: who, which tool, which channel, which scope, outcome, latency. Available under Settings → MCP, strictly scoped to your organisation.
Coming soon
- Fine-grained, per-tool control of the MCP-exposed surface.
- Server-to-client streaming (SSE) for server notifications.
See also
- Admin API — automate betool from your own systems.
- Security & compliance — the proposal governance model.