Call Tools on the MCP Endpoint
The Model Gateway publishes the RAG and MCP tools your API key may use at /mcp/. Any MCP client can list them and
call them. The gateway checks your permissions, runs the tool, and returns the result.
Set API_BASE_URL and API_KEY as in
Use Model Gateway tools with the Responses API, and use tools/list to get the exact
tool names.
Call a tool
Send one tools/call request with the tool name from tools/list and its arguments:
curl -fsS -X POST "${API_BASE_URL}/mcp/" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "YOUR_RAG__search_documents",
"arguments": {
"query": "What are the main conclusions?"
}
}
}'
Filter a RAG search
The RAG search_documents tool accepts optional metadata_filters. Filters decide which documents are eligible for
the existing relevance ranking; they do not add a metadata score or change ranking. When you send several filters,
every filter must match.
{
"name": "YOUR_RAG__search_documents",
"arguments": {
"query": "What are the main conclusions?",
"metadata_filters": [
{"field": "department", "operator": "contains", "value": "legal"},
{"field": "published", "operator": "gte", "value": "2026-01-01"}
]
}
}
Each filter has a metadata field, a value, and an operator: eq, contains, gt, gte, lt, or lte.
An invalid filter makes the tool call fail before the RAG searches any documents. See
Metadata filters for matching behavior, accepted values, and request limits.
Explore a RAG's document metadata
A RAG also publishes YOUR_RAG__explore_metadata. Use tools/list to get its exact name. The tool reads a
refreshable metadata catalog derived from the complete document corpus. It helps you find field paths and
filter-compatible values before calling search_documents.
Call it without arguments to list metadata fields:
curl -fsS -X POST "${API_BASE_URL}/mcp/" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "YOUR_RAG__explore_metadata",
"arguments": {}
}
}'
Add "field": "department" to return values and ranges for one known field. The optional runtime argument limit
accepts a value from 1 to 100 and defaults to 20. Without field, it bounds the number of fields. With field, it
bounds exact values and ranges together. It does not change or refresh the catalog.
The result contains:
| Field | What it means |
|---|---|
fields | Metadata paths returned when you omit field. Each entry reports observed container types and semantic value_types. |
values | Bounded exact values. Use lowercase discovered strings with case-insensitive contains. Booleans can be copied into typed filters. Exact-number objects preserve decimal text and can be copied when the encoded filter value stays within the 4 KiB limit. |
ranges | Bounded numeric, date, datetime, or time ranges. Each range reports its bounds, inclusivity, and granularity so you can construct gt, gte, lt, or lte filters. |
fields_truncated | More fields exist in the catalog than this response returned. You can raise limit only up to 100. |
values_truncated | More exact values or ranges exist for the requested field than this response returned. You can raise limit only up to 100. |
response_truncated | The encoded response reached the 64 KiB server limit. Raising limit does not recover omitted entries. |
catalog_ready | false until the first catalog refresh succeeds. Discovery entries are empty while it is false. |
catalog_dirty | Documents changed after the latest successful catalog refresh. |
refresh_status | pending, running, succeeded, failed, or unavailable. |
last_successful_refresh_at | When the latest successful catalog refresh finished. |
One call returns at most 100 deterministically ordered fields or 100 combined values and ranges. This interface does not currently provide a cursor, so entries after that first bounded result cannot be enumerated through subsequent pages.
The catalog is a snapshot. While the RAG endpoint is running, it refreshes after metadata writes have been quiet for five minutes and uses a 24-hour age-based refresh as a fallback. Search and filtering always use the current document metadata, so a known filter can work before its value appears in the catalog.
Nulls, empty values, unsupported value shapes, invalid paths, and values above the 4 KiB filter-value limit remain in
the authoritative document metadata but do not appear in discovery. These exclusions do not set the truncation flags.
The tool requires the same RAG can_read permission as search_documents.
Call a tool that needs a user sign-in
Some MCP tools belong to an external service that each user signs in to. To call one of these tools, send that
user's access token with the request. Obtain the token through the external service's OAuth authorization flow; the
gateway does not issue or refresh it. Put the token in params._meta.mcp_authorizations, under the name of the MCP
server. The server name is the part of the tool name before the two underscores, so github__search belongs to the
server github.
Obtain the token through the platform
The manager exposes two RPCs for a directly registered server. Both require can_invoke access to the server, the
same grant as calling its tools. Your client is responsible for the OAuth state, PKCE verifier, browser redirect, and
token storage.
POST /cmind.agents.v1.ExternalMcpServerService/GetExternalMcpServerOAuthMetadatawith{"name": "github"}to get the values needed to build the provider authorization URL.- Send the user to that URL with your state value and PKCE S256 challenge, then handle the authorization code at the
returned
redirectUri. POST /cmind.agents.v1.ExternalMcpServerService/ExchangeExternalMcpOAuthTokenwith the servername, thecode, the PKCEcodeVerifier, theredirectUri, and themetadataVersion. It returnsaccessToken,tokenType,expiresIn, and, when the provider issues one, arefreshToken.- Refresh an expired token by calling the same RPC with
refreshTokenandmetadataVersioninstead ofcode. A changed server configuration invalidates themetadataVersion. Fetch metadata again.
The platform performs the exchange without exposing the client secret. It does not persist the returned user tokens.
When you use such a server through a preset agent, you do not need any direct access to the
server — access to the agent is enough. Two agent-scoped RPCs run the sign-in for you: GetPresetAgentMcpOAuthMetadata
returns the data to start the browser flow, and ExchangePresetAgentMcpOAuthToken trades the returned code for a
token. Both check your access to the agent, not a server grant. The token stays yours; the platform does not store it.
curl -fsS -X POST "${API_BASE_URL}/mcp/" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "github__search",
"arguments": {
"query": "release notes"
},
"_meta": {
"mcp_authorizations": {
"github": {
"access_token": "YOUR_ACCESS_TOKEN"
}
}
}
}
}'
Only bearer tokens are accepted. Send the raw access token; the gateway adds the Bearer scheme upstream.
tools/list takes the same field, so send it during discovery as well to see the tools of a server the user has
signed in to.
When the tool asks for authorization
The direct /mcp/ endpoint only publishes an OAuth-backed server when its token is present and accepted. If the token
is missing, uses an unsupported type, or is refused by the external service, the server is omitted from tools/list
and its tools cannot be called.
The shared dispatcher returns this error payload for tool-calling flows such as the Responses API when an OAuth-backed tool cannot run:
{
"error": {
"type": "mcp_auth_required",
"code": "mcp_auth_required",
"message": "MCP server requires OAuth authorization",
"server": "github",
"auth_type": "oauth_authorization_code",
"reason": "missing_token",
"metadata_rpc": "GetExternalMcpServerOAuthMetadata"
}
}
reason | What it means |
|---|---|
missing_token | No access token was sent for this server. |
unsupported_token_type | The token is not a bearer token. |
rejected_token | The external service refused the token. Get a new token and call the tool again. |
When the tool belongs to a preset agent, the payload points at the agent-scoped RPC and names the agent:
{
"error": {
"type": "mcp_auth_required",
"code": "mcp_auth_required",
"message": "MCP server requires OAuth authorization",
"server": "github",
"auth_type": "oauth_authorization_code",
"reason": "missing_token",
"metadata_rpc": "GetPresetAgentMcpOAuthMetadata",
"agent_name": "acme-support"
}
}
Pass agent_name to GetPresetAgentMcpOAuthMetadata to start the sign-in for that agent. The reason values are
the same as above.
One message per request
Send a single JSON-RPC message when the request carries mcp_authorizations. A request whose body is an array of
messages is refused:
HTTP 400
OAuth-authorized JSON-RPC batches are not supported
Send each message as its own request. A request that carries no mcp_authorizations is not affected.