Arbol’s MCP server offers the API’s operations as tools to AI clients. It runs at the API’s own URL, https://api.getarbol.com, over Streamable HTTP. Its former address, https://mcp.getarbol.com, redirects there.
A tool call is the REST request its operation describes, sent with your credential. The same scopes decide it and the same errors come back, so everything in Authentication and Concepts applies.
Add the server to your client
Add https://api.getarbol.com to your client as a remote server. Each client has its own configuration file and field names, so check its documentation. A common shape:
{
"mcpServers": {
"arbol": {
"url": "https://api.getarbol.com"
}
}
}A client that supports MCP authorization signs you in the first time it connects. See Sign-in.
{
"mcpServers": {
"arbol": {
"url": "https://api.getarbol.com",
"headers": {
"Authorization": "Bearer arb_live_…"
}
}
}
}Use an API key for an unattended agent, or with a client that can’t sign in. Give the key only the scopes the agent needs, and keep the file out of version control.
A plain GET https://api.getarbol.com/, as from a browser, answers the API’s index rather than MCP. Clients send their MCP requests to the same URL with POST.
Sign-in
Without a valid credential, the server answers 401 with a challenge that names the protected resource metadata and the scopes its tools require:
WWW-Authenticate: Bearer resource_metadata="https://api.getarbol.com/.well-known/oauth-protected-resource", scope="account:api-keys:read account:api-keys:write …"- The client reads the metadata, which names Arbol’s authorization server,
https://auth.getarbol.com/. - It signs you in there for the resource
https://api.getarbol.com, with one of your organizations selected. - It connects again with the access token.
The token acts in the organization you selected. It holds the scopes the client asked for, as far as your roles grant them, so a client that asks for no scopes gets no tools.
The tools you see
The server lists only the tools your credential may use: the operation must accept your kind of caller (a person or a machine), your credential must hold one of its scopes, and an API key’s restrictions must allow it. Calling a tool still goes through the same checks as REST.
Each tool is named after its operation: account.organization.get is the tool account_organization_get. Its annotations come from the operation’s Effect: readOnlyHint for a read, destructiveHint for a delete, and idempotentHint when it’s idempotent. See Retries.
Not every operation is a tool. Each operation’s page in the API reference names its MCP tool, or says it isn’t offered on MCP; those are REST only.
When you may use more than 40 tools
A long list is hard for a model to choose from, so when your credential may use more than 40 tools, the server lists these instead:
| Tool | What it does |
|---|---|
search_tools |
Finds the tools you may call, by what they do. |
run_read_tool |
Runs a tool that only reads. |
run_write_tool |
Runs a tool that creates or changes something. |
run_delete_tool |
Runs a tool that deletes something. |
A runner is listed only when you have tools with its effect. Since each effect has its own runner, a client’s approval of run_read_tool never covers a write or a delete.
search_tools takes a query in English, such as "list appointments", and optionally a service and a limit (10 by default, up to 50). Each match comes back in short: its name, effect, runner, what it does, its input as a signature and, for a read, the fields it returns. Before calling a tool whose input you don’t know in full, a write above all, ask for it by names, up to five at a time, to get its whole input schema.
Then call the runner with the tool’s name and its input. As the parameters of an MCP tools/call request:
{
"name": "run_read_tool",
"arguments": {
"name": "account_organization_get",
"arguments": {}
}
}Short answers
A model reads every answer in full, on every step, so read tools can answer less than REST does:
fields. Every read tool takesfieldsbesides its own input: up to 50 field names. Each record then comes back with only those fields, and always itsid. The value never reaches the service.omittedFields. A list over 16 KB, asked for withoutfields, leaves out its items’ largest fields, those over 512 bytes per item on average, and names them inomittedFields. Ask for them withfields, or read one record.
For example, a call to account_api_keys_list that asks only for each key’s name and scopes:
{
"name": "account_api_keys_list",
"arguments": { "limit": 100, "fields": ["name", "scopes"] }
}REST answers are never shaped this way. One operation, nueva-eps.affiliations.lookup, defines its own fields, which works as its reference describes.
Errors
A refused call comes back as a tool result with isError: true. Its text is the same error object REST answers, with code, message, retryable and data: see Responses and errors. A tool called through the wrong runner is refused with INVALID_INPUT, and the error’s data.runner names the right one.
Integrations
Integration operations are tools too, such as sura_appointments_create or adres_affiliations_lookup, with the same input as their REST operation and the same checks: the integration active in your organization and your credential’s restrictions. Some take agentMode to answer concise Spanish text: see Text answers for AI agents and, for ADRES, Sisbén and Policía Colombia, Colombian registries.