Hatch
Hosting for AI agents: publish a live website in one tool call, ephemeral or forever.
Sollte ich dies verwenden
Qualität und Sicherheit
Befunde (3)
- HIGH
- MEDIUMin hatch
- INFOin hatch
Basierend auf einer automatisierten Analyse der Tool-Definitionen und der Einhaltung des Protokolls.
Kontextkosten
Dies ist die ungefähre Anzahl der Tokens, die jedes Mal verbraucht werden, wenn die Tools des Servers in den Kontext eines Modells geladen werden. Höhere Werte verringern die Aufmerksamkeit, die für andere Aufgaben verfügbar ist.
Installieren
Installation mit einem Klick
Fügen Sie dies Ihrer Datei `claude_desktop_config.json` hinzu:
{
"mcpServers": {
"hatch": {
"url": "https://mcp.theroost.dev/mcp"
}
}
}Remote-Endpunkte
https://mcp.theroost.dev/mcpstreamable-httpWas es kann
Tool-Inventar
Tools (20)
🟡hatch(tier, kind, html, ttlSeconds, apex, ...)
Create a NEW site (a 'roost') and return its public URL in one call. Returns `{ hatchId, slug, url, apex, uploads? }` — show `url` to the user and remember `hatchId`. NEVER call hatch twice for the same site — use `convert` to rename or change tier, and `upload`/`deploy` for content updates. Pick `apex` from the user's intent (homes / estate / land / wedding / events / agency / site / omit for theroost.dev). Do NOT invent other apexes. Ways to call it: • `html` (PREFERRED for n8n / a single review page) → one self-contained HTML string published at /. Do not also pass site/manifest/script. • Omit `html`, `manifest`, `site`, and `script` → a placeholder page is published instantly. • Pass `manifest` (file list with sizes) → returns presigned `uploads[]`; you PUT each file's bytes directly to its URL. PREFER this for any project with images, fonts, video, or more than a few KB of HTML. • Pass `site` (inline files map) → small text-only sites only. File keys must be paths like `index.html` (n8n may send `index`; that is accepted as `index.html`). • Pass `script` → advanced: full server-side code as one ES module (1.5 MiB max, text only — NEVER base64-embed binaries here). Do not send empty strings for optional fields (hatchId, preferredSlug, apex, html, site). Omit them.
Eingabe-Schema
{
"type": "object",
"properties": {
"tier": {
"type": "string",
"enum": [
"free",
"forever"
],
"description": "`free` auto-expires (default 48h; override with `ttlSeconds`). In a paid Roost workspace, hatch stores `workspace` (still expires; not carousel-listed) even if you pass `free`. `forever` is a Pin (subscription slot or paid 1-year keep) — on this connector, hatch `free` then `checkout` with grant `publish`, or convert while subscription Pins remain."
},
"kind": {
"type": "string",
"enum": [
"site",
"run-report"
],
"description": "Artifact kind. Use `run-report` for agent observability / compliance run reports; default `site` for consumer sites."
},
"html": {
"type": "string",
"description": "Self-contained HTML document (inline CSS) published at /. Preferred for n8n and other AI tools that cannot pass nested site.files maps. Mutually exclusive with site, manifest, and script."
},
"ttlSeconds": {
"type": "integer",
"minimum": 3600,
"maximum": 604800,
"description": "Free-tier TTL in seconds (1h–7d). Default 172800 (48h). Ignored for `forever`."
},
"apex": {
"type": "string",
"enum": [
"theroost.dev",
"theroost.homes",
"theroost.estate",
"theroost.land",
"theroost.wedding",
"theroost.events",
"theroost.agency",
"theroost.site"
],
"description": "Specialty hostname apex for the live URL (`https://{slug}.{apex}`). Choose from user intent: theroost.homes (residential listing), theroost.estate (commercial/luxury), theroost.land (land/parcels), theroost.wedding (wedding RSVP), theroost.events (conference/meetup), theroost.agency (pitch/portfolio), theroost.site (generic short-lived niche). Omit for theroost.dev. Never pass theroost.rentals (reserved)."
},
"manifest": {
"type": "object",
"description": "PREFERRED for sites with assets. List every file you want served, with its byte size and optional MIME type. The response includes one presigned PUT URL per file; upload bytes directly via HTTP (e.g. `curl -T file.png -H 'Content-Type: image/png' \"$url\"`).",
"properties": {
"entry": {
"type": "string",
"description": "Document served at /. Default index.html"
},
"files": {
"type": "object",
"description": "Relative path → { size in bytes, optional contentType }.",
"additionalProperties": {
"type": "object",
"properties": {
"size": {
"type": "integer",
"minimum": 0
},
"contentType": {
"type": "string"
}
},
"required": [
"size"
]
}
}
},
"required": [
"files"
]
},
"site": {
"type": "object",
"description": "Inline file map. Suitable ONLY for small text-only sites (a handful of HTML/CSS files). For anything with images or binaries, use `manifest` instead.",
"properties": {
"entry": {
"type": "string",
"description": "Document served at /. Default index.html"
},
"files": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Relative path → contents. Text (UTF-8) for .html/.css/.js/.json/.svg; base64 (optionally prefixed `base64:`) for binary."
}
},
"required": [
"files"
]
},
"script": {
"type": "string",
"description": "Advanced: full server-side code as one ES module. Text only, 1.5 MiB hard limit. NEVER embed images/fonts/binaries here — use `manifest` instead."
},
"hatchId": {
"type": "string",
"description": "Optional id to reuse. Omit entirely to auto-generate. Do not send an empty string (n8n: leave this field unmapped). Lowercase letters, numbers, and hyphens only; 1–50 chars; must start and end alphanumeric."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"preferredSlug": {
"type": "string",
"description": "Hostname label. Omit for a friendly auto-name (e.g. swift-falcon-7a)."
},
"scriptMetadata": {
"type": "object",
"additionalProperties": true
},
"tosAcceptedAt": {
"type": "string",
"description": "ISO-8601 timestamp"
},
"workspaceId": {
"type": "string",
"description": "Workspace to hatch into (B2B). Omit when this connector is already paired to a workspace — the session supplies it. Do not hatch twice for a site that already exists in the workspace; call `list` first."
},
"policy": {
"type": "string",
"enum": [
"required",
"good_effort"
],
"description": "HITL policy override for workspace-paired hatches. `required` forks sibling `{slug}-vN` roosts when review is outstanding or approved; `good_effort` overwrites in place and supersedes open HITL. Inherits workspace default when omitted."
},
"webhookUrl": {
"type": "string",
"description": "Webhook for auto-opened HITL under workspace policy (see PARTNER-WEBHOOKS.md)."
},
"hitlTitle": {
"type": "string",
"description": "Modal title for auto-opened HITL."
}
},
"required": [
"tier"
]
}🔴upload(hatchId, tenantId, manifest, expiresSeconds, sessionToken, ...)
Add or replace files on an EXISTING roost. Pass `hatchId` plus a `manifest` listing each file's path, size, and optional content type. Returns one presigned PUT URL per file — upload bytes directly via HTTP (e.g. `curl -T file.png -H 'Content-Type: image/png' "$url"`). Files go live immediately as each PUT completes; no separate publish call is needed. Use after regenerating a dashboard locally; Hatch does not schedule regenerations.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId` from the original hatch response."
},
"manifest": {
"type": "object",
"properties": {
"entry": {
"type": "string",
"description": "Document served at /. Default index.html"
},
"files": {
"type": "object",
"description": "Relative path → { size in bytes, optional contentType }.",
"additionalProperties": {
"type": "object",
"properties": {
"size": {
"type": "integer",
"minimum": 0
},
"contentType": {
"type": "string"
}
},
"required": [
"size"
]
}
}
},
"required": [
"files"
]
},
"expiresSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 604800,
"description": "URL TTL in seconds (default 3600)."
},
"sessionToken": {
"type": "string",
"description": "Optional paired session token from poll_pairing (when Authorization headers are unavailable)."
},
"policy": {
"type": "string",
"enum": [
"required",
"good_effort"
],
"description": "HITL policy override. Under `required`, may fork a sibling `{slug}-vN` instead of overwriting."
},
"webhookUrl": {
"type": "string",
"description": "Webhook for auto-opened HITL."
},
"hitlTitle": {
"type": "string",
"description": "Modal title for auto-opened HITL."
}
},
"required": [
"manifest"
]
}🟢lookup(hatchId, tenantId, slug)
Resolve a roost by `slug` or `hatchId`. Returns a compact view `{ hatchId, slug, url, apex, tier, state, expiresAt, customDomain, galleryListed }`. Use this to recover state across turns when the user mentions their site without giving you the hatchId. To see every hatch in a workspace, use `list` instead.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"slug": {
"type": "string",
"description": "Hostname label (without the apex domain)"
}
},
"additionalProperties": false
}🟢list(workspaceId, sessionToken)
List every hatch in a workspace. Returns `{ workspaceId, name, count, hatches: [{ hatchId, slug, url, apex, kind, tier, state, expiresAt, createdAt }] }`. Use this when you lost hatchIds, before hatching (so you do not create a duplicate), or when the user asks what is live in the workspace. `workspaceId` is optional when this connector is already paired to a workspace. Requires a workspace-paired session — call `whoami`, then `get_pairing_code` with workspaceId if unidentified.
Eingabe-Schema
{
"type": "object",
"properties": {
"workspaceId": {
"type": "string",
"description": "Workspace to list. Omit when the session is already scoped to a workspace."
},
"sessionToken": {
"type": "string",
"description": "Optional paired session token from poll_pairing (when Authorization headers are unavailable)."
}
},
"additionalProperties": false
}⚪rename_org(workspaceId, orgName, workspaceName, sessionToken)
Rename the organization and/or workspace after Roost or Roost Audit has been paid. Pass `orgName`, `workspaceName`, or both. Requires a workspace-paired session. Fails on free Hatch workspaces — call `checkout` with grant `workspace_subscription` (Roost) or `agentic_pro` (Roost Audit) first, then `poll_checkout`. Does not rename a hatch URL; use `convert` for that. Returns `{ workspaceId, workspaceName, orgId, orgName, plan }`.
Eingabe-Schema
{
"type": "object",
"properties": {
"workspaceId": {
"type": "string",
"description": "Workspace to rename. Omit when the session is already scoped to a workspace."
},
"orgName": {
"type": "string",
"description": "New organization display name (1–80 characters). Omit to leave the org name unchanged."
},
"workspaceName": {
"type": "string",
"description": "New workspace display name (1–80 characters). Omit to leave the workspace name unchanged."
},
"sessionToken": {
"type": "string",
"description": "Optional paired session token from poll_pairing (when Authorization headers are unavailable)."
}
},
"additionalProperties": false
}🔴convert(hatchId, tenantId, newPreferredSlug, newTier, galleryListed, ...)
Atomically rename a roost's URL, change gallery listing, or bind a custom domain (Roost / Roost Audit after checkout grant custom_domain). Pass `hatchId` plus at least one of `newPreferredSlug`, `galleryListed`, or `customDomain`. Do NOT call `hatch` again to rename — that creates a second site. Roost and Roost Audit include 10 subscription Pins. `convert` with `newTier: forever` is allowed while those slots remain. After that, call `checkout` with grant `publish` (Pin, $4.99/yr). Do not use convert to collect payment. Pins are hidden from the carousel by default; pass `galleryListed: true` to feature the site publicly.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"newPreferredSlug": {
"type": "string",
"description": "New hostname label. The old slug is released atomically."
},
"newTier": {
"type": "string",
"enum": [
"free",
"forever"
],
"description": "Roost / Roost Audit may pass `forever` while subscription Pins remain (10). After the allotment, use `checkout` (grant: publish) for a paid Pin."
},
"galleryListed": {
"type": "boolean",
"description": "Opt in (`true`) or out (`false`) of the public Barnyard carousel. Pins require `true` to appear; free is listed unless `false`. Paid Roost hatches (`tier: workspace`) are never listed."
},
"customDomain": {
"type": "string",
"description": "Customer-owned hostname. Roost / Roost Audit only, after checkout grant custom_domain (+$29/mo). Pass an empty string to clear."
},
"sessionToken": {
"type": "string",
"description": "Optional paired session token from poll_pairing (when Authorization headers are unavailable)."
}
}
}🟢catalog(grant)
List VibeRooster features the user can pay for (Pin $4.99/yr, Pack $4.99/yr/GB, Roost $259/mo, Roost Audit $459/mo, custom domain +$29/mo) with Stripe Price ids, amounts, and feature lists. Call this before `checkout` if you don't already know the grant. Returns `{ items: [{ grant, title, description, features, priceId, amountCents, scope }] }`.
Eingabe-Schema
{
"type": "object",
"properties": {
"grant": {
"type": "string",
"enum": [
"publish",
"record",
"credit_topup",
"workspace_coin_pack",
"workspace_subscription",
"agentic_pro",
"custom_domain"
],
"description": "Optional filter. `publish` = Pin. `workspace_coin_pack` = Pack. `workspace_subscription` = Roost. `agentic_pro` = Roost Audit. `custom_domain` = custom domain add-on."
}
},
"additionalProperties": false
}🟡checkout(grant, hatchId, tenantId, workspaceId, orgId, ...)
Create a Stripe Checkout Session so the user can pay for a VibeRooster feature in this chat. Returns `{ checkoutUrl, sessionId, grant, amountCents }` — ALWAYS show checkoutUrl to the user (open it / paste it). After they pay, call `poll_checkout` with sessionId until status is `complete`. The webhook applies the grant (Pin, Pack, Roost, Roost Audit, custom domain). Required ids by grant: `publish` / `record` / `credit_topup` / `workspace_coin_pack` (Pack) → hatchId; `workspace_subscription` (Roost) / `custom_domain` → workspaceId (or hatchId in that workspace); `agentic_pro` (Roost Audit) → orgId or workspaceId/hatchId attached to the org. Do not use Stripe MCP (mcp.stripe.com) for VibeRooster features — that would charge a different Stripe account. Hatch `checkout` stamps hatch/workspace/org metadata the webhook expects.
Eingabe-Schema
{
"type": "object",
"properties": {
"grant": {
"type": "string",
"enum": [
"publish",
"record",
"credit_topup",
"workspace_coin_pack",
"workspace_subscription",
"agentic_pro",
"custom_domain"
],
"description": "`publish` = Pin ($4.99/yr, 1-year keep; also overage after 10 subscription Pins). `workspace_subscription` = Roost ($259/mo). `agentic_pro` = Roost Audit ($459/mo). `workspace_coin_pack` = Pack ($4.99/yr per GB). `custom_domain` = +$29/mo on Roost / Roost Audit."
},
"hatchId": {
"type": "string",
"description": "Hatch id from hatch/lookup. Required for publish (Pin), record, credit_topup, and Pack."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"workspaceId": {
"type": "string",
"description": "Workspace id. Required for Roost (`workspace_subscription`) and custom_domain."
},
"orgId": {
"type": "string",
"description": "Organization id. Required for Roost Audit (`agentic_pro`) unless derivable from workspace/hatch."
},
"priceId": {
"type": "string",
"description": "Optional Stripe Price id from `catalog`. Omit to use the mapped default for this grant."
},
"quantity": {
"type": "integer",
"minimum": 1,
"maximum": 20,
"description": "Line-item quantity (Pack GB, custom domain slots). Default 1."
}
},
"required": [
"grant"
],
"additionalProperties": false
}🟢poll_checkout(sessionId)
Long-poll a Checkout Session from `checkout` (~18s). Returns `{ status: open|complete|expired, grantApplied, roostUrl, tier }`. If still `open`, tell the user to finish paying at checkoutUrl and call poll_checkout again. When `grantApplied` is true, the webhook has (or is about to) apply the grant — call `lookup` to confirm forever/tier.
Eingabe-Schema
{
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "Checkout Session id (`cs_…`) from `checkout`."
}
},
"required": [
"sessionId"
],
"additionalProperties": false
}🔴auth(hatchId, tenantId, action, mode, password, ...)
Put a sign-in screen in front of any roost so visitors must authenticate. Works on free, workspace, and forever hatches. Pass `hatchId` plus an `action`: • `enable` with `mode: "password"` and a `password` → ONE shared site password (everyone uses the same one). Best for a private demo or staging link. • `setPassword` with a new `password` → rotate the shared password. • `disable` → remove the login and serve the site publicly again. • `status` → report whether auth is on and which mode. Returns `{ enabled, mode, loginUrl }`. The sign-in screen lives at `/__roost/login`. Prefer `password` mode; `useraccounts` is unavailable (per-hatch databases are no longer provisioned).
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId` from the original hatch response."
},
"action": {
"type": "string",
"enum": [
"enable",
"disable",
"setPassword",
"status"
],
"description": "What to do. Defaults to `status`."
},
"mode": {
"type": "string",
"enum": [
"password",
"useraccounts"
],
"description": "`password` = one shared site password (recommended). `useraccounts` is unavailable. Required when `action` is `enable`."
},
"password": {
"type": "string",
"description": "The shared site password (password mode only). Required for `enable` (password mode) and `setPassword`."
},
"sessionToken": {
"type": "string",
"description": "Optional paired session token from poll_pairing (when Authorization headers are unavailable)."
}
}
}🟢share(hatchId, tenantId, expiresSeconds, sessionToken)
Issue a signed, expiring guest view URL for any tier (`?vt=…`). Use for private run reports without the shared site password. Returns `{ url, viewToken, expiresAt }`.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"expiresSeconds": {
"type": "integer",
"minimum": 300,
"maximum": 604800
},
"sessionToken": {
"type": "string"
}
}
}🟡await_decision(hatchId, tenantId, options, title, agentOutput, ...)
Create a human-in-the-loop review on the live artifact. Default options: Approve / Request changes / Reject. Reviewers see a Review required chip → modal. Request changes is non-terminal: webhook or poll returns changes_requested, then call continue_decision after regenerating. Optional timeoutSeconds and maxIterations (default 5). If the page has interactive controls (sliders/forms), the hatch HTML MUST expose window.__VR_HITL_GET_SETTINGS__ so the review can attach those assumptions as JSON. When the user integrates n8n, Temporal, CI, or any external workflow, pass webhookUrl (MCP opens the review; the platform POSTs each transition to that URL — prefer webhook over poll_decision for automation). See PARTNER-WEBHOOKS.md for event payloads.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "Radio choices (default Approve, Request changes, Reject). Labels are classified into approve / reject / changes_requested."
},
"title": {
"type": "string",
"description": "Modal heading (default: Finish your review)."
},
"agentOutput": {
"type": "string",
"description": "Optional seed of the agent’s current output into the conversation transcript."
},
"maxIterations": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"description": "Max review rounds (default 5). Requesting changes at the last iteration fails with max_iterations_exceeded."
},
"timeoutSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 604800,
"description": "Wall-clock timeout for this review round; omit for no timeout."
},
"contextUrl": {
"type": "string"
},
"webhookUrl": {
"type": "string",
"description": "HTTPS URL that receives a POST on every HITL transition (decision.resolved, decision.changes_requested, timeout, superseded, etc.). Prefer this over poll_decision when wiring n8n, Temporal, or other automation — MCP creates the review; the webhook delivers the outcome. Full payload: PARTNER-WEBHOOKS.md."
},
"policy": {
"type": "string",
"enum": [
"required",
"good_effort"
],
"description": "Policy override when hatch has none set (idempotent with auto-opened HITL)."
},
"sessionToken": {
"type": "string"
}
}
}⚪continue_decision(decisionId, hatchId, tenantId, agentOutput, title, ...)
After poll_decision returns status changes_requested, regenerate, then call this to reopen the same decision as pending_review for the next human round.
Eingabe-Schema
{
"type": "object",
"properties": {
"decisionId": {
"type": "string"
},
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"agentOutput": {
"type": "string",
"description": "Summary of the revised output for the conversation transcript."
},
"title": {
"type": "string"
},
"timeoutSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 604800,
"description": "Optional new timeout for this review round."
},
"sessionToken": {
"type": "string"
}
},
"required": [
"decisionId"
]
}🟢poll_decision(decisionId, hatchId, tenantId)
Long-poll (~20s) until the decision leaves pending_review. Returns changes_requested (regenerate + continue_decision), approved, rejected, timeout_exceeded, max_iterations_exceeded, or still pending_review. Includes comment, settings, conversation, iteration.
Eingabe-Schema
{
"type": "object",
"properties": {
"decisionId": {
"type": "string"
},
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
}
},
"required": [
"decisionId"
]
}🟢whoami(hatchId, tenantId, sessionToken)
Return the caller's current identity and hatch state. Never errors when unidentified — returns a pairing path instead. After poll_pairing completes, whoami with the same hatchId should show identified:true via server-side session binding. Returns sessionExpiresAt (~1h) and grantExpiresAt (~7d). If sessionExpired:true, call refresh_session with your stored refreshToken.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Optional hatch to check or re-pair against."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"sessionToken": {
"type": "string",
"description": "Optional token from poll_pairing. Pass when whoami stays unidentified after a successful pair (connectors that cannot set Authorization headers)."
}
},
"additionalProperties": false
}🟢get_pairing_code(hatchId, tenantId, workspaceId, forceNew)
Issue a pairing code + URL (TTL 10 minutes) for claiming a hatch (`hatchId`) or authorizing an agent session in a workspace (workspaceId). Reuses the active pending code for this connector session unless `forceNew: true`. Render pairingUrl as a QR for the Vibe Rooster app — do not call again until poll_pairing returns expired/completed or you intentionally rotate with forceNew.
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from hatch response (consumer path)."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"workspaceId": {
"type": "string",
"description": "Workspace id for B2B agent pairing (partner path)."
},
"forceNew": {
"type": "boolean",
"description": "When true, invalidate any outstanding QR and mint a new code. Default false — reuse the live pending code from whoami or a prior get_pairing_code."
}
}
}🟢poll_pairing(code, hatchId, tenantId, workspaceId)
Poll for pairing completion (Device-Grant style). Waits up to ~20s for phone approval before returning. Statuses: pending / completed / expired / not_found. On completed, store sessionToken, refreshToken, and grantId — refreshToken renews access for up to 7 days without re-pairing. When sessionToken expires (~1h), call refresh_session. The server also binds tokens to this connector session. Pass hatchId when known. Device claim ≠ forever billing upgrade.
Eingabe-Schema
{
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Pairing code from get_pairing_code / whoami."
},
"hatchId": {
"type": "string",
"description": "Optional hatch id — improves lookup after the phone has approved."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"workspaceId": {
"type": "string",
"description": "Optional workspace id — for B2B pairing flows."
}
},
"required": [
"code"
]
}🟢refresh_session(refreshToken, hatchId, tenantId, workspaceId)
Renew a short-lived access token (~1h) using the refreshToken from poll_pairing. The grant (and refresh capability) lasts up to 7 days — after that, re-pair via get_pairing_code. Each refresh rotates the refreshToken; store the new one. Requires the same connector session (MCP-Session-Id) as when you paired — if fingerprint mismatches, re-pair.
Eingabe-Schema
{
"type": "object",
"properties": {
"refreshToken": {
"type": "string",
"description": "Opaque refresh token from poll_pairing (vr1.{grantId}.{secret})."
},
"hatchId": {
"type": "string",
"description": "Hatch id (consumer path)."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"workspaceId": {
"type": "string",
"description": "Workspace id (B2B path)."
}
},
"required": [
"refreshToken"
]
}🟢poll_approval(approvalId, hatchId, tenantId)
Poll a pending Tier-2 phone approval. Returns the result once the owner approves or denies on their phone.
Eingabe-Schema
{
"type": "object",
"properties": {
"approvalId": {
"type": "string"
},
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
}
},
"required": [
"approvalId"
]
}🔴deploy(hatchId, tenantId, workerName, script, metadata, ...)
Replace the server-side code of an existing roost. Advanced — most agents should use `upload` (for static files) or `convert` (for renames) instead. Pass `hatchId`, `workerName`, and a full ES module `script` (text only, 1.5 MiB max).
Eingabe-Schema
{
"type": "object",
"properties": {
"hatchId": {
"type": "string",
"description": "Hatch id from the original hatch response."
},
"tenantId": {
"type": "string",
"description": "Legacy alias for `hatchId`."
},
"workerName": {
"type": "string"
},
"script": {
"type": "string",
"description": "Full ES module source."
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"sessionToken": {
"type": "string",
"description": "Optional paired session token from poll_pairing (when Authorization headers are unavailable)."
},
"approvalId": {
"type": "string",
"description": "Tier-2 phone approval id from a prior deploy attempt."
},
"policy": {
"type": "string",
"enum": [
"required",
"good_effort"
],
"description": "HITL policy override. Under `required`, may fork a sibling `{slug}-vN`."
},
"webhookUrl": {
"type": "string",
"description": "Webhook for auto-opened HITL."
},
"hitlTitle": {
"type": "string",
"description": "Modal title for auto-opened HITL."
}
},
"required": [
"workerName",
"script"
]
}Community
Nachweis