{
  "schema": "snappy-card/1",
  "skill": "snappy-agent-host",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "This hand is the ACP road through the skills MCP. It uses the exact adapters already bundled in SnappyOS.app and imports `@agentclientprotocol/sdk@1.4.0` from that runtime. The SDK owns NDJSON, JSON-RPC, method validation, and protocol constants. The hand does not install or reimplement ACP.",
  "verbs": [
    {
      "name": "start",
      "args": [
        "runtime",
        "cwd",
        "prompt"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts start <runtime> <cwd> \"<prompt>\""
    },
    {
      "name": "prompt",
      "args": [
        "session",
        "text"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts prompt <session> \"<text>\""
    },
    {
      "name": "status",
      "args": [
        "session"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts status <session>"
    },
    {
      "name": "cancel",
      "args": [
        "session"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts cancel <session>"
    },
    {
      "name": "sessions",
      "args": [],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts sessions"
    },
    {
      "name": "models",
      "args": [
        "runtime"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts models <runtime>"
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [
    "snappy-ax",
    "snappy-voice-control"
  ],
  "checks": {
    "pass": 36,
    "fail": 9,
    "defer": 16,
    "line": "36 of 45 checks pass",
    "failing": [
      {
        "id": 4,
        "rule": "Near-neighbour descriptions cross-reference each other",
        "says": "near neighbours not named: snappy-client-feisst, snappy-runner"
      },
      {
        "id": 8,
        "rule": "Skill body and reference graph stay within disclosure budgets",
        "says": "334 lines; ~13602 tokens"
      },
      {
        "id": 9,
        "rule": "Time-sensitive prose is isolated under Old patterns",
        "says": "2 time-sensitive instruction line(s) outside Old patterns"
      },
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path, field/box/element"
      },
      {
        "id": 11,
        "rule": "Each task presents one default, not a menu",
        "says": "2 line(s) present three-way alternative menus"
      },
      {
        "id": 16,
        "rule": "Runner-known values are not required arguments",
        "says": "runner-known required args: start.cwd"
      },
      {
        "id": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~161 tokens; body ~13602 tokens"
      },
      {
        "id": 55,
        "rule": "Eval scenarios are multi-call with ground truth",
        "says": "eval manifest missing"
      },
      {
        "id": 57,
        "rule": "Eval manifest contains a disjoint holdout",
        "says": "0 disjoint holdout scenario(s)"
      }
    ]
  },
  "coverage": null,
  "spec": null,
  "evals": null,
  "files": [
    "AGENTS.md",
    "SKILL.md",
    "agent-run.test.ts",
    "api.test.ts",
    "api.ts",
    "contract.test.ts",
    "references/agmente-codex-app-server.md",
    "references/agmente-test-oracle.md",
    "references/desktop-acp-clients.md",
    "references/extract-agent-host.md",
    "references/extract-agmente-rendering.md",
    "references/snappy-os-app-seams.md",
    "references/swift-acp-probe/Package.swift",
    "references/swift-acp-probe/Sources/probe/main.swift",
    "references/zed-acp-client.md",
    "references/zed-plan-usage-modes-commands.md"
  ],
  "total_size": 712956,
  "checksum": "sha256:a1ba531ce9d8fd84c37c28f3d98a2a01e612008f7696499053f35f75b31c5a68",
  "built_at": "2026-09-09T22:08:00.485Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-agent-host",
      "version": "0.0.0",
      "description": "Run the REAL Claude Code, Codex, and Gemini CLIs through ACP via the skills MCP, with durable per-folder sessions and every tool call, diff, plan, permission ask, answer, and cancellation printed as paged JSON lines. Also holds the full native SnappyOS.app ACP host research and proven launch constraints. Use for start/prompt/status/cancel/sessions, hosted coding agents, agent client protocol, or showing every agent step instead of a black box. NOT building an MCP server (see mcp-server-builder). Triggers on: ACP, agent client protocol, claude-agent-acp, codex-acp, app-server, host agent, embed CLI, durable agent session, agent steps."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-agent-host/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/start": {
        "post": {
          "operationId": "snappy_agent_host_start",
          "summary": "snappy-agent-host start",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runtime": {
                      "type": "string",
                      "description": "Which agent CLI to run over ACP",
                      "enum": [
                        "claude",
                        "codex",
                        "gemini"
                      ],
                      "x-snappy-position": 0
                    },
                    "cwd": {
                      "type": "string",
                      "description": "Absolute path of the folder the session runs IN; the repo is the team",
                      "x-snappy-position": 1
                    },
                    "prompt": {
                      "type": "string",
                      "description": "The first turn's text, sent once the session is up",
                      "x-snappy-position": 2
                    },
                    "permissions": {
                      "x-snappy-flag": "--permissions"
                    },
                    "model": {
                      "x-snappy-flag": "--model"
                    },
                    "effort": {
                      "x-snappy-flag": "--effort"
                    }
                  },
                  "required": [
                    "runtime",
                    "cwd",
                    "prompt"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/prompt": {
        "post": {
          "operationId": "snappy_agent_host_prompt",
          "summary": "snappy-agent-host prompt",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session": {
                      "type": "string",
                      "description": "Session id returned by start",
                      "x-snappy-position": 0
                    },
                    "text": {
                      "type": "string",
                      "description": "The turn to send to the running session",
                      "x-snappy-position": 1
                    },
                    "answer": {
                      "x-snappy-flag": "--answer"
                    }
                  },
                  "required": [
                    "session",
                    "text"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/status": {
        "get": {
          "operationId": "snappy_agent_host_status",
          "summary": "snappy-agent-host status",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "session",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Session id returned by start",
                "x-snappy-position": 0
              }
            },
            {
              "name": "cursor",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--cursor"
              }
            },
            {
              "name": "json",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--json"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/cancel": {
        "post": {
          "operationId": "snappy_agent_host_cancel",
          "summary": "snappy-agent-host cancel",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": true,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session": {
                      "type": "string",
                      "description": "Session id to stop; an already-stopped session answers the same",
                      "x-snappy-position": 0
                    }
                  },
                  "required": [
                    "session"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/sessions": {
        "get": {
          "operationId": "snappy_agent_host_sessions",
          "summary": "snappy-agent-host sessions",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/models": {
        "get": {
          "operationId": "snappy_agent_host_models",
          "summary": "snappy-agent-host models",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "runtime",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Runtime whose own advertised model list is read",
                "enum": [
                  "claude",
                  "codex",
                  "gemini"
                ],
                "x-snappy-position": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      }
    },
    "components": {
      "schemas": {
        "SnappyRefusal": {
          "type": "object",
          "required": [
            "outcome",
            "code",
            "message"
          ],
          "properties": {
            "outcome": {
              "type": "string",
              "const": "refused"
            },
            "code": {
              "type": "string",
              "description": "A row of the closed refusal table."
            },
            "message": {
              "type": "string"
            },
            "fix": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}