From 2f3de1af3cab060b0382bb3ef109bccda9c6f233 Mon Sep 17 00:00:00 2001 From: Gabriel Bauman <967743+gabrielbauman@users.noreply.github.com> Date: Sat, 6 Jun 2026 13:31:41 -0700 Subject: [PATCH] Add AT Protocol (lexicon/XRPC) support and one-command install Add an `atproto` adapter kind: search/execute against any AT Protocol service (e.g. Bluesky) via a thin, typed XRPC client. Types are reused from @atproto/api with a type-only import, so none of the SDK runs in the execute sandbox; writeTypes emits only an NSID -> {params,input,output} map, letting client.query/procedure infer from the NSID string literal. The operation index is built from the package's runtime `schemas`, and NSID -> namespace names come from its `ids` export (never derived) so a type reference can't drift and break the whole-program check. Auth runs in the parent like OAuth: app-password sessions (createSession/refreshSession), injecting only a short-lived access JWT into the sandbox. Registering without an identifier is anonymous (public reads, no token); with one, the parent mints/refreshes a session and guides to `login` when needed. install.sh now runs `anyapi-mcp install` after building (best-effort; opt out with ANYAPI_MCP_NO_INSTALL), and `install` also registers with OpenCode by merging an `mcp` entry into its config (its `mcp add` is interactive-only). Docs and the landing page updated throughout. --- CLAUDE.md | 95 +++++++---- README.md | 105 +++++++----- deno.lock | 94 ++++++++++- site/index.html | 37 +++-- site/install.sh | 34 +++- src/adapters.ts | 2 + src/atproto-auth.ts | 285 ++++++++++++++++++++++++++++++++ src/atproto.ts | 352 ++++++++++++++++++++++++++++++++++++++++ src/atproto_test.ts | 217 +++++++++++++++++++++++++ src/commands/add.ts | 76 ++++++++- src/commands/install.ts | 95 ++++++++++- src/commands/list.ts | 5 + src/commands/login.ts | 81 ++++++++- src/commands/logout.ts | 30 +++- src/commands/serve.ts | 85 ++++++++-- src/register.ts | 46 +++++- src/registry.ts | 24 ++- 17 files changed, 1524 insertions(+), 139 deletions(-) create mode 100644 src/atproto-auth.ts create mode 100644 src/atproto.ts create mode 100644 src/atproto_test.ts diff --git a/CLAUDE.md b/CLAUDE.md index 4e8a667..651c1ab 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,8 +1,9 @@ # CLAUDE.md anyapi-mcp is a Deno 2.x CLI + stdio MCP server (TypeScript, strict) that turns -an HTTP API (OpenAPI, GraphQL, or SOAP/WSDL) into a typed client the model -drives by writing code. See [README.md](README.md) for the user-facing pitch. +an HTTP API (OpenAPI, GraphQL, SOAP/WSDL, or AT Protocol/lexicon/XRPC) into a +typed client the model drives by writing code. See [README.md](README.md) for +the user-facing pitch. ## Commands @@ -29,23 +30,24 @@ protocol plugs in through one in-tree adapter object. - `src/commands/{add,install,list,regenerate,login,logout,remove,serve}.ts`: one file per subcommand. `serve.ts` is the MCP server exposing `search`, `execute`, `authenticate`, `configure_oauth`, `add_api`, `list_apis`, - `remove_api`; `install.ts` registers anyapi-mcp with Claude Code / Desktop; - `login`/`logout` manage OAuth sessions; `regenerate.ts` rebuilds generated - code from saved sources (credentials untouched) — and `serve` runs the same - pass on stale entries at startup (see `register.ts`). + `remove_api`; `install.ts` registers anyapi-mcp with Claude Code, Claude + Desktop, and OpenCode; `login`/`logout` manage OAuth sessions and atproto + app-password sessions; `regenerate.ts` rebuilds generated code from saved + sources (credentials untouched) — and `serve` runs the same pass on stale + entries at startup (see `register.ts`). - `src/adapter.ts`: the `ProtocolAdapter` seam. `prepare()` turns a source into base URL + hosts + operation index + generated client types (+ optional discovered OAuth config); `buildHarness()` builds the `execute` preamble that puts a typed `client` in scope. - `src/adapters.ts`: discriminated-union registry keyed by `kind`. **Adding a protocol means a new entry here plus an adapter file, not a plugin system.** -- `src/openapi.ts` / `src/graphql.ts` / `src/soap.ts`: the three adapters. - OpenAPI also does OAuth2 discovery (`discoverOAuth`) and derives the base URL - from document-, path-, or operation-level `servers` (`resolveBaseUrl`), - failing loudly if the result lands on a raw spec-hosting host (e.g. - raw.githubusercontent.com) rather than silently registering a broken base. - After `openapi-typescript` writes the `.d.ts`, OpenAPI post-processes it - through `src/openapi-sanitize.ts` (see below). +- `src/openapi.ts` / `src/graphql.ts` / `src/soap.ts` / `src/atproto.ts`: the + protocol adapters. OpenAPI also does OAuth2 discovery (`discoverOAuth`) and + derives the base URL from document-, path-, or operation-level `servers` + (`resolveBaseUrl`), failing loudly if the result lands on a raw spec-hosting + host (e.g. raw.githubusercontent.com) rather than silently registering a + broken base. After `openapi-typescript` writes the `.d.ts`, OpenAPI + post-processes it through `src/openapi-sanitize.ts` (see below). - `src/openapi-sanitize.ts`: post-processes openapi-typescript output so a recursive "arbitrary JSON" schema (or a `$ref` cycle) can't fail the whole-program type check `execute` runs. openapi-typescript references schemas @@ -63,8 +65,28 @@ protocol plugs in through one in-tree adapter object. browser login flow (local one-shot callback server), token storage in the keystore, automatic refresh (`ensureAccessToken`), and a small known-provider quirks table (e.g. Strava's real endpoints + comma scope separator). +- `src/atproto.ts`: the AT Protocol adapter. It generates **no** types of its + own: `prepare()` dynamic-imports the lexicons shipped in `@atproto/api` + (pinned `ATPROTO_API`) to build the operation index from the runtime + `schemas`, and `writeTypes` emits only an `XrpcMethods` map (NSID → + `{ params, input, output }`) whose members point at the official per-method + type namespaces. NSID → namespace name comes from the package's own `ids` + export (never derived), so a `Lex.` reference can't drift and break the + whole-program check. The harness imports those types **type-only** + (`import type * as Lex`), so nothing from the SDK runs in the sandbox; the + client is a thin XRPC fetch wrapper whose `query`/`procedure` infer params + + result from the NSID string literal. +- `src/atproto-auth.ts`: app-password session auth, the atproto analogue of + `oauth.ts`. `ensureAtprotoAccessToken` returns `string | undefined` and + escalates only as far as needed — empty `identifier` → `undefined` (anonymous; + public reads, no token) → cached access JWT → `refreshSession` → + `createSession` from the stored app password (the self-heal path; no browser, + unlike OAuth) — all in the parent. `identifier` is the intent signal: set + means "act as this account" (and a missing session/password is a hard + `AtprotoNeedsLoginError`, not a silent anonymous fallback); empty means + anonymous by design. - `src/registry.ts`: the `apis.jsonl` registry (one `RegistryEntry` per line). - `Auth` is a union: `none` | `bearer` | `oauth2`. + `Auth` is a union: `none` | `bearer` | `oauth2` | `atproto`. - `src/register.ts`: registration logic shared by `add` and `add_api`; resolves the OAuth config (precedence: explicit flag > quirk > discovered). `force` upserts in place (fresh `addedAt` invalidates serve's ops cache; same-id @@ -85,7 +107,9 @@ protocol plugs in through one in-tree adapter object. - `src/keystore.ts`: OS keychain access (`security` on macOS, `secret-tool` on Linux). Service name is `anyapi-mcp`; accounts look like `anyapi-mcp:` (bearer), `anyapi-mcp::client` / `anyapi-mcp::oauth` (OAuth client - creds + token bundle, each a JSON blob). + creds + token bundle), and `anyapi-mcp::apppass` / + `anyapi-mcp::session` (atproto app password + session bundle), each a JSON + blob. - `src/paths.ts`: XDG dirs. Registry under `~/.config/anyapi-mcp`, generated types under `~/.cache/anyapi-mcp`. - `src/execute/run.ts`: the sandboxed subprocess runner (per-call `check` and @@ -106,12 +130,13 @@ protocol plugs in through one in-tree adapter object. `--check` — it never touches the net/env allowlist above, so it is not a grant widening. - **Secrets** live only in the OS keystore. The registry stores keystore account - names (`tokenKey`; for OAuth also `clientKey`), never the secret itself. No - MCP tool may accept secrets: bearer tokens go through - `anyapi-mcp add --token`, and OAuth client credentials go through - `anyapi-mcp login` (`--client-id` / `--client-secret`). The agent-facing - `authenticate` tool only (re-)runs the browser flow with credentials the user - already stored. + names (`tokenKey`; for OAuth also `clientKey`; for atproto `passwordKey` / + `sessionKey`), never the secret itself. No MCP tool may accept secrets: bearer + tokens go through `anyapi-mcp add --token`, OAuth client credentials through + `anyapi-mcp login` (`--client-id` / `--client-secret`), and atproto app + passwords through `anyapi-mcp login` (`--identifier`, password read without + echo) or `add --app-password`. The agent-facing `authenticate` tool only + (re-)runs the OAuth browser flow with credentials the user already stored. - **Agents may set only the _safe_ OAuth params.** `configure_oauth` (and the `login`/`add` CLI) can change `scopes`/`scopeSeparator`/`extraAuthParams`, but the `authorizationUrl`/`tokenUrl` endpoints are CLI-only: `tokenUrl` is where @@ -119,11 +144,13 @@ protocol plugs in through one in-tree adapter object. exfiltration vector. `buildAuthorizeUrl` and `configure_oauth` both reject `RESERVED_AUTHORIZE_PARAMS` (`client_id`, `redirect_uri`, `response_type`, `scope`, `state`) in `extraAuthParams`. -- **OAuth lives in the parent, never the sandbox.** Token refresh and the login - flow run in the serve/CLI process (full net + keystore). The execute sandbox - only ever receives a ready access token via `ANYAPI_MCP_TOKEN`; it never sees - the client secret or refresh token and never calls the token endpoint. Refresh - happens in `executeRequest` (via `ensureAccessToken`) before the harness runs. +- **OAuth/atproto auth lives in the parent, never the sandbox.** Token/session + refresh and the login flow run in the serve/CLI process (full net + keystore). + The execute sandbox only ever receives a ready access token/JWT via + `ANYAPI_MCP_TOKEN`; it never sees the OAuth client secret/refresh token, nor + the atproto app password/refresh JWT, and never calls the token or session + endpoints. Refresh happens in `executeRequest` (via `ensureAccessToken` / + `ensureAtprotoAccessToken`) before the harness runs. - `serve` re-reads the registry on each call, so a mid-session `add_api`/`add` is usable without restart. Keep it stateless across calls. - Strict TS is on (`noUnusedLocals`, `noUnusedParameters`, `noImplicitOverride`, @@ -133,8 +160,16 @@ protocol plugs in through one in-tree adapter object. OpenAPI specs in JSON or YAML — OpenAPI 3.x, or Swagger 2.0 auto-converted to 3.0 via swagger2openapi — GraphQL endpoints, SOAP/WSDL (WSDL 1.1, -document/literal). Auth: none, bearer, or OAuth 2.0 **authorization-code** (the +document/literal), and AT Protocol/lexicon/XRPC (the lexicon set shipped in the +pinned `@atproto/api`; `add --kind atproto `, e.g. +https://bsky.social). Auth: none, bearer, OAuth 2.0 **authorization-code** (the only OAuth flow; auto-discovered from OpenAPI security schemes, or set manually -with `--oauth`/`--auth-url`/`--token-url`). No PKCE, no implicit/client-creds/ -password grants yet. Each `execute` is a fresh subprocess with no persisted -state; OAuth tokens persist in the keystore and refresh automatically. +with `--oauth`/`--auth-url`/`--token-url`), or atproto **app-password sessions** +(`createSession`/`refreshSession`, minted/refreshed in the parent; the sandbox +gets only the access JWT) — or **anonymous** atproto (no `--identifier`) for +public reads, replacing the old "point an OpenAPI entry at the public AppView" +trick. No PKCE, no implicit/client-creds/password grants, and no atproto +**OAuth** (its DPoP-bound tokens can't be replayed as a bearer through the +sandbox) yet. Each `execute` is a fresh subprocess with no persisted state; +OAuth tokens and atproto sessions persist in the keystore and refresh +automatically. diff --git a/README.md b/README.md index e4bed51..4a1b51d 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,11 @@ **anyapi-mcp is one local MCP server that lets your model talk to almost any HTTP API.** Add it once to Claude Code or Claude Desktop, then point it at any -API you find (an OpenAPI spec, a GraphQL endpoint, or a SOAP/WSDL service) and -your model can search and call it right away. No separate server or custom -integration per API: one server covers everything you register, and it stays -token-efficient however many calls a task takes. +API you find (an OpenAPI spec, a GraphQL endpoint, a SOAP/WSDL service, or an AT +Protocol/XRPC service like Bluesky) and your model can search and call it right +away. No separate server or custom integration per API: one server covers +everything you register, and it stays token-efficient however many calls a task +takes. Under the hood it generates a typed client from the API's own description and exposes a small set of tools: `search` to find operations, `execute` to run a @@ -50,20 +51,17 @@ The quickest way - builds from source, so you'll need [Deno](https://deno.com/) curl -fsSL https://gabrielbauman.github.io/anyapi-mcp/install.sh | sh ``` -It fetches the source, runs `deno task compile`, and drops an `anyapi-mcp` -binary in `~/.local/bin` (override the location with `ANYAPI_MCP_BIN_DIR`). +It fetches the source, runs `deno task compile`, drops an `anyapi-mcp` binary in +`~/.local/bin` (override the location with `ANYAPI_MCP_BIN_DIR`), and registers +it with Claude Code, Claude Desktop, and OpenCode so it's ready to use (skip +that last step with `ANYAPI_MCP_NO_INSTALL=1`). Or build it yourself: ```sh deno task compile # produces a self-contained ./anyapi-mcp binary mv ./anyapi-mcp ~/.local/bin/ # or anywhere on your PATH -``` - -Then point your MCP client at it automatically: - -```sh -anyapi-mcp install # adds it to Claude Code and/or Claude Desktop +anyapi-mcp install # register it with Claude Code, Claude Desktop, and OpenCode ``` Or run from source during development: @@ -76,24 +74,26 @@ deno task dev list # = deno run -A src/main.ts list ### `add [options]` -Inspects the source (an OpenAPI spec, a GraphQL endpoint, or a WSDL), derives -the base URL and host, builds a searchable operation index, generates a typed -client, and writes a registry entry. - -| Option | Description | -| --------------------------------- | --------------------------------------------------------------------------------------------------------- | -| `--kind ` | Protocol (default: `openapi`). `graphql` introspects an endpoint; `soap` reads a WSDL URL. | -| `--id ` | Id used on the CLI and in `execute` (default: the base URL in reverse-DNS form, e.g. `com.github.api`). | -| `--name ` | Human-friendly name (default: spec `info.title`). | -| `--base-url ` | Override the base URL (otherwise derived from the spec's document-, path-, or operation-level `servers`). | -| `--docs ` | Documentation URL to store and surface (not parsed). | -| `--token` | Store a bearer token. Read without echo from a TTY, or piped via stdin. | -| `--oauth` | Treat the API as OAuth 2.0 even if the spec doesn't declare it. | -| `--auth-url` / `--token-url` | OAuth authorize / token endpoints (override the spec's values). | -| `--scope ` | Scope to request at login (repeatable; default: the spec's scopes). | -| `--scope-separator ` | Scope separator in the authorize URL (default `" "`; Strava uses `","`). | -| `--no-auth` | Register without authentication. | -| `--force` | Overwrite an existing API with the same id instead of failing (e.g. to fix a wrong base URL). | +Inspects the source (an OpenAPI spec, a GraphQL endpoint, a WSDL, or an atproto +PDS/service URL), derives the base URL and host, builds a searchable operation +index, generates a typed client, and writes a registry entry. + +| Option | Description | +| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--kind ` | Protocol (default: `openapi`). `graphql` introspects an endpoint; `soap` reads a WSDL URL; `atproto` takes a PDS/service URL (e.g. `https://bsky.social`). | +| `--id ` | Id used on the CLI and in `execute` (default: the base URL in reverse-DNS form, e.g. `com.github.api`). | +| `--name ` | Human-friendly name (default: spec `info.title`). | +| `--base-url ` | Override the base URL (otherwise derived from the spec's document-, path-, or operation-level `servers`). | +| `--docs ` | Documentation URL to store and surface (not parsed). | +| `--token` | Store a bearer token. Read without echo from a TTY, or piped via stdin. | +| `--identifier ` | atproto: the account handle/email to authenticate as (not a secret). | +| `--app-password` | atproto: store an app password now. Read without echo from a TTY, or piped via stdin. | +| `--oauth` | Treat the API as OAuth 2.0 even if the spec doesn't declare it. | +| `--auth-url` / `--token-url` | OAuth authorize / token endpoints (override the spec's values). | +| `--scope ` | Scope to request at login (repeatable; default: the spec's scopes). | +| `--scope-separator ` | Scope separator in the authorize URL (default `" "`; Strava uses `","`). | +| `--no-auth` | Register without authentication. | +| `--force` | Overwrite an existing API with the same id instead of failing (e.g. to fix a wrong base URL). | If the base URL can't be derived and would fall back to a raw spec-hosting host (e.g. `raw.githubusercontent.com`), `add` fails loudly instead of registering a @@ -121,6 +121,13 @@ anyapi-mcp add https://countries.trevorblades.com/ --kind graphql # soap - read a public WSDL pointing at a live service: anyapi-mcp add "http://www.dneonline.com/calculator.asmx?WSDL" --kind soap + +# atproto - anonymous public reads (no login), via the public AppView: +anyapi-mcp add https://public.api.bsky.app --kind atproto --id bsky-public + +# atproto - register your account to post / read private data (PDS + login): +anyapi-mcp add https://bsky.social --kind atproto --id bsky --identifier you.bsky.social +anyapi-mcp login bsky # prompts for an app password (no echo) ``` ### `list` @@ -360,13 +367,26 @@ For a **SOAP** API the harness exposes one method per operation - `{ status, data, raw }` where `data` is the parsed SOAP `Body`. anyapi-mcp builds the envelope and parses the response for you. +For an **atproto** (AT Protocol / lexicon / XRPC) API the harness exposes +`client.query(nsid, params)` and `client.procedure(nsid, input)`. The NSID +string literal selects the official `@atproto/api` types (imported type-only, so +none of the SDK runs in the sandbox), so params, input, and the awaited result +are all typed - +`const tl = await client.query("app.bsky.feed.getTimeline", { limit: 20 })` +gives a typed `tl.feed`. Public reads work anonymously - register against the +public AppView (`https://public.api.bsky.app`) with no `--identifier`. Writes +and your own private data need a session: register against your PDS (e.g. +`https://bsky.social`) with `--identifier`, then run +[`login`](#login-id-options) once to store an app password. + ## Design notes & limits - **Secrets** live in the OS keystore (service `anyapi-mcp`), never in the registry. The registry only records keystore account names (`tokenKey`; for - OAuth also `clientKey`). OAuth refresh and the browser login run in the parent - process — the execute sandbox only ever receives a ready access token, never - the client secret or refresh token. + OAuth also `clientKey`; for atproto `passwordKey` / `sessionKey`). OAuth and + atproto refresh/login run in the parent process — the execute sandbox only + ever receives a ready access token/JWT, never the client secret, refresh + token, app password, or refresh JWT. - **Files**: registry at `$XDG_CONFIG_HOME/anyapi-mcp/apis.jsonl` (default `~/.config/anyapi-mcp`); generated `.d.ts` and operation indexes at `$XDG_CACHE_HOME/anyapi-mcp` (default `~/.cache/anyapi-mcp`). @@ -381,18 +401,21 @@ builds the envelope and parses the response for you. - **Protocols & adapters**: each protocol is an in-tree `ProtocolAdapter` (`src/adapter.ts`) - a `prepare()` that turns a source into base URL + hosts + an operation index + generated types, and a `buildHarness()` that puts a typed - `client` in scope. OpenAPI, GraphQL, and SOAP/WSDL ship today; adding one is a - new arm in `src/adapters.ts`, not a plugin system. The registry, `search`, and - the execute sandbox are protocol-agnostic. + `client` in scope. OpenAPI, GraphQL, SOAP/WSDL, and AT Protocol/XRPC ship + today; adding one is a new arm in `src/adapters.ts`, not a plugin system. The + registry, `search`, and the execute sandbox are protocol-agnostic. - **SOAP scope**: WSDL 1.1, SOAP 1.1/1.2, document/literal, public WSDL → live service. Not covered: rpc/encoded, WS-Security / SOAP headers, MTOM, external XSD imports, WSDL 2.0. - **v1 scope**: OpenAPI specs in JSON or YAML - OpenAPI 3.x, or Swagger 2.0 - auto-converted to 3.0 - plus GraphQL endpoints and SOAP/WSDL services; **no / - bearer / OAuth 2.0 authorization-code** auth (no PKCE, implicit, - client-credentials, or password grants). `search` is keyword-based over the - operation index - no embeddings or freeform-doc search. Each `execute` is a - fresh subprocess (no persistent state between calls); OAuth tokens persist in + auto-converted to 3.0 - plus GraphQL endpoints, SOAP/WSDL services, and AT + Protocol/lexicon/XRPC (the lexicon set shipped in the pinned `@atproto/api`). + Auth: **none / bearer / OAuth 2.0 authorization-code** (no PKCE, implicit, + client-credentials, or password grants), or atproto **app-password sessions** + (or anonymous, for public reads; atproto OAuth, whose tokens are DPoP-bound, + isn't supported yet). `search` is keyword-based over the operation index - no + embeddings or freeform-doc search. Each `execute` is a fresh subprocess (no + persistent state between calls); OAuth tokens and atproto sessions persist in the keychain and refresh automatically. ## Development diff --git a/deno.lock b/deno.lock index 8d3baf3..b550eb5 100644 --- a/deno.lock +++ b/deno.lock @@ -10,6 +10,7 @@ "jsr:@std/internal@^1.0.14": "1.0.14", "jsr:@std/path@^1.1.5": "1.1.5", "jsr:@std/yaml@^1.1.1": "1.1.1", + "npm:@atproto/api@0.20.9": "0.20.9", "npm:@modelcontextprotocol/sdk@1.29.0": "1.29.0_zod@4.4.3", "npm:fast-xml-parser@*": "4.5.6", "npm:fast-xml-parser@^4.5.6": "4.5.6", @@ -56,6 +57,67 @@ } }, "npm": { + "@atproto/api@0.20.9": { + "integrity": "sha512-Yuw7Ewn+yMJZ8GskbuvI3lKPW65rsXic1xjFA2Dpq6H8WjVYs6xNZ31bkwtTYDDwjKIZcJmAVbAVgdfjo4T9iw==", + "dependencies": [ + "@atproto/common-web", + "@atproto/lexicon", + "@atproto/syntax", + "@atproto/xrpc", + "await-lock", + "multiformats", + "tlds", + "zod@3.25.76" + ] + }, + "@atproto/common-web@0.5.0": { + "integrity": "sha512-ReWnkuZdDU/74/I47gaI26uxQjHmpq4edp41NnZZQ5vIIKGb7Ei6pZHzDTUD9JURo109SKrPx9RMP2IQm0fOKA==", + "dependencies": [ + "@atproto/lex-data", + "@atproto/lex-json", + "@atproto/syntax", + "zod@3.25.76" + ] + }, + "@atproto/lex-data@0.1.1": { + "integrity": "sha512-/xza8nU/YhtzhETnHL3QKKofaJ28/0NCzhT7LaYoUkm8EgypWp5ykEtmW52yLhQM2JF6fVa25g1soQmNTGqtSg==", + "dependencies": [ + "multiformats", + "tslib", + "uint8arrays", + "unicode-segmenter" + ] + }, + "@atproto/lex-json@0.1.0": { + "integrity": "sha512-oWUrRMwFyWpmi/5k1Se3xBTbP06XdxBS5iFuUz9LmqItaPXwrWRD87a9ldPvINQ/A2/mn7J6/qug8sDVlhD+vQ==", + "dependencies": [ + "@atproto/lex-data", + "tslib" + ] + }, + "@atproto/lexicon@0.7.1": { + "integrity": "sha512-voNfNED5KUxn3vpo7N5DMRblBDfWf7kSfdKhJFC1RrLCxg38YbBzzURNVQJ32bp13Oot8kYfyXBWxTgtKLvw8w==", + "dependencies": [ + "@atproto/common-web", + "@atproto/syntax", + "multiformats", + "zod@3.25.76" + ] + }, + "@atproto/syntax@0.6.1": { + "integrity": "sha512-kA4dQDoMPpWCH8N0Q4KoSq024u5MkVfDVa8DdhyLjGA72z/khbOf1jXKPv7NIL2oEc9aj7geKELdvqyf4ogopA==", + "dependencies": [ + "iso-datestring-validator", + "tslib" + ] + }, + "@atproto/xrpc@0.8.0": { + "integrity": "sha512-NJy02bIKrWlE2NQkRV1kT0Cj0ixbuxlF/MejBdo4cPWAa9v3oZexvAcjjb0zaOYeABkaU14iyIhvn2G4e/oLpw==", + "dependencies": [ + "@atproto/lexicon", + "zod@3.25.76" + ] + }, "@babel/code-frame@7.29.7": { "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dependencies": [ @@ -94,7 +156,7 @@ "json-schema-typed", "pkce-challenge", "raw-body", - "zod", + "zod@4.4.3", "zod-to-json-schema" ] }, @@ -167,6 +229,9 @@ "argparse@2.0.1": { "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "await-lock@3.0.0": { + "integrity": "sha512-eO6fLiSnrJrMdjWMNK8zbVRXPs2TKJg78iKZd9wDpN3na5tcoV6EoeiOlMgk2QaAQ1gIrK1YuMsJHXWqz89tSA==" + }, "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, @@ -485,6 +550,9 @@ "isexe@2.0.0": { "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "iso-datestring-validator@2.2.2": { + "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==" + }, "jose@6.2.3": { "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==" }, @@ -534,6 +602,9 @@ "ms@2.1.3": { "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "multiformats@13.4.2": { + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==" + }, "negotiator@1.0.0": { "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==" }, @@ -849,12 +920,19 @@ ], "bin": true }, + "tlds@1.261.0": { + "integrity": "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==", + "bin": true + }, "toidentifier@1.0.1": { "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "tr46@0.0.3": { "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "tslib@2.8.1": { + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "type-fest@4.41.0": { "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==" }, @@ -870,6 +948,15 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "bin": true }, + "uint8arrays@5.1.1": { + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "dependencies": [ + "multiformats" + ] + }, + "unicode-segmenter@0.14.5": { + "integrity": "sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==" + }, "unpipe@1.0.0": { "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, @@ -934,9 +1021,12 @@ "zod-to-json-schema@3.25.2_zod@4.4.3": { "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", "dependencies": [ - "zod" + "zod@4.4.3" ] }, + "zod@3.25.76": { + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" + }, "zod@4.4.3": { "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==" } diff --git a/site/index.html b/site/index.html index b6ba722..048cf51 100644 --- a/site/index.html +++ b/site/index.html @@ -3,11 +3,11 @@ - anyapi-mcp - one MCP server for almost any HTTP API - + anyapi-mcp - one MCP server, every API your model needs + - +