← All Skills

snappy-xano-mcp

v1.0.0
7 files, 81.8 KB ~7,916 words · 32 min read Updated 2026-09-09

snappy-xano-mcp skill

36 of 47 checks pass
What it can do
healthread
test toolwrite
What does not pass yet
Architecture 6 endpoints
🔑 Bearer token auth
GETPOST
xnwv-v1z6-dvnr.n7c.xano.io5 endpoints
POST/api:GROUP_ID/endpoint
POST/api:hZB4Dj0c/slack/bot-message
GET/api:GROUP_ID/endpoint
GET/api:hZB4Dj0c/slack/bot-message
GET/api:e6emygx3/me
localhost:87871 endpoint
POST/mcp
$ npx snappy-skills install snappy-xano-mcp
zip ↓
Documents
AGENTS.md

Context#

snappy-xano-mcp is a Cloudflare Worker that wraps the Snappy Xano API surface (~50 endpoints across 7 API groups) into 8 standard MCP meta-tools. Clients (Claude Code, ChatGPT, Cursor, Windsurf) connect once via OAuth2 PKCE and access email, calendar, Slack, LinkedIn, FreshBooks, WhatsApp, YouTube, knowledge graph, and the async queue through a single Streamable HTTP endpoint (POST /mcp). Built on @modelcontextprotocol/server v2 + agents + Hono on a stateless Worker — no Durable Objects, no sessions, no initialize handshake.

Target spec revision: 2026-07-28.

8 Meta-Tools#

Tool Purpose Hits Xano?
snappy_search Fuzzy search across all tools No
snappy_info Tool docs + expected params No
snappy_execute Call any tool by ID Yes
snappy_list Browse tools by group No
snappy_query Raw queries via Xano Yes
snappy_dashboard Aggregated stats Yes
snappy_me Current user + org info Yes
snappy_batch Sequential multi-tool (up to 10) Yes

Standard flow: snappy_search -> snappy_info -> snappy_execute.

tools/list (and snappy_list) MUST return ttlMs + cacheScope, sorted deterministically by

tool id. snappy_batch is the tasks-extension candidate — anything over ~10s belongs to

io.modelcontextprotocol/tasks, not to a synchronous batch.

Current Config (spec 2026-07-28)#

  • compatibility_date: "2026-06-11"
  • No migrations block, no durable_objects block -- MCP needs no Durable Object
  • @modelcontextprotocol/server: "2.0.0" + zod: "^4.4.3" (SDK v2 requires Zod v4)
  • agents: "^0.20.1"
  • @cloudflare/workers-oauth-provider: "^0.10.3" with clientIdMetadataDocumentEnabled: true
  • resource: canonical /mcp URL in OAuthProvider -- drives RFC 9728 PRM + RFC 8707 audience
  • observability: { enabled: true } -- without it, wrangler tail returns nothing

Protocol Musts#

  • server/discover MUST be implemented (SDK answers it; a hand-rolled router 404s it)
  • RFC 9728 protected resource metadata MUST be served at /.well-known/oauth-protected-resource
  • Token audience MUST be validated (RFC 8707 §2); never forward the client's token to Xano
  • Required POST headers: MCP-Protocol-Version, Mcp-Method (+ Mcp-Name on tools/call /

resources/read / prompts/get); mismatch -> 400 + -32020 HeaderMismatch

  • Server-initiated requests are gone (MRTR): return InputRequiredResult

(resultType: "input_required"), client retries with inputResponses

  • Deprecated -- do not implement: roots, sampling, logging/setLevel, ping,

resources/subscribe, DCR

  • 405 on GET/DELETE /mcp is CORRECT, not a bug

Key Operations#

bash# Debug (always start here)
npx wrangler tail snappy-mcp

# Deploy
npm run build && npm run deploy

# Rebuild registry after adding tools
npx ts-node scripts/generate-registry.ts

# Test Xano directly (rule out API issues)
curl -s "$XANO/api:e6emygx3/me" -H "Authorization: Bearer $XANO_METADATA_TOKEN" | jq .

Rules#

  • Always test the Xano endpoint via curl BEFORE debugging the MCP wrapper.
  • Always snappy_info("tool-id") before snappy_execute -- undocumented args get dropped silently.
  • Always run generate-registry.ts after registry changes (search index is pre-built, sorted by tool id).
  • Never modify workers-oauth-utils.ts -- it's a vendored copy.
  • Xano login returns { api_key }, not { token } or { access_token }.
  • Connect clients as "type": "http" at /mcp -- never "type": "sse" at /sse.
  • The deployed Worker may still be on the pre-2026 McpAgent/Durable-Object shape. Check what is

actually deployed before assuming; migration order is in SKILL.md.

Cross-Skill Chains#

  • mcp-server-builder -- canonical build methodology (this MCP follows it exactly)
  • snappy-infra -- defines Xano API groups this MCP exposes
  • xanoscript-builder -- authors upstream Xano endpoints
  • snappy-database -- table catalog for snappy_query raw SQL
  • snappy-deploy -- includes this Worker in its deploy sequence

Directory Layout#

snappy-xano-mcp/
  SKILL.md           <- Full reference (meta-tools, auth, gotchas, anti-patterns)
  architecture.md    <- Stateless CF Worker architecture, file layout, packages, tasks extension
  development.md     <- Adding tools, deploying, smoke tests
  debugging.md       <- Transport / OAuth / tool execution error diagnosis
  AGENTS.md          <- This file

API module#

typescriptimport { checkHealth, testEndpoint } from "../snappy-xano-mcp/api.ts";

Or CLI:

bashnpx tsx ~/.claude/skills/snappy-xano-mcp/api.ts health
npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts test me

API functions#

Function Purpose
checkHealth() Check MCP server health: RFC 9728 PRM returns 200, and unauthenticated POST /mcp returns 401 with a WWW-Authenticate challenge
testEndpoint(toolName) Test a specific MCP tool by hitting the Xano endpoint directly

If this loader doesn't cover your case:

bashecho "[$(date -u +%FT%TZ)] snappy-xano-mcp: <what was missing>" >> ~/.claude/logs/agents-md-feedback.log

Show produced work with snappy-faces: call draw for image channels or lang for MCP Apps.

<!-- SKILL-INDEX-START -->

[snappy-xano-mcp Index]|root: ~/.claude/skills/snappy-xano-mcp|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,architecture.md,debugging.md,development.md}

<!-- SKILL-INDEX-END -->

Used by#

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->

Contract verbs#

Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.

Verb Contract arguments Effect First call
health read npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts health
test tool write npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts test <tool>

Show the result#

When an answer carries face_hint, show it with one snappy_present(<answer>) call.

See /snappy-faces for face selection. Human-facing images must crop to the

element, render at 2x on Retina, and fill the destination channel instead of

placing a small card in a full-page screenshot.

<!-- SNAPPY-CONTRACT-VERBS-END -->

---
name: snappy-xano-mcp
role: 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.
loaded-by: PreToolUse hook (auto-injected when "snappy-xano-mcp" is mentioned)
---

## Context

snappy-xano-mcp is a Cloudflare Worker that wraps the Snappy Xano API surface (~50 endpoints across 7 API groups) into 8 standard MCP meta-tools. Clients (Claude Code, ChatGPT, Cursor, Windsurf) connect once via OAuth2 PKCE and access email, calendar, Slack, LinkedIn, FreshBooks, WhatsApp, YouTube, knowledge graph, and the async queue through a single Streamable HTTP endpoint (`POST /mcp`). Built on `@modelcontextprotocol/server` v2 + `agents` + Hono on a **stateless** Worker — no Durable Objects, no sessions, no `initialize` handshake.

Target spec revision: **`2026-07-28`**.

## 8 Meta-Tools

| Tool | Purpose | Hits Xano? |
|------|---------|------------|
| `snappy_search` | Fuzzy search across all tools | No |
| `snappy_info` | Tool docs + expected params | No |
| `snappy_execute` | Call any tool by ID | Yes |
| `snappy_list` | Browse tools by group | No |
| `snappy_query` | Raw queries via Xano | Yes |
| `snappy_dashboard` | Aggregated stats | Yes |
| `snappy_me` | Current user + org info | Yes |
| `snappy_batch` | Sequential multi-tool (up to 10) | Yes |

Standard flow: `snappy_search` -> `snappy_info` -> `snappy_execute`.

`tools/list` (and `snappy_list`) MUST return `ttlMs` + `cacheScope`, sorted deterministically by
tool id. `snappy_batch` is the tasks-extension candidate — anything over ~10s belongs to
`io.modelcontextprotocol/tasks`, not to a synchronous batch.

## Current Config (spec 2026-07-28)

- `compatibility_date: "2026-06-11"`
- **No `migrations` block, no `durable_objects` block** -- MCP needs no Durable Object
- `@modelcontextprotocol/server: "2.0.0"` + `zod: "^4.4.3"` (SDK v2 requires Zod v4)
- `agents: "^0.20.1"`
- `@cloudflare/workers-oauth-provider: "^0.10.3"` with `clientIdMetadataDocumentEnabled: true`
- `resource:` canonical `/mcp` URL in OAuthProvider -- drives RFC 9728 PRM + RFC 8707 audience
- `observability: { enabled: true }` -- without it, `wrangler tail` returns nothing

## Protocol Musts

- `server/discover` MUST be implemented (SDK answers it; a hand-rolled router 404s it)
- RFC 9728 protected resource metadata MUST be served at `/.well-known/oauth-protected-resource`
- Token audience MUST be validated (RFC 8707 §2); never forward the client's token to Xano
- Required POST headers: `MCP-Protocol-Version`, `Mcp-Method` (+ `Mcp-Name` on `tools/call` /
  `resources/read` / `prompts/get`); mismatch -> 400 + `-32020 HeaderMismatch`
- Server-initiated requests are gone (MRTR): return `InputRequiredResult`
  (`resultType: "input_required"`), client retries with `inputResponses`
- Deprecated -- do not implement: roots, sampling, logging/setLevel, `ping`,
  `resources/subscribe`, DCR
- `405` on `GET`/`DELETE` `/mcp` is CORRECT, not a bug

## Key Operations

```bash
# Debug (always start here)
npx wrangler tail snappy-mcp

# Deploy
npm run build && npm run deploy

# Rebuild registry after adding tools
npx ts-node scripts/generate-registry.ts

# Test Xano directly (rule out API issues)
curl -s "$XANO/api:e6emygx3/me" -H "Authorization: Bearer $XANO_METADATA_TOKEN" | jq .
```

## Rules

- Always test the Xano endpoint via curl BEFORE debugging the MCP wrapper.
- Always `snappy_info("tool-id")` before `snappy_execute` -- undocumented args get dropped silently.
- Always run `generate-registry.ts` after registry changes (search index is pre-built, sorted by tool id).
- Never modify `workers-oauth-utils.ts` -- it's a vendored copy.
- Xano login returns `{ api_key }`, not `{ token }` or `{ access_token }`.
- Connect clients as `"type": "http"` at `/mcp` -- never `"type": "sse"` at `/sse`.
- The deployed Worker may still be on the pre-2026 McpAgent/Durable-Object shape. Check what is
  actually deployed before assuming; migration order is in SKILL.md.

## Cross-Skill Chains

- `mcp-server-builder` -- canonical build methodology (this MCP follows it exactly)
- `snappy-infra` -- defines Xano API groups this MCP exposes
- `xanoscript-builder` -- authors upstream Xano endpoints
- `snappy-database` -- table catalog for `snappy_query` raw SQL
- `snappy-deploy` -- includes this Worker in its deploy sequence

## Directory Layout

```
snappy-xano-mcp/
  SKILL.md           <- Full reference (meta-tools, auth, gotchas, anti-patterns)
  architecture.md    <- Stateless CF Worker architecture, file layout, packages, tasks extension
  development.md     <- Adding tools, deploying, smoke tests
  debugging.md       <- Transport / OAuth / tool execution error diagnosis
  AGENTS.md          <- This file
```

## API module

```typescript
import { checkHealth, testEndpoint } from "../snappy-xano-mcp/api.ts";
```

Or CLI:
```bash
npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts health
npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts test me
```

## API functions

| Function | Purpose |
|----------|---------|
| `checkHealth()` | Check MCP server health: RFC 9728 PRM returns 200, and unauthenticated `POST /mcp` returns 401 with a `WWW-Authenticate` challenge |
| `testEndpoint(toolName)` | Test a specific MCP tool by hitting the Xano endpoint directly |

---

If this loader doesn't cover your case:
```bash
echo "[$(date -u +%FT%TZ)] snappy-xano-mcp: <what was missing>" >> ~/.claude/logs/agents-md-feedback.log
```


Show produced work with `snappy-faces`: call `draw` for image channels or `lang` for MCP Apps.

<!-- SKILL-INDEX-START -->
[snappy-xano-mcp Index]|root: ~/.claude/skills/snappy-xano-mcp|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,architecture.md,debugging.md,development.md}
<!-- SKILL-INDEX-END -->

## Used by

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs

Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.

| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
| `health` | — | `read` | `npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts health` |
| `test` | `tool` | `write` | `npx tsx ~/.claude/skills/snappy-xano-mcp/api.ts test <tool>` |

## Show the result

When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?