Skip to main content

Manifests — the tool contract

A manifest is the JSON metadata that describes one MCP tool: what it does, what it accepts, what it returns, what side-effects it has, what it costs.

colabhive-mcp fetches manifests from GET /api/builder/v1/mcp/manifest at startup and serves them to the client.


Why manifests matter​

When an agent sees a tool, it sees the manifest — not the implementation. A good manifest tells the agent:

  1. Should I use this? (description, kind, stability)
  2. What do I pass it? (inputSchema)
  3. What do I get back? (outputSchema)
  4. Is it safe? (sideEffects, annotations.readOnly)
  5. What does it cost / how long? (costHint, latencyClass)
  6. What's an example? (examples)

Agents using rich manifests pick tools better, validate inputs upfront, and surface errors with clearer messages. Tools without examples are often skipped.


Canonical schema​

Every manifest conforms to mcp-manifest.schema.json (published JSON-Schema 2020-12).

{
"name": "qwen-2.5-7b-instruct-public",
"displayName": "Qwen 2.5 7B Instruct",
"version": "1.0.0",
"stability": "stable",
"description": "Multilingual instruction-tuned LLM. Long context. Supports tool-use / function calling.",
"longDescription": "Qwen 2.5 7B trained by Alibaba, served via vLLM on ColabHive GPU nodes. Good for chat, summarization, and code generation across many languages. (Context window, price, and readiness are live values — read them from this manifest, don't assume.)",
"kind": "llm",
"category": "nlp",
"tags": ["chat", "multilingual", "open-source", "apache-2.0"],

"inputSchema": {
"type": "object",
"properties": {
"messages": { "type": "array", "items": { "$ref": "#/$defs/ChatMessage" } },
"temperature": { "type": "number", "minimum": 0, "maximum": 2, "default": 0.7 },
"max_tokens": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 512 }
},
"required": ["messages"]
},

"outputSchema": {
"type": "object",
"properties": {
"choices": { "type": "array", "items": { "$ref": "#/$defs/Choice" } },
"usage": { "$ref": "#/$defs/Usage" }
},
"required": ["choices"]
},

"examples": [
{
"name": "Simple chat",
"description": "Hello-world chat completion",
"input": { "messages": [{"role": "user", "content": "What is the capital of France?"}] },
"output": { "choices": [{"message": {"role": "assistant", "content": "Paris."}}] }
}
],

"sideEffects": [],
"costHint": "low",
"latencyClass": "fast",

"annotations": {
"readOnly": true,
"idempotent": false,
"destructive": false,
"openWorld": false
},

"lineage": null,
"deprecation": null,

"links": {
"documentation": "https://docs.colabhive.com/models/llms/qwen-2.5-7b-instruct",
"source": "https://huggingface.co/Qwen/Qwen2.5-7B-Instruct"
}
}

Field reference​

Identity​

FieldTypeRequiredDescription
namestring✅Globally unique slug. URL-safe. Stable. Equals the slug in Actions API.
displayNamestring✅Human-readable. May change without breaking.
versionstring✅SemVer of this manifest version, not the underlying model.
stabilityenum✅experimental | beta | stable. The tool's maturity level (used by the --stability filter).

Classification​

FieldTypeRequiredDescription
kindenum✅llm | specialist | tool | trained_model | generative | model | operation
categorystringoptionalDomain category: nlp | vision | audio | time_series | tabular | multimodal
tagsstring[]optionalFree-form tags for search and filter

Descriptions​

FieldTypeRequiredDescription
descriptionstring✅≤ 200 chars. Surfaced in tools/list. Should be enough for the agent to decide.
longDescriptionstringoptionalMulti-paragraph. Use this for nuances, caveats, training context.

I/O schemas​

FieldTypeRequiredDescription
inputSchemaJSONSchema✅JSON-Schema 2020-12. May include $defs and $ref.
outputSchemaJSONSchemaoptional but recommendedHelps agents validate responses and parse robustly.

If outputSchema is missing, the agent treats the response as opaque JSON.

A CLM scorer endpoint (CLM-8B or a head trained for it) declares an inputSchema that admits exactly one of system_one and rank: the endpoint's own schema when it has one, otherwise the platform's CLM schema. system_one takes state and questions ({id: {type: noul|choice|score, instructions, criteria}}), rank takes context, question and answers; both accept temperature. The CLM schema is chosen before the category rules, which would otherwise give an nlp row the chat messages schema. The public endpoint's outputSchema describes the model's envelope: result (the upstream answer), head_sha256, encoder_identity, runtime_vendor, device and dtype.

Examples​

FieldTypeRequiredDescription
examplesobject[]≥ 2 recommendedEach: {name, description, input, output}. Agents read these to disambiguate edge cases.

Curation guideline: at least one "happy path" + one "edge case" (long input, edge value, optional fields populated).

Side-effects​

FieldTypeRequiredDescription
sideEffectsstring[]✅ (may be [])From {network, storage, pii, cost, mutating, external}.

A pure model (LLM, classifier, embedder) → []. A web tool → ["network"]. A future "send_email" tool → ["network", "external", "mutating"].

ValueMeaning
networkTool makes outbound network calls beyond ColabHive
storageTool writes to MinIO / object store
piiTool may process personally identifiable info — agent should warn user
costTool consumes significant credits (>$0.01/call)
mutatingTool changes external state (writes, sends, posts)
externalTool depends on third-party services that may fail independently

Hints​

FieldTypeRequiredDescription
costHintenum✅free | low (<$0.001) | medium (<$0.01) | high (>$0.01) per invocation
latencyClassenum✅instant (<200ms) | fast (<2s) | slow (<30s) | batch (>30s)

Annotations (MCP spec)​

FieldTypeRequiredDescription
annotations.readOnlybool✅True if the tool does not alter any state.
annotations.idempotentbool✅True if N invocations with the same input produce the same effect as 1.
annotations.destructivebool✅True if invoking can cause data loss / irreversible actions.
annotations.openWorldbool✅True if the tool reaches outside the closed ColabHive world (e.g., web).

Operation tools (kind=operation)​

Platform operations (e.g. training.merge, training.retrain_on) are injected as static manifests rather than derived from a model row. They describe a job-creating action, so their hints use job-oriented labels: costHint: "training_quota" and a coarse latencyClass ("minutes" for a merge, "long" for retraining). Their sideEffects always include creates_job and creates_model_version. See the Tools Reference.

Lineage (trained models only)​

The gateway populates lineage only for endpoints backed by a training job, from the job + dataset JOIN. It emits exactly these fields:

{
"lineage": {
"jobId": "uuid",
"baseModel": "bert-classification-gpu",
"dataset": "fraud-transactions-2026",
"datasetDomain": "tabular",
"architecture": "bert-classification-gpu (transformers)",
"columns": { "text_column": "description", "label_column": "is_fraud" }
}
}

Deprecation​

The gateway emits deprecation when an endpoint has mcp_deprecated_at or mcp_replaced_by set, with exactly these fields:

{
"deprecation": {
"deprecatedAt": "2026-03-01T00:00:00Z",
"replacedBy": "<newer-endpoint-slug>"
}
}

Agents should surface deprecation warnings and prefer the replacedBy tool.


Discovery endpoint​

GET https://api.colabhive.com/api/builder/v1/mcp/manifest
Header: X-API-Key: hive_xxx

Response:

{
"protocolVersion": "2026-01-01",
"server": {
"name": "colabhive",
"version": "<gateway-service-version>",
"vendor": "ColabHive"
},
"tools": [ /* manifests */ ],
"hasMore": true,
"nextCursor": "<opaque-cursor>",
"generatedAt": "2026-05-22T15:00:00Z",
"etag": "W/\"sha256:abc...\""
}

The endpoint returns at most 1,000 dynamic tools per page. Follow nextCursor until it is null; hasMore tells you whether another page exists. The official colabhive-mcp client does this automatically and exposes one complete tools array. Built-in platform operations appear only on the first page.

GET /api/builder/v1/mcp/manifest?cursor=<opaque-cursor>

Single-tool detail​

GET https://api.colabhive.com/api/builder/v1/mcp/manifest/{slug}
Header: X-API-Key: hive_xxx

Caching with ETag​

Subsequent calls:

GET /api/builder/v1/mcp/manifest
If-None-Match: W/"sha256:abc..."

If an entire manifest fits in one page and is unchanged → 304 Not Modified, zero body. Paginated manifests are fetched completely on refresh because an unchanged first page does not prove that later pages are unchanged. The gateway returns a weak ETag (W/"sha256:...").


Authoring guidelines (for ColabHive model owners)​

If you publish a model to the marketplace, your manifest fields are mandatory:

  1. description — ≤ 200 chars. Imagine an agent reads only this. Will it know whether to use your tool?
  2. inputSchema — must be valid JSON-Schema 2020-12 and accurately describe accepted inputs. Tested at registration.
  3. outputSchema — strongly recommended even if your output is just {"text": "..."}.
  4. ≥ 2 examples — required for stability=stable. Cover happy path + edge case.
  5. sideEffects — honesty contract. Lying here is treated as a security bug, not a typo.
  6. costHint + latencyClass — heuristic-filled on registration, but you can override.

The developer console (console.colabhive.com/models/{slug}/manifest) has a form-driven editor + JSON validator.


Schema versioning​

The manifest's version field follows SemVer:

  • major — breaking input/output schema change (callers need to update)
  • minor — additive: new optional fields, new examples
  • patch — descriptions, tags, hints

The MCP server pins to a specific manifest version per session. Schema changes mid-session don't break running tool calls.


See also​