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:
- Should I use this? (description, kind, stability)
- What do I pass it? (
inputSchema) - What do I get back? (
outputSchema) - Is it safe? (
sideEffects,annotations.readOnly) - What does it cost / how long? (
costHint,latencyClass) - 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
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Globally unique slug. URL-safe. Stable. Equals the slug in Actions API. |
displayName | string | ✅ | Human-readable. May change without breaking. |
version | string | ✅ | SemVer of this manifest version, not the underlying model. |
stability | enum | ✅ | experimental | beta | stable. The tool's maturity level (used by the --stability filter). |
Classification
| Field | Type | Required | Description |
|---|---|---|---|
kind | enum | ✅ | llm | specialist | tool | trained_model | generative | model | operation |
category | string | optional | Domain category: nlp | vision | audio | time_series | tabular | multimodal |
tags | string[] | optional | Free-form tags for search and filter |
Descriptions
| Field | Type | Required | Description |
|---|---|---|---|
description | string | ✅ | ≤ 200 chars. Surfaced in tools/list. Should be enough for the agent to decide. |
longDescription | string | optional | Multi-paragraph. Use this for nuances, caveats, training context. |
I/O schemas
| Field | Type | Required | Description |
|---|---|---|---|
inputSchema | JSONSchema | ✅ | JSON-Schema 2020-12. May include $defs and $ref. |
outputSchema | JSONSchema | optional but recommended | Helps agents validate responses and parse robustly. |
If outputSchema is missing, the agent treats the response as opaque JSON.
Examples
| Field | Type | Required | Description |
|---|---|---|---|
examples | object[] | ≥ 2 recommended | Each: {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
| Field | Type | Required | Description |
|---|---|---|---|
sideEffects | string[] | ✅ (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"].
| Value | Meaning |
|---|---|
network | Tool makes outbound network calls beyond ColabHive |
storage | Tool writes to MinIO / object store |
pii | Tool may process personally identifiable info — agent should warn user |
cost | Tool consumes significant credits (>$0.01/call) |
mutating | Tool changes external state (writes, sends, posts) |
external | Tool depends on third-party services that may fail independently |
Hints
| Field | Type | Required | Description |
|---|---|---|---|
costHint | enum | ✅ | free | low (<$0.001) | medium (<$0.01) | high (>$0.01) per invocation |
latencyClass | enum | ✅ | instant (<200ms) | fast (<2s) | slow (<30s) | batch (>30s) |
Annotations (MCP spec)
| Field | Type | Required | Description |
|---|---|---|---|
annotations.readOnly | bool | ✅ | True if the tool does not alter any state. |
annotations.idempotent | bool | ✅ | True if N invocations with the same input produce the same effect as 1. |
annotations.destructive | bool | ✅ | True if invoking can cause data loss / irreversible actions. |
annotations.openWorld | bool | ✅ | 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 */ ],
"generatedAt": "2026-05-22T15:00:00Z",
"etag": "W/\"sha256:abc...\""
}
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 unchanged → 304 Not Modified, zero body. The MCP server reuses its in-memory cache. 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:
description— ≤ 200 chars. Imagine an agent reads only this. Will it know whether to use your tool?inputSchema— must be valid JSON-Schema 2020-12 and accurately describe accepted inputs. Tested at registration.outputSchema— strongly recommended even if your output is just{"text": "..."}.- ≥ 2 examples — required for
stability=stable. Cover happy path + edge case. sideEffects— honesty contract. Lying here is treated as a security bug, not a typo.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
- Architecture — how manifests flow through the system
- Tools Reference — every shipped tool with its manifest summary
- Actions API — the underlying surface