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
namestringGlobally unique slug. URL-safe. Stable. Equals the slug in Actions API.
displayNamestringHuman-readable. May change without breaking.
versionstringSemVer of this manifest version, not the underlying model.
stabilityenumexperimental | beta | stable. The tool's maturity level (used by the --stability filter).

Classification

FieldTypeRequiredDescription
kindenumllm | 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
inputSchemaJSONSchemaJSON-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.

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
costHintenumfree | low (<$0.001) | medium (<$0.01) | high (>$0.01) per invocation
latencyClassenuminstant (<200ms) | fast (<2s) | slow (<30s) | batch (>30s)

Annotations (MCP spec)

FieldTypeRequiredDescription
annotations.readOnlyboolTrue if the tool does not alter any state.
annotations.idempotentboolTrue if N invocations with the same input produce the same effect as 1.
annotations.destructiveboolTrue if invoking can cause data loss / irreversible actions.
annotations.openWorldboolTrue 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:

  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