The manifest
GET <manifest-url> is the entire discovery surface — a directory of tools, not a proxy for calling them.
GET /manifest -> 200
{
"rcpVersion": "0.1",
"auth": { "type": "none" },
"tools": [
{
"name": "get_learner_profile",
"description": "Fetches a learner's plan and progress by id.",
"method": "GET",
"url": "https://api.example.com/learners/{{learnerId}}/profile",
"params": [
{ "name": "learnerId", "type": "string", "description": "The learner's id" }
],
"responseMappings": { "name": "@data.name", "progress": "@data.progress.percent" }
},
{
"name": "search_courses",
"description": "Searches the course catalog by free-text query.",
"method": "GET",
"url": "https://api.example.com/courses/search",
"queryParams": { "q": "{{query}}" },
"params": [
{ "name": "query", "type": "string", "description": "Free-text search term", "required": true }
]
}
]
}Tool fields
| Field | Required | Notes |
|---|---|---|
name | yes | Unique within this manifest. |
description | yes | What the model sees when deciding whether to call it. |
method | yes | GET | POST | PUT | PATCH | DELETE |
url | yes | May contain {{token}} placeholders — see params. |
params | no | Declares each token used in url/queryParams/headers/body: { name, type, description, required }. |
queryParams / headers | no | Token-templated maps, same substitution rules as url. |
body | no | A JSON template; presence implies the request has a JSON body. |
auth | no | Overrides the server-level auth for this one tool. Omitted = inherits it. |
responseMappings | no | { fieldName: "@json.path" } — reshapes the response before it reaches the model. |
Discovery and execution hit different places
The manifest URL is only ever a directory. A model’s tool call goes straight to the tool’s own url — which can be a completely different host than the manifest itself. Fetching the manifest tells a client what exists; it never proxies the actual call.
Versioning
rcpVersion is a plain string on every manifest response. A client that receives a manifest with a version it doesn’t understand should refuse to load that server’s tools rather than guess.