> ## Documentation Index
> Fetch the complete documentation index at: https://docs.consile.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Studio connectors and bots

> Own connectors built in Consile Studio have their own MCP endpoint. How the endpoint behaves, who gets tools, the initialize instructions, and how AI bots authenticate with a key.

In [Studio](https://docs.consile.ai/en/studio/introduction.md) (marked **Beta** in the portal), an organization
builds its own connectors from tools in the systems it already has access to. An own
connector belongs to one [customer](https://docs.consile.ai/en/studio/customers.md) and gets its own MCP endpoint.
There are two types, chosen when it is created:

* **AI-assistent**: people sign in with their Consile login, exactly as on a
  connector endpoint ([Authentication](https://docs.consile.ai/developers/authentication.md)).
* **AI-bot**: one bot calls the endpoint with a key instead of a login. See
  [AI bot keys](#ai-bot-keys) below and [AI-bots](https://docs.consile.ai/en/studio/ai-bots.md).

This page describes the protocol side. How to build and share an own connector is
described in [Egne connectors](https://docs.consile.ai/en/studio/own-connectors.md).

## The endpoint

```
https://mcp.consile.ai/studio/s_<16 hex characters>/mcp
```

For example `https://mcp.consile.ai/studio/s_0123456789abcdef/mcp`. The portal shows
it under **Connectorens URL** on the own connector's page in Studio. Renaming the own
connector does not change the URL. Deleting it stops the endpoint from serving tools
immediately.

| Method & path | Purpose |
| - | - |
| `POST /studio/<id>/mcp` | JSON-RPC: `initialize`, `tools/list`, `tools/call`, … |
| `GET /studio/<id>/mcp` | Server→client SSE stream |
| `GET /.well-known/oauth-protected-resource/studio/<id>/mcp` | Public RFC 9728 metadata; points to the authorization server |

Any other method returns `405` with `Allow: GET, POST`. Headers, statelessness, the
`Origin` rule and the request size limit are the same as on connector endpoints
([Protocol notes](https://docs.consile.ai/developers/connect-mcp-client.md#protocol-notes)). Without a valid
token or key, the endpoint answers `401` with a `WWW-Authenticate` header that points
to its metadata document.

> [!NOTE]
>
> The id in the URL is not a secret, and it never decides which organization you
> reach. Your organization comes from your access token or bot key. A URL that does
> not belong to your organization answers like an own connector that is not
> available to you: no tools, and `initialize` instructions that say so.

## What the endpoint serves

* `initialize` reports `serverInfo.name` `"Consile Studio"`.
* `tools/list` returns only the tools in the own connector's selection, at most 50.
  Each tool keeps its real name with the endpoint id of the portal it comes from,
  for example `economic__create_draft_invoice`, `economic-2__list_customers` or
  `cvr__soeg_virksomhed`. Schemas and annotations are the same as on the connector
  endpoint, so the [API reference](https://docs.consile.ai/developers/tools/gsc.md) applies unchanged.
* There is no `connect_account` tool. Portals are connected in the portal under
  **Connectors**.
* A tool outside the selection returns a tool result with `isError: true` and the
  text `Unknown tool.`, even when your organization has the tool elsewhere. The same
  applies to `connect_account`.
* Every platform check still runs on every call, as on the connector endpoint:
  access to the connector (subscription or plan), the plan's monthly call limit,
  the seat or plan licence, the organization's tool switches, the user's access
  level, the [company lock](https://docs.consile.ai/en/portal/company-lock.md) and
  [approvals](https://docs.consile.ai/developers/write-tools-and-guardrails.md#approvals). A colleague whose
  access level leaves out a tool does not see it. A colleague without a seat on one
  of the systems still sees its tools, but every call to them is refused, as on the
  connector endpoint.
* An own connector only uses portals that belong to its customer, plus tools with
  public data such as CVR. This is checked again on every request: if a portal is
  moved to another customer, its tools drop out of the next `tools/list`, and they
  come back if the portal is moved back.
* The server sends no `notifications/tools/list_changed`. Call `tools/list` again to
  see a changed selection.

### Who gets tools

| Session | Result |
| - | - |
| The owner of an **AI-assistent** connector, or a colleague it is shared with | The selection, filtered by that person's own access |
| Any other person in the organization, administrators included | No tools |
| A person on an **AI-bot** connector | No tools |
| The bot's own key, on its own **AI-bot** connector | The selection, except write tools added since an administrator last confirmed the bot |
| A bot key on any other Studio endpoint | No tools |
| A deactivated own connector, for anyone | No tools |

"No tools" means that `tools/list` returns an empty list, every `tools/call` returns
`Unknown tool.`, and the `initialize` result carries one of the
[unavailable texts](#when-the-own-connector-is-not-available).

### The initialize instructions

When the own connector is available, the `initialize` result carries `instructions`
in this form:

```
<name> is a custom selection of tools, made in Consile Studio for <customer>. It draws on these portals: <label> (tools prefixed <id>__), <label> (tools prefixed <id>__). Treat the tools listed in this session as the complete surface: never promise an action that no listed tool performs, and when the user wants something no listed tool can do, say that it is not part of this connector and that an administrator of the Consile account can change the selection in the Consile portal under Studio. Do not suggest purchasing anything.
```

* `<name>` is the own connector's name and `<customer>` is the customer's name. For
  an own connector made for the organization itself, the text reads
  `made in Consile Studio for the signed-in organisation`.
* When the own connector has no tool it can serve right now, for example because
  the selection is empty, the portals sentence is replaced by
  `It exposes no tools in this session.`
* The optional instructions written in the portal (**Instruktioner til
  AI-assistenten**, or **Instruktioner til boten** for a bot, at most 2,000
  characters) come first, followed by a blank line and the text above.

The own connector's name, the customer's name and the portal labels are therefore
sent to the model.

### When the own connector is not available

| Reason | `instructions` |
| - | - |
| It does not exist for your organization, or it is an **AI-assistent** connector that you neither own nor have had shared with you | `This Consile Studio connector is not available to the signed-in Consile account: it does not exist for this organisation, or it has not been shared with the signed-in user. It exposes no tools in this session. If the user asks why, say only that, and that the person who made it, or an administrator of the Consile account, can share it in the Consile portal under Studio.` |
| A person, or another bot's key, on an **AI-bot** connector | `This Consile Studio connector is not available to the signed-in principal: a bot connector runs only for its own bot, and an assistant connector only for a signed-in person. It exposes no tools in this session. If the user asks why, say only that, and that an administrator of the Consile account can change it in the Consile portal under Studio.` |
| The bot is paused | `This Consile Studio connector is paused by an administrator of the Consile account, so it exposes no tools in this session. If the user asks why, say only that, and that an administrator can resume it in the Consile portal under Studio.` |
| The own connector is deactivated | `This Consile Studio connector is deactivated. It exposes no tools in this session. Its owner or an administrator of the Consile organisation can activate it again in the Consile portal.` |

An own connector is deactivated with **Deaktivér** in the portal, and automatically
when its owner is removed from the team.

## Errors on a Studio endpoint

Refusals come back as a tool result with `isError: true`, as on the connector
endpoints. Most texts are the same. These differ, because a Studio endpoint offers
no connect link and sells nothing:

| Situation | Text in the result |
| - | - |
| The tool is not in the selection | `Unknown tool.` |
| The portal is not connected | `<id> is not connected yet. Connect it in the Consile portal under Connectors, at https://app.consile.ai/connectors/<connector>.` |
| The connector is no longer part of the organization's subscription or plan | `<id> is no longer part of the organisation's Consile subscription, so this tool cannot run. An administrator of the Consile account can check the subscription in the Consile portal under Connectors, at https://app.consile.ai/connectors/<connector>.` |
| The plan's monthly call limit is reached (signed-in person) | `This Consile account has used <used> of <limit> tool calls included in its plan for <YYYY-MM>, so the call was not made and nothing was changed. This is an account limit, not a fault: retrying will not help. The allowance resets at the start of next month. An administrator of the Consile account can review the subscription in the Consile portal (https://app.consile.ai). Report the limit and that one option; do not describe any other way of getting more calls.` |

`<id>` is the portal's endpoint id (for example `economic-2`) and `<connector>` the
connector it belongs to (`economic`). The seat, tool-access, company-lock and
approval texts are the same as on the connector endpoints; see
[Errors & limits](https://docs.consile.ai/developers/errors-and-limits.md). A bot gets its own texts for the
monthly limit and approvals; see [Texts a bot gets](#texts-a-bot-gets).

Requests are rate limited per own connector, and all of an organization's Studio
endpoints also share one budget. Over the limit you get HTTP `429` with
`Retry-After: 1` and the JSON-RPC error `-32029`, as described in
[Rate limits](https://docs.consile.ai/developers/errors-and-limits.md#rate-limits). Calls on a Studio endpoint
count as usage under the portal's id, like calls on the connector endpoint. A call
answered with `Unknown tool.` is not counted.

## AI bot keys

An **AI-bot** connector is called with a key, not with OAuth. Only administrators
create bots. The key is made when an administrator takes the bot live with
**Gå live**, and it is shown once (**Nøglen vises kun nu**). It cannot be shown
again; if it is lost, an administrator makes a new one.

* Format: `csl_bot_` followed by 40 letters and digits.
* Send it on every request as `Authorization: Bearer csl_bot_…`. The key is read
  only from that header. A key in the URL, a query parameter or the body is not
  accepted, and the request gets `401`.
* The key works only on its own bot's Studio endpoint. Sent to a connector endpoint
  such as `/economic/mcp`, to an extra portal's endpoint or to the Concierge `/mcp`,
  it gets `401`. Sent to another Studio endpoint, it gets no tools.
* A key expires 180 days after it was made, and then gets `401`. In the last 14
  days, administrators see **Nøglen udløber om … dage** on the bot.
* **Lav ny nøgle** makes a new key and stops the old one immediately.
  **Spær nøglen** stops the key: every request with it gets `401`, and the bot works
  again only with a new key.
* **Sæt på pause** keeps the key valid, but the endpoint serves no tools and the
  `initialize` instructions say that the connector is paused (see the table above).
  **Genoptag** starts the bot again.
* The RFC 9728 metadata on a bot endpoint points to the OAuth authorization server,
  which is for people. A bot key is never issued through OAuth, only in the portal.

A bot is not a user and does not sign in. The platform checks still apply to its
calls, and it can only use the tools in its own connector. Nobody is asked before a
bot writes, unless an administrator has made the tool require approval. A write tool
added to a live bot is not listed or callable until an administrator confirms the
bot again (**Bekræft igen**). If the same key is used from two different addresses
at about the same time, administrators see the warning **Bruges fra 2 steder**.

### Call limits

Each bot has a limit per minute and a limit per day. Both start at the maximum,
30 calls per minute and 1,000 calls per day, and an administrator can lower them but
not raise them. The day follows UTC. Every `tools/call` counts, including a call to
a tool outside the selection. Over a limit, the result is:

```
This bot has reached its limit of <N> calls per minute set by its administrator. Try again later.
```

with `per day` instead of `per minute` for the daily limit. The endpoint's ordinary
rate limit applies as well.

### Texts a bot gets

A bot's counterpart is usually outside the organization, so a bot gets neutral texts
without figures, request ids or portal routes in two cases:

| Situation | Text in the result |
| - | - |
| The organization's plan has used its monthly calls | `The Consile account this bot belongs to has used the tool calls included in its plan for this month, so the call was not made and nothing was changed. This is an account limit, not a fault: retrying will not help. If the user asks, say only that, and that an administrator of the Consile account has to resolve it.` |
| The tool requires approval (waiting, still pending, rejected or too many waiting) | `This tool requires a person at the Consile account to approve the call before it runs, so the call was not made and nothing was changed. This is an account policy, not a fault: retrying will not help. If the user asks, say only that, and that an administrator of the Consile account has to resolve it.` |

A bot's calls wait for approval like a person's. If an administrator approves the
call while it waits, it runs and returns its normal result. The bot's page in Studio
keeps a log of its calls for 30 days: time, tool, result and source address, never
data from the customer's system.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.