/docs/mcp
Host an MCP server in 5 minutes — no infrastructure required.
Amitte runs your MCP server for you. Declare your tools as JSON; we host the runtime at mcp.amitte.com, handle auth, retries, rate-limiting, and observability. Your consumers paste one snippet into Claude Desktop and they're done.
Hosting tiers
Manifest
Declare an HTTP template + JSONPath response shape. We interpret it. 60-70% of real MCP servers fit here — they're wrappers around APIs.
github_search_issues → GET api.github.com/search/issues
Bring your own URL
You host the MCP server. Amitte proxies, applies SSRF guards, signs the manifest, surfaces health. Same registry experience for consumers.
endpoint.your-domain.com → your service
Code
Small JS modules per tool, running in a sandboxed isolate. For tools needing computation or state beyond stateless HTTP. Coming once demand is real.
fn(input, ctx) → output
Container
Full Docker image, persistent process, native deps. For ML serving or stateful sessions. Enterprise tier.
dockerfile → fly machines
Authoring a tool
A tool spec is one JSON object. Here's a complete real example — github_search_issues, written for the manifest tier.
{
"spec_version": "1",
"tool_name": "github_search_issues",
"description": "Search GitHub issues by query",
"hosting_tier": "manifest",
"input_schema": {
"type": "object",
"properties": {
"query": { "type": "string", "minLength": 1 }
},
"required": ["query"]
},
"requires_secrets": [
{
"name": "github_token",
"description": "GitHub PAT, scope: repo",
"env_hint": "GITHUB_TOKEN"
}
],
"http": {
"method": "GET",
"url": "https://api.github.com/search/issues?q={{input.query}}",
"headers": {
"authorization": "Bearer {{secret.github_token}}",
"accept": "application/vnd.github+json"
},
"timeout_ms": 10000,
"error_map": [
{ "status": "401", "code": -32010, "message": "GitHub token invalid" },
{ "status": "403", "code": -32020, "message": "Rate limited by GitHub" }
]
},
"response": {
"map": "$.items[*].{number: number, title: title, url: html_url}",
"body_type": "json"
},
"idempotent": true,
"cache_ttl_seconds": 30
}Template fields use Mustache-style {{input.x}} / {{secret.y}}. Nested templates are rejected. Every {{secret.x}} reference must be declared in requires_secrets — undeclared secrets fail validation at publish time.
Secrets model
When the consumer's MCP client calls a tool, secrets ride inside the JSON-RPC body, never as cookies or stored values:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "github_search_issues",
"arguments": {
"query": "is:open label:bug",
"_secrets": {
"github_token": "ghp_xxx"
}
}
},
"id": 1
}- •
_secretsis stripped fromargumentsbefore the interpreter sees them. The gateway logs are redacted via pino's structured redaction; secrets never hit disk. - •Tool args matching common token shapes (
ghp_,sk_live_, etc.) are rejected if they appear outside_secrets— defense against publisher misuse. - •Templates can reference
{{secret.x}}only inhttp.url,http.headers, andhttp.body— never inresponse.map. Secrets are write-only into the upstream call.
Versioning
Three URL shapes, three guarantees:
| URL | Resolves to | When to use |
|---|---|---|
| /<pub>/<name>@0.2.1 | Exact pin | Default — what the install snippet generates. |
| /<pub>/<name>@v1 | Latest 1.x | Auto-pick minor/patch within a major version. |
| /<pub>/<name> | Latest published | Floats forever — only use for tools you fully trust to never break. |
Deprecated versions keep serving (consumers see a Deprecation: true response header). Archived versions return a structured error with data.upgrade_to so clients can prompt the user to migrate.
Security guarantees
Manifest signed
Each tool spec's hash is part of the parent manifest's Sigstore-signed payload. The interpreter verifies the chain before serving any request. A DB-level tamper invalidates the signature.
SSRF guarded
Every rendered HTTP target re-passes the SSRF guard — no private IPs, no cloud-metadata endpoints, no localhost. Template substitution can't escape the rule.
Bounded resources
10 MB max upstream response, 30s max timeout. One bad upstream can't OOM or stall the gateway.
Secrets never stored
The vault is opt-in. Default flow keeps tokens in the consumer's local config; they ride the wire encrypted by TLS and discarded after every call.