search_docs
Search the StitchAPI documentation semantically (hybrid BM25 + vector). Returns the most relevant doc sections as excerpts with deep links — never full pages. Follow up with get_doc to read a full page.
limitqueryrequired
dev.stitchapiPublished by stitchapi.devOfficial publisherv1.1.0Updated Oct 24, 2026
Search and read the StitchAPI docs: search_docs finds relevant sections, get_doc reads a page.
Searches and reads the StitchAPI documentation, letting an assistant find relevant doc sections and fetch full pages as Markdown.
Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.
Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.
Read https://sourceweft.com/mcp/dev.stitchapi%2Fdocs/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.Add this to your client's mcpServers config.
{
"mcpServers": {
"stitchapi-docs": {
"type": "http",
"url": "https://stitchapi.dev/api/mcp"
}
}
}[StitchAPI — turn any API into a typed, resilient function]
API stitching: turn any API into a typed, resilient function. Declare an endpoint once — its types, auth, and resilience — and call it like a local function. No server, no codegen, no config files. The same definition answers to your code, the CLI, and an AI agent alike.
📚 stitchapi.dev — documentation, guides & live playground
[Dependencies: 0] [Bundle: ~21 kB min+gzip] [OpenSSF Scorecard] [npm provenance: signed]
[code health: 77 (B)] [coverage: 90% lines · 78% branches]
Zero runtime dependencies · ~21 kB min+gzip — a typical import { stitch } tree-shakes to ~19 kB, and with no transitive tree there is nothing else to install or audit. The cache engine and the OTLP exporter load lazily, on first use, so they are not in those figures. The size is an enforced budget in CI, not an aspiration.
Verifiable supply chain — every package publishes from GitHub Actions over OIDC with a signed npm build-provenance attestation, so you can confirm which commit and which workflow produced the tarball you installed. Each release also ships an SBOM in both SPDX and CycloneDX, and the repo is scored publicly by OpenSSF Scorecard.
[!NOTE]
StitchAPI is at
1.0.0-rc.9. The core runtime is feature-complete, zero-dependency, covered by a green test gate, and already running in production in two projects. We're validating in the wild before stamping a stable1.0.0— pin an exact version and expect only small, documented changes. Feedback is welcome.
.with()A stitch is StitchAPI's core primitive: it takes a single endpoint and hands back a callable. You declare the contract once — input, output, auth, resilience — and call it like a local function. The same definition your code calls, the CLI runs and an AI agent invokes — and every caller gets a capability, not a credential. A service with more than one endpoint is a seam — a group of stitches that share a base URL, auth, and one runtime (throttle budget, store, trace sink).
Keep the fetch or axios you already have — it's the adapter underneath. A stitch sits above the transport and turns an endpoint into a function rather than replacing the call.
In almost every project there's a src/api/ folder of thin functions that fire an HTTP request and pull the payload out of the response. Everything that actually makes an integration reliable — auth lifecycle, retries, rate limits, timeouts, response validation, drift detection, observability — gets re-implemented at every call site, and each wrapper rots independently. fetch hands back opaque bytes, and raw bytes aren't what application code (or an AI agent) needs; both want structured, validated, observable results.
A stitch folds all of that back into the call:
There are plenty of ways to get a typed API client — spec-based generators, hand-authored contract clients, workflow platforms, or a folder of hand-rolled fetch wrappers. StitchAPI sits in a spot none of them cover: it turns one endpoint at a time into a resilient, validated, observable function — no spec, no codegen, no config files, no server; only explicit composition.
undefined three layers downstream.For the full competitive landscape and positioning, see the Overview.
Knowing what a tool refuses to be is how you trust what it is:
fetch replacement — fetch/axios are the substrate underneath; a stitch sits above the transport.No server, no codegen, no config files, no implicit inheritance — only explicit composition.
stitch(url | config) returns a typed callable; a service with more than one endpoint is a seam that shares base, auth, throttle budget, store, and trace sink across its members.start → progress → drift → result → done); await is sugar that returns the final validated value.warn / info / verbose finding instead of a silent undefined.Retry-After, proactive throttle, layered timeouts, a circuit breaker, and idempotency keys.stitchapi/cache.bearer, apiKey, basic, cookieSession (auto-login/re-login), oauth2; secrets resolve at call time and never reach the caller.http by default; graphql, sse, stream, download, llm, shell, and postmessage are peer surfaces behind subpath imports.get/set store with optional atomic verbs; swap in Redis/Postgres to go distributed.STITCH_TRACE_* env vars. No collector, no dashboard.stitch run), HTTP (stitch serve), and MCP (stitch mcp)."dependencies": {}, built on global fetch, tree-shakeable; ~21 kB min+gzip for the whole entry, ~19 kB for a typical import { stitch } (the cache engine and the OTLP exporter load lazily, on first use).Validation is bring-your-own — pass a Zod schema or any Standard Schema validator; none is bundled. The examples below use Zod for familiarity, and api.example.com as an illustrative host — point them at your own API to run them, or try them as-is in the playground, which serves that host from an in-browser simulator.
The smallest stitch is a URL — declare once, call many times:
Path params use RFC 6570 URI templates; params, query, headers, and body all travel in one input object:
Reach for the full set of knobs only when you need them — they default off:
A stitch yields a typed event stream; await consumes it and returns the final value, while .safe() resolves to { ok, data, error } and .stream() yields progress, throttle waits, retries, and drift as they happen.
.with()Everything reusable is a named value, and a stitch composes values — no global config is ever required. A service with more than one endpoint is a seam: declare the shared base, auth, and budget once; each endpoint is a member that inherits the config and shares one runtime (throttle bucket, store, trace sink):
For lighter reuse, extends: [fragment | stitch] merges config left→right (own fields win), and .with() pre-binds part of the input while reusing the same runtime. Full guide: Authoring.
The declared output schema is the contract. Wrap it in drift(): a response is validated (the call returns the validated value — coerced, defaulted, unknown keys stripped), and the difference between the raw body and that validated value is reported as a leveled, non-fatal signal:
Drift is schema-anchored — no snapshot to manage. Severity lives in the schema: a required field missing/incompatible is a hard invalid that throws; everything else is non-fatal drift on the event stream. Declared variance (an optional field, a nullable, an empty array) validates clean, so it's never a false alarm; ignore silences known-but-unconsumed fields and level filters or re-levels the soft signals. The request side validates too: input takes a schema per part and fails fast before any request is sent. Full guide: Validation & drift.
The things every src/api/ folder reinvents are configuration here — uniform across every stitch:
throttle is proactive (keeps you under a limit before it bites; pool: 'host' shares a limiter across stitches), retry is reactive (backoff + Retry-After), and timeout aborts with a real AbortSignal. Three more knobs round it out: circuit fast-fails a dependency that's already down, idempotency injects a stable Idempotency-Key on writes, and verdict declares what counts as success — accept treats a non-2xx (e.g. 404) as a normal result instead of a throw, flag fails a 200 whose body says it failed. Full guide: Resilience.
A read-through response cache with in-process request coalescing — off by default, loaded lazily from stitchapi/cache only when a stitch sets cache. The key is derived from the resolved request (no caller-authored keys to drift) and principal-scoped by default, so user A is never served user B's cached response:
Caching is sound by construction: a stitch with an output schema caches only when that schema can be fingerprinted or you pin a fingerprint tag — otherwise it refuses to cache rather than serve a stale shape. Mark sensitive data sensitive: true to opt out entirely.
Auth is a field on the stitch — never global. Secrets resolve at call time (env(), credential.file()), the declaration is committable, and the caller gets data without ever seeing the credential:
bearer, apiKey, and basic are header strategies; oauth2() runs the client-credentials grant and caches/refreshes the token; and cookieSession runs a login, captures the cookie, replays it, and re-logs-in when the wall returns — the caller never sees the password or writes the cookie dance. Full guide: Auth.
A surface is the request style a stitch speaks. http is the default; the rest are peer surfaces on the same engine — auth, retry, throttle, timeout, validation, and the event stream compose with every one. Each ships as its own subpath import, so import { stitch } pulls in http alone.
Full guide: Surfaces.
The same typed unit is reachable four ways, so humans and agents call exactly the same validated, observable thing:
The three non-function doors address a stitch by its export name, the same name list_stitches and GET / list.
stitch run streams every event as one JSON line on stdout (ready for jq); stitch trace summarizes the run log — runs, failures, retries, drift, and latency percentiles. Full guide: Surfaces → CLI.
A stitch is built to be invoked by an AI agent. Auth lives on the stitch, so an agent gets a capability, not a credential. And rather than one MCP tool per endpoint (which floods the model's context), an agent drives a single code-mode tool, run_stitch: it writes a small TypeScript snippet that imports stitchapi and calls the stitch, with list_stitches and describe_stitch for discovery — so the context budget stays flat as the catalog grows.
Authoring is agent-friendly too — hand an agent one curl/HAR/doc example and it emits a stitch declaration, with a deterministic shortcut for the common case:
stitch init writes the “declare a stitch, don't hand-roll fetch” rule into the files coding agents read (AGENTS.md, Cursor/Windsurf/Cline rules, a CLAUDE.md section), and the docs build emits an auto-generated llms.txt. Full guide: Use from an agent.
A failed stitch throws a StitchError — an Error subclass carrying .status, .attempts, and (for response failures) .body (the parsed error payload, on a non-enumerable channel that never reaches a trace sink) and .url. Prefer branching? .safe() resolves to { ok, data, error }. Branch on .status and .attempts (plus instanceof RateLimitError) — the STITCH_* names below are documentation IDs, not runtime values, so there is no error.code to match on:
Full catalog: Errors & pitfalls.
Observability is a consumer of the event stream, not a separate system — and it's off by default. Opt in per stitch (trace: 'console' / fileSink(path) / a TraceSink) or globally with env vars — no collector, no dashboard, nothing to deploy:
Built-in sinks scrub secrets at the sink boundary (the live request is never touched). stitch trace summarizes the JSONL; @stitchapi/pino ships the same events as structured logs.
This repository is a pnpm workspace. The published library is stitchapi; the rest are thin, peer-dependency integrations that add no capability of their own. The table below is generated by pnpm gen:readme (and verified in CI by pnpm check:readme): it lists every publishable workspace package, so it never drifts as packages are added. Each package's own README links to it on npm.
The full documentation site lives at stitchapi.dev — Quickstart, per-feature Guides, Concepts, Surfaces, For agents, and the generated Reference.
The published library's own README (what npm renders) is in packages/core/README.md. Design notes live in docs/: Feature Lenses, Overview, Design.
Local setup, the dev loop, the bundle-size budget, and the worktree + PR workflow are documented in CONTRIBUTING.md.
Source: README.md at commit f197318
Search the StitchAPI documentation semantically (hybrid BM25 + vector). Returns the most relevant doc sections as excerpts with deep links — never full pages. Follow up with get_doc to read a full page.
limitqueryrequiredFetch a full StitchAPI documentation page as Markdown — the "read the whole thing" escape hatch for a search_docs hit. Pass a `url` (as returned by search_docs) or a `slug` like "guides/resilience/throttle".
urlslug100% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
import { stitch } from 'stitchapi';import { z } from 'zod';
const getUser = stitch({ path: 'https://api.example.com/users/{id}', output: z.object({ id: z.number(), name: z.string() }), pick: 'data',});
const user = await getUser({ params: { id: 1 } }); // typed · validatednpm install stitchapi@rc # or: pnpm add stitchapi@rc · yarn add stitchapi@rcimport { stitch } from 'stitchapi';
const getUsers = stitch('https://api.example.com/users');
const users = await getUsers(); // GET, parsed JSONconst getUser = stitch('https://api.example.com/users/{id}');
await getUser({ params: { id: 1 }, query: { expand: 'roles' } });// → GET https://api.example.com/users/1?expand=rolesconst getUser = stitch({ path: 'https://api.example.com/users/{id}', output: User, // a validator of your choice pick: 'data', retry: 3, // ≡ { attempts: 3 } timeout: '5s', // ≡ { total: '5s' } cache: '1m', // ≡ { ttl: '1m' }});
const user = await getUser({ params: { id: 42 } });// → typed · validated · retried · cachedimport { seam } from 'stitchapi';
const api = seam({ baseUrl: 'https://api.example.com', retry: { attempts: 3, on: [429, 503] }, timeout: { total: '30s' },});
const listUsers = api.stitch({ path: '/users', output: User.array(), pick: 'data',});const getUser = api.stitch({ path: '/users/{id}', output: User, pick: 'data',});import { drift, stitch } from 'stitchapi';import { z } from 'zod';
const listOrders = stitch({ path: 'https://api.example.com/users/{id}/orders', pick: 'data', output: drift( z.array(z.object({ id: z.number(), total: z.number().optional() })), { ignore: ['[].meta'], // acknowledged, unconsumed — don't report it level: { coerced: 'info' }, // re-level a kind, or pass a level/list to filter }, ),});const listUsers = stitch({ baseUrl: 'https://api.example.com', path: '/users', retry: { attempts: 4, on: [429, 502, 503] }, throttle: { rate: '1/s', concurrency: 2, pool: 'host' }, timeout: { total: '30s', each: '10s' },});const getUser = stitch({ path: 'https://api.example.com/users/{id}', output: User, pick: 'data', cache: '5m',});
const listAnnouncements = stitch({ path: 'https://api.example.com/announcements', output: z.array(z.object({ id: z.number(), title: z.string() })), pick: 'data', cache: { ttl: '1h', tenancy: 'app', vary: ['accept-language'], entries: 500, fingerprint: 1, // pins the shape — cacheable without a fingerprinter },});import { stitch } from 'stitchapi';import { bearer, env } from 'stitchapi/auth';
const getUser = stitch({ path: 'https://api.example.com/users/{id}', auth: bearer(env('API_TOKEN')), // resolved per call; the caller passes no secret});$ stitch from-curl 'curl https://api.example.com/users/7 -H "authorization: Bearer …"'# prints a ready-to-commit stitch: id-like segments lifted to {params}, secrets → env()STITCH_TRACE_CONSOLE=1 node app.js # live, colored, one line per event on stderrSTITCH_TRACE_FILE=./run.jsonl node app.js # append JSONL to a pathSTITCH_EXPORT=otlp node app.js # also fan events to an OTLP collector