Skip to main content

MCP tools

This page lists the tools of the Foundation4 Model Context Protocol (MCP) server: the name and description of each tool as an MCP client receives them, every argument with the input schema, the output with the output schema, the annotations, the permissions and the errors. The page also lists the server information of the initialize response and the HTTP errors of the /mcp endpoint. Integrators use this page to configure an MCP client and to interpret tool results. MCP server describes the transport, sessions, authentication and limits.

Server information​

The initialize response returns the following server information:

FieldValueDescription
protocolVersionThe revision named in the request, or 2025-11-25The server supports the revisions 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25 and 2026-07-28. A request for any other revision receives 2025-11-25.
capabilities{"tools": {}}Tools only. The server sends no list change notifications and declares no resources, prompts, completions or logging.
serverInfo.namermcpThe name of the MCP library that the API server uses, not a Foundation4 name
serverInfo.version3.1.4The version of the MCP library, not the Foundation4 release
instructionsFoundation4.aiA fixed text. The branding name configuration does not change the text.

The result of an initialize request with the revision 2025-11-25:

{
"protocolVersion": "2025-11-25",
"capabilities": {"tools": {}},
"serverInfo": {"name": "rmcp", "version": "3.1.4"},
"instructions": "Foundation4.ai"
}

The server also answers ping with an empty result, resources/list and prompts/list with empty lists, and completion/complete with an empty list of values. logging/setLevel returns the JSON-RPC error -32601.

Tool list​

tools/list returns the three tools in alphabetical order, in one page without a nextCursor. Each tool definition contains name, description, inputSchema, outputSchema and annotations, and no title. The schemas follow JSON Schema draft 2020-12, as the $schema field of each schema states.

ToolDescription sent to the client
get_pipeline_classificationsRetrieve a list of document classifications for a particular pipeline
get_pipelinesRetrieve a list of available Pipelines
search_knowledgePerform a search across a foundation4 pipeline. Returns ranked fragments with scores, source document IDs, and classification.

The annotations describe the effect of each tool. MCP clients treat annotations as hints, for example to decide whether a call needs the user's confirmation.

ToolreadOnlyHintdestructiveHintidempotentHintopenWorldHint
get_pipeline_classificationstruefalsetruefalse
get_pipelinestruefalsefalsefalse
search_knowledgetruefalsetruefalse

Tool results​

A successful tool call returns a result object with three fields:

FieldTypeDescription
contentArrayOne text block, {"type": "text", "text": "<JSON>"}, whose text is the tool output serialized as a JSON string
structuredContentObjectThe tool output as a JSON object, described by the outputSchema of the tool
isErrorBooleanfalse

The keys of every object in the tool output appear in alphabetical order, in both content and structuredContent. The MCP server page shows a complete response.

With the protocol revision 2026-07-28, which has no sessions, each request carries the revision in the MCP-Protocol-Version header and carries the revision and the client capabilities in _meta. The following tool call needs no session:

curl -X POST "$FOUNDATION4_URL/mcp" \
-H "x-api-key: $FOUNDATION4_API_KEY" \
-H "x-api-key-secret: $FOUNDATION4_API_SECRET" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: get_pipelines" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_pipelines",
"arguments": {"query": "support"},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}'

The response is an event stream with one event and no session identifier. The result object carries the field "resultType": "complete" before content, structuredContent and isError. A request whose _meta lacks io.modelcontextprotocol/clientCapabilities receives HTTP status 400 and the JSON-RPC error -32602 request _meta is missing or has malformed required fields: io.modelcontextprotocol/clientCapabilities.

Tool errors​

A failed tool call returns an error in one of two forms. When the arguments do not match the types of the input schema, the response is a result with isError set to true and one text block:

CauseText
A required argument is missingfailed to deserialize parameters: missing field `pipeline_id`
An argument has the wrong typefailed to deserialize parameters: invalid type: string "5", expected u16
type has an undefined valuefailed to deserialize parameters: unknown variant `vector`, expected one of `query`, `similarity`, `search`, `hybrid`, `mmr`, `history`

Arguments that the input schema does not define, such as filters or distance_strategy, are ignored without an error.

When the tool runs and the operation fails, the response is a JSON-RPC error object with code, message and, for some errors, data:

CodeMeaningMessages
-32600Invalid requestThe parser message of an identifier that is not a universally unique identifier (UUID), such as invalid length: found 3; Embedding model not found; Missing embedding model ID
-32602Invalid parameterstool not found, for a tool name that the server does not define
-32002Resource not foundPipeline not found, with data set to {"id": "<pipeline id>"}
-32603Internal errorEvery other failure, including permission errors, with a message that describes the failure

The following response reports a pipeline that does not exist or that the key cannot use:

{
"jsonrpc": "2.0",
"id": 2,
"error": {
"code": -32002,
"message": "Pipeline not found",
"data": {"id": "7d3e9a41-2b6c-4f8d-9e1a-5c0b3f6a8d27"}
}
}

HTTP errors​

The /mcp endpoint returns the following HTTP errors before a tool runs. Except for status 401 and the _meta error of revision 2026-07-28, which return JSON, the body is plain text, not the JSON error body of the REST API.

StatusBodyCause
400Bad Request: Session ID is requiredA GET or DELETE request without the Mcp-Session-Id header
400Bad Request: Unsupported MCP-Protocol-Version: <value>The MCP-Protocol-Version header names a revision that the server does not support
400JSON-RPC error -32602 request _meta is missing or has malformed required fields: <field>A request with the revision 2026-07-28 whose _meta lacks a required field, such as io.modelcontextprotocol/clientCapabilities
401JSON error body, such as Unauthorized: No API Key specified.The API key headers are missing or invalid, as described in Errors
403Forbidden: Host header is not allowedThe Host header names a host other than localhost, 127.0.0.1 or ::1
404Not Found: Session not foundThe Mcp-Session-Id header names an unknown or ended session, or a session of another API server replica
404EmptyA path under /mcp, such as /mcp/
405Method Not AllowedA method other than GET, POST and DELETE. The Allow header lists the three methods.
406Not Acceptable: Client must accept both application/json and text/event-streamThe Accept header of a POST request does not list both types
406Not Acceptable: Client must accept text/event-streamThe Accept header of a GET request does not list text/event-stream
413Payload Too Large: request body exceeds 4194304 bytesThe body is larger than 4 MiB
415Unsupported Media Type: Content-Type must be application/jsonThe Content-Type header is not application/json
415fail to deserialize request body <reason>The body is not a JSON-RPC message
422Unexpected message, expect initialize requestA request other than initialize without the Mcp-Session-Id header

get_pipelines​

get_pipelines lists the pipelines that the API key can read, ordered by pipeline identifier, with offset pagination. The tool corresponds to GET /pipelines with the name$contains filter.

ArgumentTypeRequiredDefaultDescription
limitInteger, 0 or greater, or nullNo10The maximum number of pipelines to return. A value of 0 returns no pipelines. No upper limit applies.
offsetInteger, 0 or greater, or nullNo0The number of pipelines to skip
queryString or nullNoNoneReturns only the pipelines whose name contains the text, case-sensitive. In the text, % matches any sequence of characters and _ matches any single character.

The call can omit arguments entirely. The output object has one field, results, an array of pipelines with the following fields:

FieldTypeDescription
pipeline_idStringThe pipeline identifier
nameStringThe pipeline name
descriptionString or nullThe pipeline description
embedding_model_idString or nullThe pipeline's vector embedding identifier, which the REST API returns as default_vector_embedding_id. The value is not an embedding model identifier and is not accepted as the embedding_model_id argument of search_knowledge.
default_text_splitter_idStringThe identifier of the pipeline's default text splitter

The output contains no total count and no page information. A client reads the next page with offset increased by limit, until a call returns fewer pipelines than limit.

  • Permissions. The tool returns only the pipelines on which the key holds read permission. A key without read permission on any pipeline receives an empty results array.
  • Errors. Argument type errors, such as a negative limit, return a result with isError set to true. A database failure returns error -32603.

Input schema:

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"description": "the maximum number of pipelines to return, defaults to 10",
"format": "uint",
"minimum": 0,
"type": ["integer", "null"]
},
"offset": {
"description": "the offset for pagination, defaults to 0",
"format": "uint",
"minimum": 0,
"type": ["integer", "null"]
},
"query": {
"description": "an optional search query to filter pipelines by name",
"type": ["string", "null"]
}
},
"type": "object"
}

Output schema:

{
"$defs": {
"Pipeline": {
"properties": {
"default_text_splitter_id": {
"description": "the unique identifier of the default text splitter used by the pipeline",
"type": "string"
},
"description": {"description": "the description of the pipeline", "type": ["string", "null"]},
"embedding_model_id": {
"description": "the unique identifier of the default embedding model used by the pipeline",
"type": ["string", "null"]
},
"name": {"description": "the name of the pipeline", "type": "string"},
"pipeline_id": {"description": "the unique identifier of the pipeline", "type": "string"}
},
"required": ["pipeline_id", "name", "default_text_splitter_id"],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {"results": {"items": {"$ref": "#/$defs/Pipeline"}, "type": "array"}},
"required": ["results"],
"type": "object"
}

The following call reads the first 10 pipelines whose name contains support:

{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {"name": "get_pipelines", "arguments": {"query": "support", "limit": 10}}
}

The structuredContent of the result for the support-kb pipeline of First search:

{
"results": [
{
"default_text_splitter_id": "019252e9-b4a0-7713-9a69-d701b4f4a2d1",
"description": "Support knowledge base",
"embedding_model_id": "5d1e8c2a-3f4b-4a6c-9e7d-1b2c3d4e5f60",
"name": "support-kb",
"pipeline_id": "c4a7e2d1-6b3f-4f8e-a2d9-7e1b5c3f9a06"
}
]
}

get_pipeline_classifications​

get_pipeline_classifications returns the classifications of one pipeline and the inheritance relationships between the classifications. The tool corresponds to GET /pipelines/{id}/classifications and returns the same object.

ArgumentTypeRequiredDefaultDescription
pipeline_idStringYesNoneThe pipeline identifier, a UUID
FieldTypeDescription
classificationsArray of stringsThe classifications that the pipeline defines
hierarchyArray of pairs of stringsThe inheritance relationships. Each pair names a classification and a classification that the first classification inherits.

Classifications describes inheritance.

  • Permissions. The key requires read permission on the pipeline and the classification allow-list * on the pipeline, as for the REST operation.
  • Errors. An identifier that is not a UUID returns error -32600 with the parser message. A pipeline that does not exist, or on which the key lacks read permission, returns error -32002 Pipeline not found. A key whose allow-list on the pipeline is not * receives error -32603 with the message Authorization error: AccessLevel(READ).

Input schema:

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {"pipeline_id": {"description": "the unique identifier of the pipeline", "type": "string"}},
"required": ["pipeline_id"],
"type": "object"
}

Output schema:

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"classifications": {
"description": "List of classifications associated with the pipeline",
"items": {"type": "string"},
"type": "array"
},
"hierarchy": {
"description": "Hierarchy of classifications (classification, derived classification)",
"items": {
"maxItems": 2,
"minItems": 2,
"prefixItems": [{"type": "string"}, {"type": "string"}],
"type": "array"
},
"type": "array"
}
},
"required": ["classifications", "hierarchy"],
"type": "object"
}

The structuredContent of the result for the support-kb pipeline of First search, which defines the classifications public and internal, where internal inherits public. The tool returns the same object as GET /pipelines/{id}/classifications, in the same order:

{
"classifications": ["internal", "public"],
"hierarchy": [["internal", "public"]]
}

search_knowledge​

search_knowledge runs a similarity, maximal marginal relevance (MMR) or full-text search on one pipeline and returns the ranked fragments. The tool corresponds to POST /pipelines/{id}/search, without metadata filters and without a distance strategy.

ArgumentTypeRequiredDefaultDescription
pipeline_idStringYesNoneThe pipeline identifier, a UUID
embedding_model_idString or nullNoThe pipeline's default embedding modelThe identifier of an embedding model that the pipeline uses: the id field of a model in the embedding_models object of the REST pipeline, the same identifier as params.embedding in REST search
queryStringYesNoneThe search text
classificationsArray of stringsYesNoneThe classifications to search, matched hierarchically: each named classification and every classification that the named classification inherits. Names that the pipeline does not define are ignored, and an empty array returns no fragments.
typeStringYesNoneThe search type: similarity, mmr or search (full-text search). The schema also lists query, hybrid and history, which return errors.
paramsObjectNoThe defaults of the search typeThe parameters of the search type

The params object accepts the following fields:

ParameterTypeSearch typesDefault without paramsDescription
kInteger, 0 to 65535All5The number of fragments to return. A value of 0 returns no fragments.
fetch_kInteger, 0 to 65535mmr10The number of candidates from which MMR search selects k fragments
lambda_multNumber or nullmmr0.5The balance between relevance (1) and diversity (0)
thresholdNumber or nullAllNoneFor similarity and MMR search, the maximum distance from the query. For full-text search, the minimum rank.
embeddingString or nullsimilarity, mmrNoneAccepted and ignored. The embedding model comes from the embedding_model_id argument.

When the call includes params, a k or fetch_k that params omits takes the value 0, as the "default": 0 of the schema states, and the search returns no fragments. A lambda_mult that params omits takes the value 0.5. Search requests describes each parameter in detail.

The tool processes a call in the following order:

  1. Pipeline. The tool reads the pipeline with the key's read and execute permissions.
  2. Embedding model. The tool selects the embedding model named by embedding_model_id, or the pipeline's default embedding model. A call on a pipeline without an embedding model, such as a full-text-only pipeline, stops here with the error Missing embedding model ID.
  3. Query embedding. The tool converts the query into a vector with the embedding model, for every search type, including full-text search and the types that return errors.
  4. Search. The tool runs the search of type with the cosine distance strategy, the hierarchical classifications and no metadata filter.

The output object has one field, results, an array of fragments ordered as in REST search: by ascending distance for similarity and MMR search, and by descending rank for full-text search.

FieldTypeDescription
idStringThe fragment identifier
classificationStringThe classification of the fragment's document
metadataObjectThe metadata of the fragment's document
document_idStringThe identifier of the document
page_contentStringThe decrypted text of the fragment. The field is absent when the text is empty.
versionIntegerThe document version, in microseconds since the Unix epoch
expired_atString or nullAlways null in search results
embeddingArray of numbersDefined in the schema, never present in search results
scoreNumberThe distance for similarity and MMR search, or the rank for full-text search
order_idIntegerThe position of the fragment within the document version, starting at 0
  • Permissions. The key requires read and execute permission on the pipeline, as for REST search.
  • Errors. The following table lists the errors of the tool in addition to the argument errors described in Tool errors.
CodeMessageCause
-32600The parser message, such as invalid length: found 3pipeline_id or embedding_model_id is not a UUID
-32002Pipeline not foundThe pipeline does not exist, or the key lacks read and execute permission on the pipeline
-32600Embedding model not foundembedding_model_id names a model that the pipeline does not use, including the embedding_model_id value of the pipeline listing
-32600Missing embedding model IDThe call omits embedding_model_id and the pipeline has no default embedding model. A full-text-only pipeline returns this error for every search type, including search.
-32603A message that describes the failureThe embedding model could not convert the query into a vector
-32603Hybrid placeholder is not implemented yettype is hybrid. data holds the parsed parameters, nested as {"params": {"params": {...}}}.
-32603History placeholder is not implemented yettype is history. data holds the parsed parameters, as for hybrid.
-32603Invalid search type or parameterstype is query
-32603A message that describes the failuretype is search on a pipeline without full-text search, or another operation failure

Input schema. The oneOf list defines type and params, and each Params definition names the parameter object of one search type:

{
"$defs": {
"Params": {
"properties": {"params": {"$ref": "#/$defs/PlaceholderParameterSimilarity"}},
"type": "object"
},
"Params2": {"properties": {"params": {"$ref": "#/$defs/PlaceholderParameterSearch"}}, "type": "object"},
"Params3": {"properties": {"params": {"$ref": "#/$defs/PlaceholderParameterHybrid"}}, "type": "object"},
"Params4": {"properties": {"params": {"$ref": "#/$defs/PlaceholderParameterMmr"}}, "type": "object"},
"Params5": {
"properties": {"params": {"$ref": "#/$defs/PlaceholderParameterHistory"}},
"type": "object"
},
"PlaceholderParameterHistory": {
"properties": {
"k": {"default": 0, "format": "uint16", "maximum": 65535, "minimum": 0, "type": "integer"}
},
"type": "object"
},
"PlaceholderParameterHybrid": {
"properties": {
"embedding": {"default": null, "format": "uuid", "type": ["string", "null"]},
"k": {"default": 0, "format": "uint16", "maximum": 65535, "minimum": 0, "type": "integer"}
},
"type": "object"
},
"PlaceholderParameterMmr": {
"properties": {
"embedding": {"default": null, "format": "uuid", "type": ["string", "null"]},
"fetch_k": {"default": 0, "format": "uint16", "maximum": 65535, "minimum": 0, "type": "integer"},
"k": {"default": 0, "format": "uint16", "maximum": 65535, "minimum": 0, "type": "integer"},
"lambda_mult": {"default": null, "format": "double", "type": ["number", "null"]},
"threshold": {"default": null, "format": "double", "type": ["number", "null"]}
},
"type": "object"
},
"PlaceholderParameterSearch": {
"properties": {
"k": {"default": 0, "format": "uint16", "maximum": 65535, "minimum": 0, "type": "integer"},
"threshold": {"default": null, "format": "double", "type": ["number", "null"]}
},
"type": "object"
},
"PlaceholderParameterSimilarity": {
"properties": {
"embedding": {"default": null, "format": "uuid", "type": ["string", "null"]},
"k": {"default": 0, "format": "uint16", "maximum": 65535, "minimum": 0, "type": "integer"},
"threshold": {"default": null, "format": "double", "type": ["number", "null"]}
},
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"oneOf": [
{
"description": "Query placeholder.",
"properties": {"type": {"const": "query", "type": "string"}},
"required": ["type"],
"type": "object"
},
{
"$ref": "#/$defs/Params",
"description": "Similarity placeholder.",
"properties": {"type": {"const": "similarity", "type": "string"}},
"required": ["type"],
"type": "object"
},
{
"$ref": "#/$defs/Params2",
"description": "Search placeholder.",
"properties": {"type": {"const": "search", "type": "string"}},
"required": ["type"],
"type": "object"
},
{
"$ref": "#/$defs/Params3",
"description": "Hybrid placeholder.",
"properties": {"type": {"const": "hybrid", "type": "string"}},
"required": ["type"],
"type": "object"
},
{
"$ref": "#/$defs/Params4",
"description": "MMR placeholder.",
"properties": {"type": {"const": "mmr", "type": "string"}},
"required": ["type"],
"type": "object"
},
{
"$ref": "#/$defs/Params5",
"description": "History placeholder.",
"properties": {"type": {"const": "history", "type": "string"}},
"required": ["type"],
"type": "object"
}
],
"properties": {
"classifications": {
"description": "the classifications to use for the search results",
"items": {"type": "string"},
"type": "array"
},
"embedding_model_id": {
"description": "the unique identifier of the embedding model to use for the search",
"type": ["string", "null"]
},
"pipeline_id": {"description": "the unique identifier of the pipeline", "type": "string"},
"query": {"description": "the search query for the pipeline", "type": "string"}
},
"required": ["pipeline_id", "query", "classifications"],
"type": "object"
}

Output schema:

{
"$defs": {
"Fragment": {
"properties": {
"classification": {"description": "Classification of the document fragment", "type": "string"},
"document_id": {
"description": "Document unique identifier associated with the fragment",
"type": "string"
},
"embedding": {
"description": "Embedding of the document fragment",
"items": {"format": "double", "type": "number"},
"type": ["array", "null"]
},
"expired_at": {
"description": "Expiration date of the document fragment (if applicable)",
"format": "date-time",
"type": ["string", "null"]
},
"id": {"description": "Unique identifier of the document fragment", "type": "string"},
"metadata": {"description": "Metadata associated with the fragment"},
"order_id": {
"description": "Order id of the fragment within the document",
"format": "int64",
"type": "integer"
},
"page_content": {"description": "Content", "type": "string"},
"score": {"description": "Score if available", "format": "double", "type": ["number", "null"]},
"version": {
"description": "Version of the document fragment",
"format": "int64",
"type": "integer"
}
},
"required": ["id", "classification", "metadata", "document_id", "page_content", "version", "order_id"],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {"results": {"items": {"$ref": "#/$defs/Fragment"}, "type": "array"}},
"required": ["results"],
"type": "object"
}

The following call runs an MMR search for 5 fragments from 20 candidates:

{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "search_knowledge",
"arguments": {
"pipeline_id": "c4a7e2d1-6b3f-4f8e-a2d9-7e1b5c3f9a06",
"query": "How do I rotate the database credentials?",
"classifications": ["internal"],
"type": "mmr",
"params": {"k": 5, "fetch_k": 20, "lambda_mult": 0.5}
}
}
}

The structuredContent of the result for the support-kb pipeline of First search. The pipeline holds no document about database credentials, so the search returns the three fragments of the pipeline by ascending distance. A threshold in params drops fragments beyond a given distance.

{
"results": [
{
"classification": "public",
"document_id": "01a0ed0d-cf82-7c3d-8e4f-5a6b7c8d9e0f",
"expired_at": null,
"id": "01a0ed0d-d291-7c5d-8e4f-3a2b1c0d9e8f",
"metadata": {"product": "accounts"},
"order_id": 0,
"page_content": "To reset a password, open Settings, choose Security and select Reset password. A reset link is sent to the registered email address and expires after 30 minutes.",
"score": 0.6850275409090324,
"version": 1790683500418273
},
{
"classification": "internal",
"document_id": "01a0ed0d-d75f-7d5e-8f60-718293a4b5c6",
"expired_at": null,
"id": "01a0ed0d-d814-7d6c-8b5a-4c3d2e1f0a9b",
"metadata": {"product": "billing"},
"order_id": 0,
"page_content": "Invoices are generated on the first day of each month. Finance staff can export invoices as PDF or CSV files from the Billing page.",
"score": 0.8752695693762373,
"version": 1790683502431906
},
{
"classification": "internal",
"document_id": "01a0ed0d-df3f-7f80-9a1b-2c3d4e5f6a7b",
"expired_at": null,
"id": "01a0ed0d-e007-7c3d-8e4f-6a7b8c9d0e1f",
"metadata": {"product": "billing"},
"order_id": 0,
"page_content": "Refunds for annual plans are prorated. Support agents must record the refund reason in the ticket before approving a refund.",
"score": 1.0389346220209017,
"version": 1790683504447128
}
]
}