Local-first, spec-synced, agent-native API client. Your API collection is plain text — your coding agent and your CI both read it, run it, and keep it in sync with your OpenAPI spec. Fully offline. No account, ever.
📚 Read the documentation → — getting started, file format, CLI, spec sync, CI, MCP, and the programmatic API.
The API-client market runs from local-and-minimal (Bruno) to cloud-and-everything (Postman). TruSpec owns the unclaimed intersection: an integrated engine where your OpenAPI spec is the source of truth, your collection is plain text, and an AI agent or CI pipeline can run it and fail the build the moment your code drifts from the spec — entirely offline.
| Postman | Bruno | TruSpec | |
|---|---|---|---|
| Local files + Git source of truth | ✗ | ✓ | ✓ |
| Fully offline, no account | ✗ | ✓ | ✓ |
| Open source (MIT) | ✗ | ✓ | ✓ |
| OpenAPI drift detection (CI gate) | ✗ | basic | ✓ |
| OpenAPI coverage report | ✗ | ✗ | ✓ |
| OpenAPI response contract validation | ✗ | ✗ | ✓ |
| Local mock server (no cloud) | cloud | ✗ | ✓ |
| Collection linter (inline secrets, dead assertions) | ✗ | ✗ | ✓ |
| Committable Markdown docs from the collection | cloud | ✗ | ✓ |
| First-party MCP server for agents | bolted-on | community | ✓ |
| Import from Postman + Bruno + Insomnia + curl + HAR | — | partial | ✓ |
| Code generation (17 clients/langs) | ✓ | ✓ | ✓ |
Install the CLI (Node ≥ 22):
npm i -g truspec # global `truspec` command — or run any command with `npx truspec …`
truspec --helpHacking on TruSpec itself? Run from source instead:
git clone https://github.com/code-with-rashid/truspec && cd truspec, thenpnpm install && pnpm build— nownode packages/cli/dist/index.jsis thetruspecbinary.
A collection is a folder of plain-text YAML files that diff cleanly and live in your repo:
# api/get-pet.tspec.yaml
name: Get pet by id
method: GET
url: "{{baseUrl}}/pets/{{petId}}"
assertions:
- { type: status, equals: 200 }
- { type: jsonpath, path: "$.id", exists: true }
spec:
operation: "GET /pets/{id}" # links back to your OpenAPI spectruspec init scaffolds exactly that — a request, an environment, and a .gitignore — in an empty folder.
See the blog and petstore example
collections rendered by truspec docs — those files are regenerated and diffed in CI, so they are
never out of date with the collections they describe.
Try it now — clone the repo for a ready-made collection + OpenAPI spec and run the whole loop offline. These commands work as-is (no placeholders to fill in):
git clone https://github.com/code-with-rashid/truspec
cd truspec
truspec mock examples/blog/openapi.yaml &
truspec run examples/blog --env local
truspec drift examples/blog --spec examples/blog/openapi.yaml
truspec coverage examples/blog --spec examples/blog/openapi.yamlYou should see run report 3 passing requests against the mock, drift flag GET /users/{id} as untracked, and coverage show 75% (3/4). (Two examples ship in examples/: petstore and a fuller blog.)
Point these at your own collection — a folder of .tspec.yaml files — plus your OpenAPI spec. Replace the <…> placeholders:
Start a collection
truspec init [<dir>]— scaffold a runnable collection (request + environment +.gitignore)truspec gen <openapi.yaml> --out <dir>— scaffold a request stub per spec operationtruspec import <postman|bruno|insomnia|curl|har> <path> --out <dir>— migrate what you already have
Run it
truspec run <dir> --env <name>— run requests + assertions; non-zero exit on failuretruspec run <dir> --data <file>— data-driven runs: one iteration per row of a CSV or JSON datasettruspec run <dir> --repeat <n>— run the selection n times (load smoke, flake hunting)truspec run <dir> --watch— re-run on file change while you edittruspec run <dir> --reporter <human|json|junit|html>— human by default, machine formats for CI
Keep it honest against the spec
truspec drift --spec <openapi.yaml> <dir> [--live <baseUrl>]— fail CI on drift vs the spec (and a live API)truspec coverage --spec <openapi.yaml> <dir> --min 80— gate on tested-operation coveragetruspec contract --spec <openapi.yaml> <dir> --env <name>— run + validate responses against the spec's schemastruspec mock <openapi.yaml> --port 4000— offline mock server from your spec
Work with it day to day
truspec lint <dir> --strict— 13 static checks (inline secrets, dead assertions, undeclared vars, …)truspec docs <dir> --out API.md— render the collection as committable Markdowntruspec env [--diff <a> <b>]— list, inspect, and diff environments (never prints secret values)truspec codegen <request> --lang <target>— a runnable snippet in any of 17 clients/languagestruspec export postman <dir>— hand the collection to someone who works in Postmantruspec serve <dir>— open the local web UI
The reporting commands — run, drift, coverage, contract, lint, env — all speak --json
for machines, and every command exits non-zero on failure, so they drop straight into CI.
Chaining: a request can capture a value for later requests in the same run (ordered by order) — e.g. log in, capture the token, use it downstream. No scripting required:
# 01-login.tspec.yaml → order: 1, capture: { token: "$.access_token" }
# 02-me.tspec.yaml → order: 2, auth: { type: bearer, token: "{{token}}" }truspec serve <dir> opens a local web UI over the same engine — and it reads and writes the same
plain-text files, so anything you do in it lands as a clean diff in your repo:
- Edit requests visually — URL, headers, query, body, auth, assertions, capture, scripts, tags, and options, with variable-aware inputs
- Manage the tree — create, rename, duplicate, and delete requests and folders; edit folder defaults and environments
- Run and inspect — single requests or the whole collection, with response body, timings, assertion results, and script logs
- Flow view — visualize and run request chains as a graph, so a capture-and-reuse sequence is something you can see
- Import and export — pull in Postman/Bruno/Insomnia/curl/HAR, push back out to Postman, or copy a request as a snippet
- Drift, coverage, and the mock server — the spec-sync loop and a mock with a live request log, without leaving the UI
- Keyboard-first — a command palette (and a shortcuts reference) for everything above
Prefer a GUI over the CLI, without a Node install? TruSpec Desktop is a native app (built with Tauri) that wraps the same UI in an installable window.
Grab the installer for your OS from the latest release:
- Windows —
TruSpec_<version>_x64-setup.exe(or the.msi) - macOS —
TruSpec_<version>_aarch64.dmg(Apple Silicon; runs on Intel Macs too, under Rosetta 2) - Linux —
.AppImage,.deb, or.rpm
These are unsigned builds for now (no code-signing cert or Apple notarization yet), so your OS will warn on first launch:
- Windows: SmartScreen shows "unknown publisher" — click More info → Run anyway.
- macOS: Gatekeeper quarantines the download — run
xattr -cr /Applications/TruSpec.apponce, then open it. - Linux: no equivalent warning.
TruSpec ships a first-party MCP server so agents like Claude Code can author, run, and sync collections directly.
# published (recommended):
claude mcp add truspec -- npx -y @truspec/mcp-server
# or from a source checkout, after `pnpm build`:
claude mcp add truspec -- node ./packages/mcp-server/dist/index.jsOr add it to your MCP client config:
{
"mcpServers": {
"truspec": { "command": "npx", "args": ["-y", "@truspec/mcp-server"] }
}
}23 tools, grouped by what an agent is trying to do:
| Tools | |
|---|---|
| Author | list_collections · read_request · create_request · update_request · delete_request · validate_request · format_reference |
| Run | run_request · run_collection · environments |
| Sync with the spec | drift · coverage · contract · scaffold_from_spec |
| Mock | mock_start · mock_stop |
| Inspect | lint · docs |
| Generate | codegen · codegen_targets |
| Import | import_curl · import_har · import_insomnia |
(Each is prefixed truspec_ — e.g. truspec_run_collection.) Write operations validate against the
schema before touching disk, and format_reference lets an agent look the format up rather than
guess at it.
@truspec/core — the engine (pure TS; no platform deps in the browser-safe entry)
├─ format parse / serialize / validate (+ the published JSON Schema)
├─ runner interpolation, auth, fetch, declarative assertions, scripts
├─ workspace discovery, folder inheritance, env + secret resolution
├─ spec OpenAPI drift, coverage, response-contract validation
├─ importers Postman · Bruno · Insomnia · curl · HAR → .tspec.yaml
├─ exporters collection → Postman v2.1
├─ codegen request → a runnable snippet in 17 clients/languages
├─ lint 13 static checks over a collection
├─ docs collection → deterministic Markdown
├─ mock local mock server generated from a spec
├─ jsonpath the JSONPath subset used by assertions and capture
└─ http shared server lifecycle (a shutdown that always terminates)
truspec — the CLI (14 commands: init · run · drift · coverage · contract · gen ·
codegen · lint · docs · env · import · export · mock · serve)
@truspec/mcp-server — the agent surface (23 MCP tools)
@truspec/web — the web UI + local server (truspec serve)
@truspec/desktop — the Tauri shell around that UI
truspec-vscode — the editor extension (CodeLens + results view)
Each core module is a subpath import — @truspec/core/runner, /spec, /lint, and so on. The
filesystem and server modules (workspace, spec, importers, mock, http) are deliberately
kept out of the browser-safe main entry.
Full documentation lives in docs/:
| Getting started · Core concepts | install, the example loop, and the mental model |
| File format · CLI · Programmatic API | the complete references |
| Spec sync · Mock server · Importing | drift & coverage, offline mocks, Postman/Bruno migration |
| Scripting · CI/CD · AI agents (MCP) · Editors | the advanced surfaces |
| FAQ & troubleshooting | common questions and error fixes |
One request per file (*.tspec.yaml), folder config (folder.tspec.yaml) for shared base URL/auth/headers, and environments (environments/*.env.yaml) where secrets are referenced by name, never inlined. The Zod schema in packages/core/src/format/schema.ts is the source of truth; a JSON Schema is generated to packages/core/schema/ for editors and agents. See the file format reference for the full guide (or CLAUDE.md for the agent-oriented summary).
pnpm test # vitest
pnpm test:coverage # v8 coverage
pnpm typecheck
pnpm build
pnpm gen:schema # regenerate JSON Schema from the Zod sourceCI runs the suite on Linux, macOS, and Windows, and additionally checks that the published JSON
Schema is in sync with the Zod source, that the example collections pass truspec lint --strict,
and that the committed example docs are byte-identical to a fresh truspec docs render.
TruSpec is alpha: the file format is at schema version 0.1 and any breaking change bumps
SCHEMA_VERSION and ships a migration.
Shipped
- Format — the Zod schema, a published JSON Schema, and validation on every write
- Runner — REST + GraphQL, bearer / basic / API-key / OAuth2 auth, request chaining via
capture, pre-/post-request scripts, retries, redirects, and TLS options (--ca,--proxy,--insecure) - Spec sync — drift (added / removed / changed, plus a
--liveAPI probe), coverage, and response-contract validation ({ type: schema },run --spec,contract) - Mock server — local and offline, generated from a spec, with latency simulation and request validation
- CLI — 14 commands,
--jsoneverywhere, andhuman/json/junit/htmlrun reporters - Secrets — referenced by name, resolved from the OS env or a project
.env, masked in run output, and never written into generated snippets - Interop — import from Postman / Bruno / Insomnia / curl / HAR; export back to Postman v2.1
- Agents — a first-party MCP server with 23 tools
- GUI — the web UI (
truspec serve) with full request editing, a Flow view, and a command palette; an installable desktop app for Windows / macOS / Linux - Editors — a VS Code extension with CodeLens and a results view (pre-release)
Next
- Publish the VS Code extension to the Marketplace
- A Bun-compiled single binary for zero-install distribution (it still needs the
serveweb-client assets embedded and version stamping wired into the compile step) - Signed and notarized desktop builds, so first launch stops warning
Deferred by design (not bloat): hosted dashboards, visual flow builders, exotic protocols, mandatory cloud sync.