How errors are returned
There are two kinds of errors. Problems with the HTTP request itself are returned as an HTTP error status before any tool runs. A tool call that fails is returned as a normaltools/call result with isError: true.
HTTP and protocol errors
These responses carry a JSON-RPC error body with"id": null, except the last two,
which carry a small JSON object.
Tool errors
A failed tool call returns HTTP200 with a JSON-RPC result, not a JSON-RPC error.
The result has isError: true and one text block that explains what went wrong:
A call to a connector that is not connected yet returns the connect link, even when
its arguments are invalid.
What
tools/list shows follows the same checks. Without a subscription, a connector
endpoint lists only connect_account (CVR lists nothing), and the initialize result
carries instructions that explain how to get access. A user without a seat still
sees the tools, but every call is refused. A tool that is not enabled for your user, by the
organization or by your access level, is not listed. See Authentication for the full access model.
While a subscription’s payment is overdue, the connector’s tools are withdrawn and
calls return the not-subscribed text. Do not buy the connector again. The stored
connection is kept, and access returns without reconnecting once the payment goes
through. An administrator manages the payment under Abonnement in the portal.
Messages from the provider
Most provider failures return the fixed textTool invocation failed., because a
provider’s raw error can contain data that should not be passed on. That covers a
provider error, a timeout and, on most connectors, a provider rate limit or a
validation error from the provider.
Some failures return an explanatory message instead:
- Expired or rejected access: when a connection has expired or the provider rejects
the stored access, the result usually says that the connector must be reconnected,
for example
Search Console rejected the access token (401); reconnect required. This applies to every connector except CVR, which has no connection of its own. Reconnect the connector in the portal. - e-conomic: a rate limit returns a message to wait and ask for fewer or smaller
pages. Temporary unavailability returns a message to try again shortly; after a
write, check in e-conomic whether it was applied before you repeat it. When
e-conomic rejects a request as invalid (HTTP
400,404or422, and409on the journal tools), the result summarizes what e-conomic rejected, such as the field, so the model can correct the call. See the e-conomic reference. - Uniconta, on the four daily-journal write tools: when Uniconta refuses a write
(for example missing rights or an unknown account), the result is
Uniconta refused <METHOD> <path>: <reason>. Nothing was changed.The connector’s own checks (unknown or blocked journal, a line that is not unposted, a posting preview that no longer matches) also return a message. See the Uniconta reference. - Ordrestyring: a rate limit that persists, and validation errors that name the field. See the Ordrestyring reference.
- Business Central (early access): missing permissions (
403), an unknown environment, a wrong company id (404), a rejected query (400) and a rate limit that persists. See the Business Central reference.
Tool invocation failed. for calls that used to work,
check the connector’s status in the portal and reconnect it there. The portal’s
disconnect button applies only to the first portal; for an extra portal, call
connect_account on that portal’s endpoint (for example /gsc-2/mcp) to get a new
connect link. Shopify can only be connected in the portal. CVR has no
connection of its own, so there is nothing to reconnect; if CVR calls keep failing,
try again later or write to support@consile.dk.
Rate limits
Consile currently allows 20 requests per second per account and connector endpoint, with bursts of up to 60 requests. Every authenticated HTTP request counts:initialize, tools/list, tools/call and the GET stream. Each connector
endpoint has its own budget, an extra portal endpoint such as /economic-2/mcp has
its own as well, and the Concierge endpoint /mcp has one per account. Heavy use of
one connector therefore does not slow down another.
Over the limit you get HTTP 429 with Retry-After: 1 and the JSON-RPC error
-32029 (Rate limit exceeded). Wait a second and retry. The limit is approximate.
It is there to stop runaway loops and is not a monthly quota; for monthly usage, see
Usage & fair use.
The portal API, including GET /api/usage, has its own limits: currently about
10 requests per second per client IP address and 20 per second per account. Over the
limit it returns 429 with Retry-After: 1 and {"error":"rate_limited"}.
Provider limits
Providers also limit requests. On some connectors Consile may briefly retry a provider’s rate-limit response before giving up. When the provider still refuses, e-conomic, Ordrestyring and Business Central return a message that tells you to wait, and the other connectors returnTool invocation failed.. Wait a moment, and ask for
fewer or smaller pages, before you retry.
Known provider limits: Dinero allows about 100 requests per minute per organization,
HubSpot about 110 requests per 10 seconds per connected HubSpot account, and Business
Central 6,000 requests per 5 minutes per Business Central user, shared with the
user’s other Business Central clients. Shopify throttles by query cost, and
Ordrestyring’s limit varies with the time of day.
Timeouts
Each request from Consile to a provider has a time limit, so a slow provider does not leave a call hanging. A call that times out returnsTool invocation failed.. Ask for
a shorter period or fewer rows and try again. If book_journal_entries times out, the
booking may still have completed in e-conomic, so check list_account_entries before
you retry. The same applies to Uniconta’s post_journal_lines: check
list_journal_lines before you retry.
Request limits
- Request size: a request body may be at most 256 KiB. A larger body gets HTTP
400withParse error. - Headers: send
Content-Type: application/jsonandAccept: application/json, text/event-streamon everyPOST. - Sessions: the endpoints are stateless. The server issues no
Mcp-Session-Id, so every request carries its own bearer token. APOSTmay be answered as a Server-Sent Events stream. - Browser calls: the MCP endpoints send no CORS headers and refuse a foreign
Originwith403. Call them from a server-side process or a native MCP client. - Long-running calls: while a tool call is still running on an SSE response stream,
the server sends an SSE comment line (
: keepalive) about every 25 seconds to keep the connection alive. Clients should ignore it.
Row limits per connector
The main page sizes and caps per connector are listed below. Each connector’s API reference has the full details.Google Search Console
- Rows per request: up to 25,000 (
limitontop_queriesandtop_pages,rowLimitonsearch_analytics_query). - Pagination: use
startRowinsearch_analytics_queryto fetch further rows. - Dates: always
YYYY-MM-DD. - Properties: you can only reach properties that the authorized Google account
already has access to. Use
list_sitesto see them.
CVR
sizeis 1–50 onsoeg_virksomhed,find_produktionsenhederandfind_virksomheder_for_person(default 10, or 50 forfind_produktionsenheder). Values outside the range are rejected, not reduced, and there is no paging beyond the first 50 rows.find_ejerehas nosizeand returns all relations.
Uniconta
- Rows per call:
limitdefaults to 50, max 1000. - Paging:
list_inventory_items,list_inventory_transactions,list_journal_linesandquerytakeoffset; follownextOffsetin the result. - Aggregation:
aggregatecovers at most about 50,000 rows per call and returnstruncated: truebeyond that; narrow the filters or the date range. A grouping that produces more than 1,000 groups fails the call. - Journal batches:
create_journal_lines,update_journal_linesandpost_journal_linestake at most 50 lines per call;delete_journal_linedeletes one line. - Write refusals: a write Uniconta refuses returns
Uniconta refused <METHOD> <path>: <reason>. Nothing was changed. - Confirming: the confirming call of
update_journal_linesapplies your changes to the lines as they are at that moment.post_journal_linesrefuses to post if a line changed after the preview.
e-conomic
- Page size: list tools take
pagesize(default 20, max 1000) andskippages. Not every list tool acceptsfilterorsort. - Journal batches:
create_journal_entries,update_journal_entriesandbook_journal_entriestake at most 50 entries per call. - Journal filters:
list_journal_entriescannot filter on text or amount. - Confirming: the confirming call of
update_journal_entriesapplies your changes to the entries as they are at that moment.book_journal_entriesrefuses to book if an entry changed after the preview.
Dinero
- Rate limit: Dinero allows about 100 requests per minute per organization. A call
Dinero keeps refusing returns
Tool invocation failed.. - Dinero Pro: the public API only works for organizations on Dinero Pro. A non-Pro
organization gets
403from Dinero on every call exceptlist_organizationsandvalidate_connection, and the call returnsTool invocation failed.. Uselist_organizationsto checkisPro.
Billy
- Page size: list tools take
pageandpageSize(default 50, 200 forlist_currencies, max 1000).
Ordrestyring
- Page size:
list_casesreturns up to 200 rows per page (limit, default 50).list_case_hoursandlist_case_sales_invoicescollect up tomaxRowsrows (default 500, max 2,000). find_casesscans at most the 1,000 most recently updated cases.- Result size:
graphql_queryresults over 100,000 characters, andintrospect_schemaordescribe_typeresults over 40,000 characters, are refused withTool invocation failed..
Meta Ads
- Rows per call:
limit1–5000 (default 100). A largelimitcan return fewer rows than requested. Usequerywithparams.afterto page further. - Budgets and bids on the write tools are in minor units of the account currency
(
5000= 50.00).
LinkedIn Ads
- Rows per call: list tools return up to
limitrows (default 100, max 1000). - Analytics:
get_ad_analyticsandget_ad_statisticsreturn one response without paging. LinkedIn caps it at 15,000 rows and accepts at most 20 metricfields. - Money: amounts are decimal strings in major units (
"500.00").currencyCodeis required with any amount and must match the ad account’s currency. - 22 tools (Company Page, organic posts, comments and reactions, member profile) are
not available yet; calls to them fail with
Tool invocation failed.. They are listed under Write tools & guardrails.
HubSpot CMS and HubSpot Marketing Email
- Page size: list tools take
limit(default 20, max 100) and theaftercursor frompaging.next.after. - Analytics (HubSpot CMS):
get_traffic_analyticstakes dates asYYYYMMDDandlimitup to 1000.
Shopify
- Rows per list call:
limitdefaults to 50, max 250. There is no cursor argument; narrow the result withquerywhere the tool takes one. graphql_query: one read-only query per call, at most 64 KiB (65,536 characters) and 20,000 tokens.
Business Central
- Page size: default 50, max 500 rows.
- Result size:
query_entityresults over 100,000 characters andlist_entity_metadataresults over 40,000 characters are refused withTool invocation failed..
Data freshness (Google Search Console)
Search Console data is not real-time. The most recent days may be incomplete or missing because Google is still collecting them.- Expect a delay of a couple of days on the newest numbers.
- In
search_analytics_queryyou can control this withdataState:final: only fully collected data.all: includes preliminary (fresh but unstable) data.
Empty numbers usually mean the period has no data yet, or the selected property
has no traffic in the range. That is not necessarily an error.