{
  "schema": "snappy-card/1",
  "skill": "snappy-xano-mcp",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "Stateless Cloudflare Worker MCP server exposing ~50 Snappy Xano endpoints as 8 meta-tools over Streamable HTTP (POST /mcp) with OAuth2 PKCE auth. Spec revision 2026-07-28.",
  "verbs": [
    {
      "name": "health",
      "args": [],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts health"
    },
    {
      "name": "test",
      "args": [
        "tool"
      ],
      "effect": "write",
      "firstCall": "npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts test <tool>"
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [],
  "checks": {
    "pass": 36,
    "fail": 11,
    "defer": 14,
    "line": "36 of 47 checks pass",
    "failing": [
      {
        "id": 4,
        "rule": "Near-neighbour descriptions cross-reference each other",
        "says": "near neighbours not named: snappy-client-feisst, snappy-runner, snappy-slack, snappy-specwatch"
      },
      {
        "id": 5,
        "rule": "Description is valid, third-person, and says what plus when",
        "says": "first/second person"
      },
      {
        "id": 8,
        "rule": "Skill body and reference graph stay within disclosure budgets",
        "says": "428 lines; ~6645 tokens; deep reference ../mcp-server-builder/SKILL.md; deep reference ../snappy-infra/auth-reference.md"
      },
      {
        "id": 9,
        "rule": "Time-sensitive prose is isolated under Old patterns",
        "says": "1 time-sensitive instruction line(s) outside Old patterns"
      },
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path"
      },
      {
        "id": 11,
        "rule": "Each task presents one default, not a menu",
        "says": "1 line(s) present three-way alternative menus"
      },
      {
        "id": 32,
        "rule": "Refusals name a literal from the valid domain",
        "says": "refusals checked against contract literals"
      },
      {
        "id": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~254 tokens; body ~6645 tokens"
      },
      {
        "id": 54,
        "rule": "At least three eval scenarios precede ready status",
        "says": "0 eval scenario(s); ready=true"
      },
      {
        "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",
    "api.ts",
    "architecture.md",
    "debugging.md",
    "development.md",
    "refusals.test.ts"
  ],
  "total_size": 83766,
  "checksum": "sha256:020fe5d5dad2bda3309797a374504fa417c05fa65b5a926dd4d4323a13595cc3",
  "built_at": "2026-09-09T22:11:33.441Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-xano-mcp",
      "version": "0.0.0",
      "description": "THE EXISTING, DEPLOYED Snappy MCP server: the Cloudflare Worker exposing the Snappy Xano API (email, calendar, Slack, LinkedIn, FreshBooks, WhatsApp, YouTube, knowledge graph, async queue) over MCP Streamable HTTP with OAuth2 PKCE, 8 meta-tools (search/info/execute/list/query/dashboard/me/batch), wrangler tail debugging, registry generation, RFC 9728 metadata, the tasks extension. Use when Robert says: /snappy-xano-mcp, \\\"the snappy mcp\\\", \\\"the snappy xano mcp\\\", \\\"are we using tasks and durable objects, the latest mcp spec\\\", \\\"go through all the endpoints and fix the wording so they are AI first\\\", \\\"harden your mcp tools\\\", \\\"add a tool / redeploy the worker\\\", \\\"wrangler tail snappy-mcp\\\". Triggers on: snappy mcp, xano mcp worker, meta-tools, wrangler tail, oauth pkce, mcp tasks. NOT \\\"use the xano mcp\\\" to build endpoints inside Xano (see xanoscript-builder). NOT a from-scratch MCP for another backend (see mcp-server-builder). NOT the Snappy OS operator MCP on port 3147 (see snappy-os-operator)."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/health": {
        "get": {
          "operationId": "snappy_xano_mcp_health",
          "summary": "snappy-xano-mcp health",
          "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`."
            }
          }
        }
      },
      "/test": {
        "post": {
          "operationId": "snappy_xano_mcp_test",
          "summary": "snappy-xano-mcp test",
          "x-snappy-effect": "write",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tool": {
                      "type": "string",
                      "description": "MCP tool name to call",
                      "x-snappy-position": 0
                    }
                  },
                  "required": [
                    "tool"
                  ]
                }
              }
            }
          },
          "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"
            }
          }
        }
      }
    },
    "x-snappy-requires": [
      "XANO_METADATA_TOKEN"
    ]
  }
}