{"id":"6876b2eb-4776-4552-806e-99ab0167fd35","entityType":"agent","slug":"clawhub-chrischall-resy-fpx","name":"resy-fpx","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chrischall-resy-fpx","canonicalPath":"/agent/clawhub-chrischall-resy-fpx","generatedAt":"2026-10-10T17:36:56.773Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":null},"description":"Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without the MCP, in a script, or on a machine where the MCP isn't installed. Skill: resy-fpx Owner: chrischall Summary: Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:resy-fpx","sourceUrl":"https://clawhub.ai/chrischall/resy-fpx","homepage":"https://clawhub.ai/chrischall/skills/resy-fpx","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chrischall/resy-fpx","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chrischall/skills/resy-fpx","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel "},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":null},"stars":null,"forks":null,"downloads":1394,"packageName":null,"latestVersion":"1.3.3","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T14:11:22.577Z","lastCrawledAt":"2026-10-10T14:11:22.577Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T14:11:22.577Z","lastVerifiedAt":null,"highlights":[{"version":"1.3.3","createdAt":"2026-10-09T23:26:58.360Z","changelog":"- Removed the redundant skill-card.md file. - No user-facing functionality or documentation changes. - Internal cleanup for improved file organization.","fileCount":4,"zipByteSize":7411},{"version":"1.3.2","createdAt":"2026-10-07T13:42:48.150Z","changelog":"- Removed the file skill-card.md for simplification. - No functionality or documentation changes to the skill itself.","fileCount":4,"zipByteSize":7386},{"version":"1.3.1","createdAt":"2026-10-05T02:52:23.184Z","changelog":"- Removed the skill-card.md file. - No functional or user-facing changes. - Documentation and core usage remain unchanged.","fileCount":4,"zipByteSize":7402},{"version":"1.3.0","createdAt":"2026-10-03T01:45:45.532Z","changelog":"resy-fpx 1.3.0 - Removed the sample skill card file (skill-card.md) from the project. - No changes to user-facing functionality or documentation.","fileCount":4,"zipByteSize":7323},{"version":"1.2.2","createdAt":"2026-09-28T14:00:10.454Z","changelog":"- Removed the unused file skill-card.md. - Updated SKILL.md to refer to \"ContextMint Bridge\" instead of \"Transporter\" for fpx pairing approval. - No changes to code or API behavior; documentation only.","fileCount":4,"zipByteSize":7403},{"version":"1.2.1","createdAt":"2026-09-25T16:03:22.619Z","changelog":"- Removed the file skill-card.md. - No functional or documentation changes to the primary SKILL.md.","fileCount":4,"zipByteSize":7361},{"version":"1.2.0","createdAt":"2026-09-24T15:12:20.387Z","changelog":"resy-fpx 1.2.0 - Documentation improvements: SKILL.md updated for clarity and accuracy. - Minor language tweaks for precision (e.g., about write call confirmation). - Removed redundant file: skill-card.md. - No changes to functional behavior.","fileCount":4,"zipByteSize":7506},{"version":"1.1.3","createdAt":"2026-09-23T21:42:27.228Z","changelog":"## resy-fpx 1.1.3 - Removed the skill-card.md file. - No user-facing or documentation changes to usage or functionality.","fileCount":4,"zipByteSize":7419}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:resy-fpx","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T17:36:56.770Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-resy-fpx/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":null},"readme":"Skill: resy-fpx\n\nOwner: chrischall\n\nSummary: Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without the MCP, in a script, or on a machine where the MCP isn't installed.\n\nTags: latest:1.3.3\n\nVersion history:\n\nv1.3.3 | 2026-10-09T23:26:58.360Z | auto\n\n- Removed the redundant skill-card.md file.\n- No user-facing functionality or documentation changes.\n- Internal cleanup for improved file organization.\n\nv1.3.2 | 2026-10-07T13:42:48.150Z | auto\n\n- Removed the file skill-card.md for simplification.\n- No functionality or documentation changes to the skill itself.\n\nv1.3.1 | 2026-10-05T02:52:23.184Z | auto\n\n- Removed the skill-card.md file.  \n- No functional or user-facing changes.  \n- Documentation and core usage remain unchanged.\n\nv1.3.0 | 2026-10-03T01:45:45.532Z | auto\n\nresy-fpx 1.3.0\n\n- Removed the sample skill card file (skill-card.md) from the project.\n- No changes to user-facing functionality or documentation.\n\nv1.2.2 | 2026-09-28T14:00:10.454Z | auto\n\n- Removed the unused file skill-card.md.\n- Updated SKILL.md to refer to \"ContextMint Bridge\" instead of \"Transporter\" for fpx pairing approval.\n- No changes to code or API behavior; documentation only.\n\nv1.2.1 | 2026-09-25T16:03:22.619Z | auto\n\n- Removed the file skill-card.md.\n- No functional or documentation changes to the primary SKILL.md.\n\nv1.2.0 | 2026-09-24T15:12:20.387Z | auto\n\nresy-fpx 1.2.0\n\n- Documentation improvements: SKILL.md updated for clarity and accuracy.\n- Minor language tweaks for precision (e.g., about write call confirmation).\n- Removed redundant file: skill-card.md.\n- No changes to functional behavior.\n\nv1.1.3 | 2026-09-23T21:42:27.228Z | auto\n\n## resy-fpx 1.1.3\n\n- Removed the skill-card.md file.\n- No user-facing or documentation changes to usage or functionality.\n\nv1.1.2 | 2026-09-23T15:43:32.932Z | auto\n\n- Removed the skill-card.md file as part of cleanup.\n- No user-facing functional changes.\n\nv1.1.1 | 2026-09-21T04:14:02.266Z | auto\n\n- Removed the sample file skill-card.md.\n- No user-facing feature or behavior changes.\n\nv1.1.0 | 2026-09-20T02:50:31.631Z | auto\n\n- Removed the file: skill-card.md\n- No changes to usage or documentation in SKILL.md.\n- No functional changes; update is solely a cleanup of unused/auxiliary documentation.\n\nv1.0.0 | 2026-09-19T11:19:42.478Z | auto\n\n- Removed the file skill-card.md.\n- No changes to functionality or user-facing documentation aside from the file removal.\n\nv0.14.4 | 2026-09-15T19:25:51.964Z | auto\n\n- Removed the skill-card.md file.\n- No changes to functionality or documentation aside from the file removal.\n\nv0.14.3 | 2026-09-14T14:10:35.696Z | auto\n\n- Removed the file skill-card.md from the project.\n- No user-facing behavior or API changes.\n- Documentation and usage remain unchanged.\n\nv0.14.2 | 2026-09-10T17:14:30.996Z | auto\n\n- Removed the skill-card.md file.\n- No other changes made; all functionality and documentation remain the same.\n\nv0.14.1 | 2026-09-10T16:45:49.989Z | auto\n\n- Removed the file: skill-card.md\n- No other changes to code or documentation.\n\nv0.14.0 | 2026-09-10T13:47:39.403Z | auto\n\n- Removed the skill-card.md file.\n- No feature or documentation changes to SKILL.md.\n- No breaking changes; update is limited to file cleanup.\n\nv0.13.3 | 2026-09-09T19:43:31.711Z | auto\n\n- Removed the skill-card.md file.\n- No user-facing functionality changes; documentation and core usage remain the same.\n\nv0.13.2 | 2026-09-08T02:58:02.496Z | auto\n\n- Removed the sample skill card file (skill-card.md) from the project.\n- No changes to functionality or documentation in SKILL.md.\n\nv0.13.1 | 2026-09-05T00:51:06.828Z | auto\n\n- Removed the skill-card.md file.\n- No changes to functionality or user-facing documentation.\n- Housekeeping update to remove redundant or unneeded project metadata.\n\nv0.13.0 | 2026-09-04T22:21:33.170Z | auto\n\n- Removed the file: skill-card.md.\n- No changes to user-visible functionality or documentation.\n\nv0.12.0 | 2026-09-02T19:14:20.227Z | auto\n\n- Version bump to 0.12.0 with no file or documentation changes.\n- No updates or modifications made to the SKILL.md or code in this release.\n\nv0.11.0 | 2026-09-02T18:05:36.794Z | auto\n\nVersion 0.11.0\n\n- No file changes detected in this release.\n- Functionality and documentation remain unchanged from the previous version.\n\nv0.10.0 | 2026-09-02T17:13:06.907Z | auto\n\n- Removed the sample file skill-card.md.\n- No functional or documentation changes to the code or skill instructions.\n\nv0.9.1 | 2026-09-02T02:58:27.400Z | auto\n\n- Removed the sample file skill-card.md.  \n- No functional or documentation changes; maintenance cleanup only.\n\nv0.9.0 | 2026-08-31T00:22:24.381Z | auto\n\n- Removed the file skill-card.md.\n- No user-facing changes to functionality or documentation.\n\nv0.8.0 | 2026-08-29T13:54:11.438Z | auto\n\n- Removed the file: skill-card.md.\n- No other user-facing changes. This update is file cleanup only.\n\nv0.7.0 | 2026-08-28T11:35:03.458Z | auto\n\n- Initial public release of resy-fpx.\n- Query and manage Resy (resy.com) reservations entirely via shell with curl — no resy-mcp server needed.\n- Supports full end-to-end flows: search venues, check slots, book/cancel reservations, manage favorites and Priority Notify.\n- fpx CLI only required for one-time token bootstrap if Resy credentials are unavailable; otherwise, all ongoing actions are via API calls with curl.\n- Suitable for script automation and environments without MCP installed.\n\nArchive index:\n\nArchive v1.3.3: 4 files, 7411 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1847b), SKILL.md (4985b), _meta.json (127b)\n\nFile v1.3.3:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.3.3:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.3.3\",\n  \"publishedAt\": 1791588418360\n}\n\nFile v1.3.3:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.3.3:skill-card.md\n\n## Description:\n\nHelps agents search Resy restaurants, check availability, and manage reservations, favorites, and Priority Notify using shell commands.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nResy account holders and developers can use this skill to find restaurants and available tables, book or cancel reservations, and manage favorites and Priority Notify without an MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Booking, cancellation, favorite, and notify requests change a live Resy account without an enforced confirmation step.\n\nMitigation: Before each write, show and confirm the venue, date, time, party size, reservation or notify identifier, and payment method as applicable; check the account afterward.\n\nRisk: Resy credentials and account tokens may be exposed through shared scripts or logs.\n\nMitigation: Treat RESY_PASSWORD and RESY_TOKEN as secrets; avoid including their values in shared logs or scripts.\n\n## Reference(s):\n\n- [Resy API request examples](references/resy-api.md)\n- [resy-fpx on ClawHub](https://clawhub.ai/chrischall/skills/resy-fpx)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Includes read-only lookups and commands that change a live Resy account.]\n\n## Skill Version(s):\n\n1.3.3 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.2: 4 files, 7386 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1856b), SKILL.md (4985b), _meta.json (127b)\n\nFile v1.3.2:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.3.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.3.2\",\n  \"publishedAt\": 1791380568150\n}\n\nFile v1.3.2:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.3.2:skill-card.md\n\n## Description:\n\nGuides agents through searching Resy availability and managing reservations, favorites, and Priority Notify from a shell without an MCP server.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and Resy account holders can use this skill to find restaurant availability and manage their own reservations, favorites, and notifications through shell commands without running an MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Resy passwords and account tokens may be exposed through logs or shared files.\n\nMitigation: Treat RESY_PASSWORD and RESY_TOKEN as sensitive; use a trusted shell and avoid recording tokens in logs or shared files.\n\nRisk: Booking or cancellation commands can change real reservations, including use of a saved payment method.\n\nMitigation: Manually confirm the venue, date, party size, payment method, and reservation token before booking or canceling; read back reservations afterward.\n\n## Reference(s):\n\n- [Resy API request examples](references/resy-api.md)\n- [ClawHub release page](https://clawhub.ai/chrischall/skills/resy-fpx)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands may access account data or change live reservations and notifications.]\n\n## Skill Version(s):\n\n1.3.2 (source: ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.1: 4 files, 7402 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1899b), SKILL.md (4985b), _meta.json (127b)\n\nFile v1.3.1:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.3.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.3.1\",\n  \"publishedAt\": 1791168743184\n}\n\nFile v1.3.1:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.3.1:skill-card.md\n\n## Description:\n\nGuides agents in searching Resy venues, checking availability, and managing reservations, favorites, and Priority Notify from a shell.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nResy users and developers can search restaurants, inspect reservation availability, and manage their own bookings, favorites, and notifications through shell commands without an MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Booking, cancellation, favorite, and notification commands can change a live Resy account without a built-in confirmation step.\n\nMitigation: Require manual confirmation of the account, venue, date, and intended action before running any account-changing command.\n\nRisk: Credentials, authentication tokens, and access to a signed-in browser session can expose private reservation data or enable unauthorized actions.\n\nMitigation: Treat credentials, tokens, and browser-session access as secrets; avoid sharing or logging them and restrict access to the account owner.\n\n## Reference(s):\n\n- [Resy API request examples](references/resy-api.md)\n- [resy-fpx on ClawHub](https://clawhub.ai/chrischall/skills/resy-fpx)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands can retrieve reservation details or change a live Resy account.]\n\n## Skill Version(s):\n\n1.3.1 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.0: 4 files, 7323 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1645b), SKILL.md (4985b), _meta.json (127b)\n\nFile v1.3.0:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.3.0\",\n  \"publishedAt\": 1790991945532\n}\n\nFile v1.3.0:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.3.0:skill-card.md\n\n## Description:\n\nGuides agents through searching Resy availability and managing reservations, favorites, and Priority Notify from a shell using authenticated requests.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nResy account holders and developers use this skill to find restaurant availability and manage bookings, favorites, and Priority Notify without running an MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Resy credentials and tokens could be exposed in shared logs, shell history, commits, or screenshots.\n\nMitigation: Keep RESY_EMAIL, RESY_PASSWORD, and RESY_TOKEN out of shared outputs and stored history.\n\nRisk: Booking, cancellation, favorite, and notification commands change a real Resy account.\n\nMitigation: Review each account-changing command before execution and verify the resulting account state.\n\n## Reference(s):\n\n- [Resy API request examples](references/resy-api.md)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Text and Markdown with shell examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Authenticated actions can change live account state.]\n\n## Skill Version(s):\n\n1.3.0 (source: server-resolved release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.2: 4 files, 7403 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1860b), SKILL.md (4985b), _meta.json (127b)\n\nFile v1.2.2:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.2.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.2.2\",\n  \"publishedAt\": 1790604010454\n}\n\nFile v1.2.2:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.2.2:skill-card.md\n\n## Description:\n\nGuides agents to search Resy restaurants, check availability, manage reservations and favorites, and set Priority Notify alerts from a shell.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nResy account holders and developers use this skill to search restaurants, inspect available tables, and manage reservations, favorites, and Priority Notify alerts through an agent-assisted shell workflow.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: An agent may expose Resy credentials or account tokens while following authentication instructions.\n\nMitigation: Keep credentials and tokens out of logs and shared shell history; review token access before installation.\n\nRisk: Booking, cancellation, favorites, and notify commands change the user's live Resy account without a built-in dry run.\n\nMitigation: Read back the target account state and obtain explicit confirmation before booking, cancellation, or removal; verify the result afterward.\n\n## Reference(s):\n\n- [Resy API request guide](artifact/references/resy-api.md)\n- [resy-fpx ClawHub listing](https://clawhub.ai/chrischall/skills/resy-fpx)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Includes instructions for actions that can change a live Resy account.]\n\n## Skill Version(s):\n\n1.2.2 (source: ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.1: 4 files, 7361 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1749b), SKILL.md (4978b), _meta.json (127b)\n\nFile v1.2.1:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in Transporter\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.2.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.2.1\",\n  \"publishedAt\": 1790352202619\n}\n\nFile v1.2.1:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.2.1:skill-card.md\n\n## Description:\n\nHelps agents search Resy restaurants, check availability, and manage reservations, favorites, and Priority Notify from a shell using direct API requests.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nResy users and developers can search restaurants, check available tables, and manage their own reservations and alerts through shell commands without running an MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Account credentials or reservation tokens may be exposed through logs or shared terminals.\n\nMitigation: Keep credentials and RESY_TOKEN out of logs and avoid shared terminals.\n\nRisk: Booking, cancellation, favorites, and notification commands change live account state.\n\nMitigation: Require explicit confirmation before each account-changing action and verify the result.\n\n## Reference(s):\n\n- [Resy API request examples](references/resy-api.md)\n- [resy-fpx ClawHub release](https://clawhub.ai/chrischall/skills/resy-fpx)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Configuration instructions, Guidance]\n\n**Output Format:** [Markdown with shell code blocks]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands can query live availability or change the user's Resy account.]\n\n## Skill Version(s):\n\n1.2.1 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.0: 4 files, 7506 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (2010b), SKILL.md (4978b), _meta.json (127b)\n\nFile v1.2.0:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in Transporter\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's confirmation step — prompt or preview token — is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.2.0\",\n  \"publishedAt\": 1790262740387\n}\n\nFile v1.2.0:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.2.0:skill-card.md\n\n## Description:\n\nQuery and act on Resy restaurant reservations from a shell using curl against api.resy.com, with optional fpx token bootstrap when email/password credentials are unavailable.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to search Resy venues, inspect availability, retrieve profile and payment method details, and perform reservation, favorite, and Priority Notify actions from shell workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can expose or reuse sensitive Resy credentials, account tokens, signed-in browser sessions, and payment method identifiers.\n\nMitigation: Only use it in trusted workspaces, keep RESY_EMAIL, RESY_PASSWORD, RESY_TOKEN, and payment method identifiers out of logs and shared transcripts, and rotate credentials or tokens if exposed.\n\nRisk: Ready-to-run write commands can book, cancel, favorite, or create/remove Priority Notify entries on a real Resy account.\n\nMitigation: Require explicit user confirmation before every write action and verify state with list/read calls before and after execution.\n\n## Reference(s):\n\n- [Resy API ready-to-run requests](references/resy-api.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with curl, jq, npm, and fpx command snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Includes ready-to-run API requests and setup guidance for authenticated Resy account actions.]\n\n## Skill Version(s):\n\n1.2.0 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.1.3: 4 files, 7419 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (1961b), SKILL.md (4952b), _meta.json (127b)\n\nFile v1.1.3:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in Transporter\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's `confirm`-gated preview is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.1.3:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.1.3\",\n  \"publishedAt\": 1790199747228\n}\n\nFile v1.1.3:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.1.3:skill-card.md\n\n## Description:\n\nQuery and act on Resy reservations from a shell with curl, including venue search, slot availability, booking or cancellation, favorites, and Priority Notify management.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and operators use this skill to produce ready-to-run shell workflows for Resy account actions without running the resy-mcp server. It supports token setup, reservation lookup, booking, cancellation, favorites, and notify management for a user's own Resy account.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill enables live Resy account automation, including booking, cancellation, favorites, and Priority Notify changes.\n\nMitigation: Require explicit user confirmation before executing write actions, and verify state with list or profile calls before and after changes.\n\nRisk: The workflows handle Resy credentials and auth tokens in shell commands.\n\nMitigation: Avoid saving credentials or tokens in shell history, use environment variables carefully, and consider an isolated browser profile for fpx pairing.\n\n## Reference(s):\n\n- [Resy API ready-to-run requests](artifact/references/resy-api.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with inline shell commands and JSON examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands may make live changes to the user's Resy account when executed.]\n\n## Skill Version(s):\n\n1.1.3 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.1.2: 4 files, 7549 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (2208b), SKILL.md (4952b), _meta.json (127b)\n\nFile v1.1.2:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in Transporter\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's `confirm`-gated preview is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.1.2\",\n  \"publishedAt\": 1790178212932\n}\n\nFile v1.1.2:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the tool's default when lat/lng are omitted.\n\n## Find slots at a venue — `resy_find_slots`\n\n```sh\nresy GET \"/4/find?lat=40.7128&long=-73.9876&day=2026-08-01&party_size=2&venue_id=123\" \\\n  | jq '.results.venues[0].slots[] | {config_token: .config.token, type: .config.type, start: .date.start}'\n```\n\n`src/tools/venues.ts` `findSlotsAtVenue`. `config.token` is the slot\ntoken — exchange it for a `book_token` (below) before booking; it expires\nquickly.\n\n## Venue detail — `resy_get_venue`\n\n```sh\nresy GET \"/3/venue?id=123\" | jq '.venue | {\n  venue_id: .id.resy, name, cuisine, price_range, rating, url_slug,\n  city: .location.locality, state: .location.region\n}'\n```\n\n`src/tools/venues.ts` `resy_get_venue`.\n\n## Reservations — `resy_list_reservations`, `resy_cancel`, `resy_book`\n\n```sh\n# list (client-side filter by day; Resy's own `scope` param is a no-op)\nresy GET /3/user/reservations | jq '.reservations[] | {\n  resy_token, reservation_id, venue_id: .venue.id, day, time_slot,\n  num_seats, cancellable: .cancellation.allowed\n}'\n\n# get a book_token for a chosen slot (config_token from find-slots above)\nresy GET \"/3/details?config_id=<CONFIG_TOKEN>&day=2026-08-01&party_size=2\" \\\n  | jq '{book_token: .book_token.value, venue: .venue.name, type: .config.type}'\n\n# book (mutates — real reservation)\nresy POST /3/book \\\n  --data-urlencode \"book_token=<BOOK_TOKEN>\" \\\n  --data-urlencode \"struct_payment_method=$(jq -nc --argjson id 456 '{id:$id}')\" \\\n  --data-urlencode \"source_id=resy.com-venue-details\" \\\n  | jq '{resy_token, reservation_id, time_slot, num_seats}'\n\n# cancel (mutates — real cancellation)\nresy POST /3/cancel --data-urlencode \"resy_token=<RESY_TOKEN_ID>\" | jq .\n```\n\n`src/tools/reservations.ts`. The `resy_token` looks like `rr://...` and\nis what `resy_list_reservations`/`resy_book` return; it's what `/3/cancel`\ntakes. `/3/details`' `config_id` param is confusingly named — it's the\n`config_token` from find-slots, not a venue config id.\n\n## Favorites — `resy_list_favorites`, `resy_add_favorite`, `resy_remove_favorite`\n\n```sh\nresy GET /3/user/favorites | jq '.results.venues[] | .venue | {\n  venue_id: .id.resy, name, cuisine: .type, url_slug, price_range,\n  city: .location.locality, neighborhood: .location.neighborhood\n}'\n\n# add (favorite=1) / remove (favorite=0) — same endpoint, no DELETE verb\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=1\"\nresy POST /3/user/favorites --data-urlencode \"venue_id=123\" --data-urlencode \"favorite=0\"\n```\n\n`src/tools/favorites.ts`. Resy has no DELETE for favorites — toggling\n`favorite=0` on the same POST removes it.\n\n## Priority Notify — `resy_list_notify`, `resy_add_notify`, `resy_remove_notify`\n\n```sh\n# list — MUST be /3/notify (not /3/user/notify, which returns HTML)\nresy GET /3/notify | jq '.notify[].specs | select(.notify_request_id) | {\n  notify_id: .notify_request_id, venue_id, date: .day, party_size,\n  time_start: .time_preferred_start, time_end: .time_preferred_end, service_type_id\n}'\n\n# add — MUST be /2/notify (POST /3/notify returns 502); field is num_seats, not party_size\nresy POST /2/notify \\\n  --data-urlencode \"venue_id=123\" \\\n  --data-urlencode \"day=2026-08-01\" \\\n  --data-urlencode \"num_seats=2\" \\\n  --data-urlencode \"time_preferred_start=18:00:00\" \\\n  --data-urlencode \"time_preferred_end=21:00:00\" \\\n  --data-urlencode \"service_type_id=2\"\n\n# remove — DELETE /2/notify needs the FULL spec as query params, not just the id.\n# Look up the spec from the list call above first, then:\ncurl -s -X DELETE \"https://api.resy.com/2/notify?notify_request_id=<ID>&venue_id=123&day=2026-08-01&num_seats=2&service_type_id=2\" \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' -H 'Referer: https://resy.com/'\n```\n\n`src/tools/notify.ts`. Notify's date window is ~30 days out; Resy rejects\ndates outside it. `time_preferred_start`/`end` are `HH:MM:SS` on the wire\n(pad `HH:MM` with `:00`); `resy_list_notify`'s output trims the seconds\nback off.\n\n## Known quirks (from `CLAUDE.md` \"Resy API quirks (from live smoke)\")\n\n- `/3/notify` is list-only; POST there 502s — adds go to `/2/notify`.\n- `/3/user/notify` returns HTML, not JSON — always use `/3/notify` for list.\n- `/2/notify`'s party-size field is `num_seats`; the `/3` reservation\n  endpoints use `party_size`.\n- Favorites toggle via `favorite=1|0` on the same `POST /3/user/favorites`\n  — there's no DELETE.\n- `/3/user/reservations`'s `scope` query param is currently a no-op; the\n  MCP's \"upcoming\"/\"past\" filtering happens client-side on `day`.\n- Slot times in `/4/find` come back with no timezone offset\n  (restaurant-local) — don't run them through `new Date()` / a TZ-aware\n  parser, read `HH:MM` off the string directly.\n\nFile v1.1.2:skill-card.md\n\n## Description:\n\nQuery and act on Resy restaurant reservations from a shell using curl against api.resy.com, with optional fpx token bootstrap, for venue search, slot availability, booking, cancellation, favorites, and Priority Notify.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to prepare shell commands for authenticated Resy workflows, including searching venues, checking slots, booking or canceling reservations, and managing favorites or Priority Notify for a user's own account.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Commands can book, cancel, favorite, or create Priority Notify entries on a real Resy account.\n\nMitigation: Review each generated write command before running it, and read reservations or subscriptions before and after execution.\n\nRisk: Resy credentials, tokens, profile data, and payment-method IDs may appear in shell commands or command output.\n\nMitigation: Keep credentials and tokens in environment variables, avoid sharing logs, and redact payment or profile data before pasting output into chats.\n\nRisk: Booking requires resolving a venue to a slot and then to a short-lived book token.\n\nMitigation: Resolve the book token immediately before booking, then verify venue, date, party size, and time before execution.\n\n## Reference(s):\n\n- [Resy API reference](references/resy-api.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with inline bash code blocks and JSON jq examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands require user-provided Resy authentication context; write commands can change real account state.]\n\n## Skill Version(s):\n\n1.1.2 (source: ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.1.1: 4 files, 7481 bytes\n\nFiles: references/resy-api.md (7871b), skill-card.md (2008b), SKILL.md (4952b), _meta.json (127b)\n\nFile v1.1.1:SKILL.md\n\n---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in Transporter\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'\n```\n\nPOST/DELETE bodies are `application/x-www-form-urlencoded`\n(`--data-urlencode`), except venue search which sends a single\n`struct_data` field containing JSON. All 14 request/response shapes,\ncopy-pasteable, are in `references/resy-api.md`.\n\n## The one rule: resolve venue → slot → book_token before booking\n\nBooking is a 3-hop chain, same as `resy_book`'s internal flow:\n\n1. `POST /3/venuesearch/search` or `GET /4/find` → `config_token` for the\n   slot you want.\n2. `GET /3/details?config_id=<config_token>&day=&party_size=` →\n   `book_token.value` (expires fast — fetch it right before booking).\n3. `POST /3/book` with `book_token` + `struct_payment_method` (get a\n   payment id from `GET /2/user` if you don't already have one).\n\n## Token lifetime\n\nResy tokens are opaque with no published TTL and no separate refresh\ntoken. If a call 401s (or 419s, or 500s with an auth-shaped message),\njust re-run Step 1 to mint a fresh one — there's no incremental refresh.\n\n## Exit codes (fpx, Path B only)\n\n- `0` — success.\n- `2` — bridge unavailable: extension not connected or pairing pending →\n  `fpx pair -p resy`, confirm a resy.com tab is open.\n- `3` — bot wall: shouldn't happen on the bootstrap call, but if it does,\n  refresh the resy.com tab and retry.\n- `4` — upstream non-2xx (e.g. not actually signed in — sign into\n  resy.com in that tab first).\n\n## Notes\n\n- This is your own Resy account — write calls (book, cancel, favorite,\n  notify) mutate real reservations/subscriptions. There is no dry-run at\n  the curl layer (the MCP's `confirm`-gated preview is an MCP-side\n  convenience); read back with a list call before/after a write if you\n  want to verify it landed.\n- `fpx health -p resy` shows bridge connection state if Path B's bootstrap\n  call fails.\n- This project is developed and maintained by AI (Claude).\n\nFile v1.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.1.1\",\n  \"publishedAt\": 1789964042266\n}\n\nFile v1.1.1:references/resy-api.md\n\n# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_","readmeExcerpt":"Skill: resy-fpx Owner: chrischall Summary: Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want","codeSnippets":[],"executableExamples":[{"language":"sh","snippet":"curl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\"},{"language":"sh","snippet":"curl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'"},{"language":"sh","snippet":"npm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge"},{"language":"sh","snippet":"fpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'"},{"language":"sh","snippet":"curl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'"},{"language":"sh","snippet":"RESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n  -H 'Accept: application/json, text/plain, */*'"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: resy-fpx\ndescription: >-\n  Query and act on Resy (resy.com restaurant reservations) from a shell\n  without running the resy-mcp server — search venues, check slot\n  availability, book/cancel reservations, and manage favorites/Priority\n  Notify with curl against api.resy.com, using the fpx CLI\n  (@fetchproxy/cli) only for the one-time token bootstrap when you have no\n  RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without\n  the MCP, in a script, or on a machine where the MCP isn't installed.\n---\n\n# Resy via curl (+ one-time fpx bootstrap)\n\nResy has no public API — resy-mcp calls the same `api.resy.com` endpoints\nthe resy.com web app calls, all of which are reachable with **plain\ncurl**; nothing here needs a bot-wall bypass. The browser bridge (`fpx`)\nis only needed to mint an auth token when you have no email/password on\nhand — after that, every actual call (search, slots, book, cancel,\nfavorites, notify, profile) is a direct curl with the token in a header.\nThis mirrors resy-mcp's own \"Pattern B\": bridge the one auth call, then\ngo direct for the hot path (see `src/client.ts` / `src/auth-fetchproxy.ts`\nin the resy-mcp repo).\n\n## Step 1 — get a token (pick ONE path)\n\n**Path A — you have Resy credentials (preferred, no browser needed):**\n\n```sh\ncurl -s 'https://api.resy.com/3/auth/password' \\\n  -H 'Authorization: ResyAPI api_key=\"VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5\"' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode \"email=$RESY_EMAIL\" \\\n  --data-urlencode \"password=$RESY_PASSWORD\" \\\n| jq -r '.token // .id.token // .auth_token'\n```\n\nThe api key above is Resy's public web-app key (baked into resy.com's own\nJS, not a secret — see `src/client.ts`). Save the returned token as\n`$RESY_TOKEN`.\n\n**Path B — no credentials, only a signed-in resy.com browser tab:**\n\nOne-time setup:\n\n```sh\nnpm install -g @fetchproxy/cli            # provides `fpx`\nfpx profile add resy --domain resy.com\nfpx pair -p resy                          # prints a pair code → approve in ContextMint Bridge\n```\n\nThen bootstrap the token through the tab (this replicates the one call\nresy.com's own JS makes to refresh its in-memory token — the HttpOnly\nsession cookies authenticate it):\n\n```sh\nfpx post-json 'https://api.resy.com/3/auth/refresh' '{}' -p resy \\\n  | jq -r '.token'\n```\n\nSave it as `$RESY_TOKEN`. `fpx` is not used again after this — every\ncall below is curl.\n\n## Step 2 — call the API directly with the token\n\nEvery authenticated request needs this header set (see `SPOOF_HEADERS` +\n`buildHeaders` in `src/client.ts`):\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # override if Resy rotates it\ncurl -s '<url>' \\\n  -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n  -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n  -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n  -H 'Origin: https://resy.com' \\\n  -H 'Referer: https://resy.com/' \\\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"resy-fpx\",\n  \"version\": \"1.3.3\",\n  \"publishedAt\": 1791588418360\n}"},{"path":"references/resy-api.md","content":"# Resy API — ready-to-run requests\n\nBase URL: `https://api.resy.com`. All requests below assume you've already\nexported:\n\n```sh\nRESY_API_KEY='VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5'   # public web-app key, see SKILL.md\nRESY_TOKEN='...'                                   # from Step 1 in SKILL.md\n```\n\nand define this helper so every call below is one line:\n\n```sh\nresy() {\n  local method=$1 path=$2; shift 2\n  curl -s -X \"$method\" \"https://api.resy.com${path}\" \\\n    -H \"Authorization: ResyAPI api_key=\\\"$RESY_API_KEY\\\"\" \\\n    -H \"x-resy-auth-token: $RESY_TOKEN\" \\\n    -H \"x-resy-universal-auth: $RESY_TOKEN\" \\\n    -H 'Origin: https://resy.com' \\\n    -H 'Referer: https://resy.com/' \\\n    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \\\n    -H 'Accept: application/json, text/plain, */*' \\\n    \"$@\"\n}\n```\n\nAny remaining args are forwarded straight to curl — use one `--data-urlencode \"key=value\"`\nper form field for POST bodies (curl sets `Content-Type: application/x-www-form-urlencoded`\nautomatically once any `--data*` flag is present). `--data-urlencode` percent-encodes each\nvalue the same way `src/client.ts`'s `URLSearchParams` does on the wire, so tokens like\n`book_token`/`resy_token` (which can contain `rr://`, `:`, `&`, `=`) survive intact instead of\ncorrupting the body when interpolated raw into a single `--data` string.\n\nEndpoints match the tool set in `src/tools/*.ts` of the resy-mcp repo\n1:1 (14 tools total). Source line references are to that repo.\n\n## Auth (Step 1 — see SKILL.md, not covered by the `resy()` helper)\n\n- `POST /3/auth/password` — form body `email`, `password` → `{ token }`\n  (or `{ id: { token } }` / `{ auth_token }` on some responses).\n  `src/client.ts` `loginWithPassword()`.\n- `POST /3/auth/refresh` (via `fpx post-json`, not curl — HttpOnly cookies\n  authenticate it) → `{ token }`. `src/auth-fetchproxy.ts`.\n\n## User / profile — `resy_get_profile`, `resy_list_payment_methods`\n\n```sh\nresy GET /2/user | jq '{\n  first_name, last_name, email: .em_address, phone: .mobile_number,\n  num_bookings, member_since: .date_created, is_resy_select: .resy_select\n}'\n\nresy GET /2/user | jq '.payment_methods[] | {\n  id, brand, last_four: (.last_four // .last4 // .display_number),\n  exp_month, exp_year, is_default\n}'\n```\n\n`payment_methods[].id` is the `payment_method_id` accepted by the book\ncall below.\n\n## Venue search — `resy_search_venues`\n\n```sh\nSTRUCT=$(jq -nc --arg q \"ramen\" --arg day \"2026-08-01\" \\\n  '{availability:true, page:1, per_page:20, slot_filter:{day:$day, party_size:2},\n    types:[\"venue\"], order_by:\"availability\",\n    geo:{latitude:40.7128, longitude:-73.9876, radius:16100}, query:$q}')\nresy POST /3/venuesearch/search --data-urlencode \"struct_data=$STRUCT\" \\\n  | jq '.search.hits[] | {venue_id: .id.resy, name, cuisine, price_range, rating, url_slug}'\n```\n\n`src/tools/venues.ts` `registerVenueTools` / `resy_search_venues`. NYC geo\n(`40.7128,-73.9876`) is the"},{"path":"skill-card.md","content":"## Description:\n\nHelps agents search Resy restaurants, check availability, and manage reservations, favorites, and Priority Notify using shell commands.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nResy account holders and developers can use this skill to find restaurants and available tables, book or cancel reservations, and manage favorites and Priority Notify without an MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Booking, cancellation, favorite, and notify requests change a live Resy account without an enforced confirmation step.\n\nMitigation: Before each write, show and confirm the venue, date, time, party size, reservation or notify identifier, and payment method as applicable; check the account afterward.\n\nRisk: Resy credentials and account tokens may be exposed through shared scripts or logs.\n\nMitigation: Treat RESY_PASSWORD and RESY_TOKEN as secrets; avoid including their values in shared logs or scripts.\n\n## Reference(s):\n\n- [Resy API request examples](references/resy-api.md)\n- [resy-fpx on ClawHub](https://clawhub.ai/chrischall/skills/resy-fpx)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Includes read-only lookups and commands that change a live Resy account.]\n\n## Skill Version(s):\n\n1.3.3 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without the MCP, in a script, or on a machine where the MCP isn't installed. Skill: resy-fpx Owner: chrischall Summary: Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1386,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T14:11:22.577Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:36:56.773Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}