- Duale AI
- Documentation
- Tools
- MCP compatibility
MCP compatibility, call contract, and Tool catalog API
MCP compatibility, the synchronous call contract, fixed platform limits, and the Tool catalog API define how Duale AI connects to and invokes remote Tools.
Reference for MCP server compatibility, synchronous call behavior, fixed platform limits, and the organization Tool catalog API for SDK and MCP Tool Sources.
- MCP Connections require Streamable HTTP at one public HTTPS URL with specific MCP protocol versions.
- This release supports only synchronous MCP calls returning complete text or structured results.
- After three failures for one Tool, Duale AI pauses that Connection-and-Tool pair for 30 seconds.
- The Tool catalog API uses cursor pagination and requires user tokens bound via DPoP.
- Platform limits cap remote responses at 4 MiB and accepted Tool Results at 2 MiB.
Summaries were generated by AI.
Use this page to check MCP server compatibility, synchronous call behavior, and fixed limits. It also documents the organization Tool catalog API for SDK and MCP Tool Sources. For setup, connect an MCP server. For status, naming, Analytics, and recovery, operate Tools.
Confirm MCP server compatibility
An MCP Connection supports Streamable HTTP at one exact public HTTPS URL. The server must negotiate MCP 2025-06-18,
2025-11-25, or 2026-07-28 and answer catalog and Tool requests at that URL. Duale AI uses HTTP/1.1, does not
follow redirects, does not retain server cookies, requests an uncompressed response, and rejects a compressed
response. A server that negotiates an older MCP revision, or that depends on a redirect, cookie state, compression,
or HTTP/2, is not compatible with this release.
Choose one authentication mode: no authentication, one bearer token, or one API key in an allowed custom header. The same credential applies to catalog checks and Tool Calls for that named Connection.
Understand the MCP call contract
This release supports synchronous MCP calls that return a complete text or structured result. It does not continue
interactive input_required responses, queued MCP Tasks, or a task handle returned for later retrieval. Image, audio,
embedded resource, and resource-link result blocks are not supported.
Duale AI cannot guarantee exactly-once execution for a remote MCP Tool. When Duale AI cannot rule out that the server received a request, it does not intentionally retry that logical call. If it also cannot prove the response, the call ends as Outcome unknown. Make state-changing remote operations idempotent where possible. Check the destination system before any manual retry or compensation.
After three transport, timeout, or invalid-result failures for one Tool, Duale AI pauses that Connection-and-Tool pair for 30 seconds. Catalog checks and other Tools on the Connection continue. The next call after the pause can test the Tool again.
Check MCP Connection limits
These Platform limits are not configurable per Connection.
- Boundary
- Connection
- Limit
- 100-character name and 1,000 assigned Agent Identities
- Boundary
- Complete catalog check
- Limit
- 30 seconds, 128 pages, 4,096 Tools, and 4 MiB of Tool definitions
- Boundary
- One Tool definition
- Limit
- 512 KiB; 128-character native name; 4,096-character description
- Boundary
- Tool JSON Schemas
- Limit
- 64 levels and 100,000 total JSON nodes across the input and optional output schemas
- Boundary
- Tool Call arguments
- Limit
- 256 top-level properties
- Boundary
- Remote HTTP response
- Limit
- 4 MiB before protocol projection
- Boundary
- Accepted Tool Result
- Limit
- 2 MiB; at most 32 text blocks, each no more than 1 MiB
If a catalog check exceeds a limit, the whole check fails and does not replace the active catalog. If a Tool Result exceeds a limit, Duale AI rejects that result.
Tool limits covers the same boundaries for an SDK Tool Host, and how many Tools one Agent Identity can hold across every Source.
Read the organization Tool catalog API
The API reads the same retained repository shown in the Dashboard. These user-authenticated routes require a user
access token bound with Demonstrating Proof of Possession (DPoP), an acr claim of 2, and the permission shown below.
They do not accept an Agent Identity API token. The Dashboard obtains the user credential; this preview does not
document a standalone command-line sign-in flow. Tenant access policies explains
how permissions combine.
For managed beta, use https://api.beta.duale.ai/orgraph as the base URL. For another deployment, use the Orgraph base
URL supplied with that deployment.
- Request
GET /tenants/{tenant_id}/tool-sources- Permission
tools:read_catalogon the Tenant- Result and filters
- Source states; optional
source_kind=sdk|mcp
- Request
GET /tenants/{tenant_id}/tool-sources/tools- Permission
tools:read_catalogon the Tenant- Result and filters
- Retained Tools; optional
source_kind,source_id, andfreshness=active|expired|all; freshness defaults toall
- Request
GET /tenants/{tenant_id}/agents/{agent_id}/tools- Permission
agent:readon the Agent Identity- Result and filters
- Assigned Tools, offered first then recently lost; required
order_by_name=native|model; optionalfreshness=active|expired|all(defaultactive) andexpired_within_days(default 7, maximum 30)
This illustrative request asks for one active Tool assigned to an Agent Identity. Replace the user token and DPoP proof with values issued for your signed-in session.
GET /orgraph/tenants/tenant_a/agents/agent_research/tools?order_by_name=native&freshness=active&limit=1 HTTP/1.1
Host: api.beta.duale.ai
Authorization: DPoP <user-access-token>
DPoP: <proof>A successful response is a JSON object:
{
"agent_id": "agent_research",
"tools": [
{
"source_kind": "mcp",
"source_id": "0199d7df-40f8-7000-8000-000000000001",
"source_name": "CRM Production",
"native_tool_name": "search_contacts",
"model_tool_name": "mcp_search_contacts",
"description": "Search contacts",
"reasons": [],
"freshness": "active",
"last_observed_at": "2026-09-14T10:00:00Z",
"expires_at": "2026-09-14T10:07:00Z"
}
],
"next_cursor": null
}Each collection uses opaque cursor pagination. limit defaults to 100 and accepts 1 through 500. Send the returned
next_cursor unchanged with the same Tenant and filters. A null value marks the final page. These are live reads, not
a cross-page snapshot. If the catalog changes while you paginate and you need one consistent current traversal, restart
from the first page. The Agent Identity read pins the instant its first page was evaluated against and carries it in
the cursor, so every page of one traversal reports freshness against that instant. A different order_by_name,
freshness, or expired_within_days is a different traversal, and the earlier cursor is refused.
The response shapes are:
- Request
- Tool Source list
- Response body
sources: Source state objects;next_cursor: string ornull
- Request
- Retained Tool list
- Response body
tools: retained Tool objects;next_cursor: string ornull
- Request
- Tools assigned to one Agent Identity
- Response body
agent_id: requested identity;tools: assigned Tool objects;next_cursor: string ornull
The item fields are:
- Item
- Source state
- Fields
source_kind,source_id,source_name,freshness,last_observed_at,expires_at,assigned_agent_count,retained_tool_count
- Item
- Tool
- Fields
source_kind,source_id,source_name,native_tool_name,model_tool_name, optionaldescription,reasons,freshness,last_observed_at,expires_at
The retained Tool list and the Agent Identity list return the same Tool object. reasons states compatibility: it is
empty for a Tool the Platform can expose to a model, and an incompatible Tool has model_tool_name: null and one or more
entries in it. description is present only when the Source reports one. The Agent Identity response includes only
compatible Tools under the selected freshness filter, so its reasons is always empty.
Errors use application/problem+json. A malformed cursor, or a cursor reused with another Tenant or filter set, returns
400. Missing or insufficient user authentication returns 401. A caller without the required permission receives
403. An invalid path or query value returns 422.