cyfyr v0.1 · 6 commits · 5 checks
cross-provider stack diagnostician·cli + mcp·read-only

cyfyr

The diagnostic layer for the AI-native stack.
Reads your manifest. Probes every provider. Reports the seams.

no telemetry no account read-only v0.1
cyfyr-doctor · imprint/web
$ cyfyr doctor Cyfyr doctor · imprint/web · 5 checks · 0.6s ── INTEGRITY ───────────────────────────────────── stripe.webhook.endpoints 1 issue across 1 webhook endpoint https://imprint.run/api/webhook — returns 404 evidence: live · enabled · 6 events · GET 404 ── REACHABILITY ────────────────────────────────── stripe.api.auth · key valid (live mode) host.cli.auth · wrangler whoami exited 1 · email.dns.dkim · email not configured ── DRIFT ───────────────────────────────────────── · env.parity · only 1 env file present ────────────────────────────────────────────────── 2 failed · 0 warned · 1 ok · 2 skipped $
01thesis

Bugs hide in the seams between providers.

A modern app spans five to ten SaaS providers — host, database, auth, payments, email, observability — plus the agent layer that writes the code in the first place.

No single vendor builds cross-provider checks. Stripe doesn't know your webhook target is undeployed. Cloudflare doesn't know which Stripe events Stripe is delivering. The seam between them is invisible to both dashboards — and to every individual provider's CLI.

cyfyr doctor reads from both sides and reports the disagreement.

Read-only. Local. Yours. No telemetry, no account, no enterprise upsell. The check library is the asset — captured scar tissue from real production bugs, growing one PR at a time.

01 / model
anthropic · openai · google
02 / host
vercel · cloudflare · fly
03 / db
supabase · neon · turso
04 / auth
clerk · workos · auth0
05 / payments
stripe
06 / email
resend · postmark
07 / obs
sentry · posthog · axiom
02checks

Five checks in v0.1.
Two in the moat.

Single-provider checks are commodities; every provider's own CLI can do them. Cross-provider integrity checks are what nobody else will build — because no individual provider has visibility into the seams, and no provider's incentives align with reporting them.

stripe.webhook.endpoints moat
Lists Stripe's registered webhook URLs, GET-probes each one against your live host. Catches: localhost-in-prod URLs, 404 (handler not deployed), 5xx (handler broken), 200 to GET (suspicious routing), disabled endpoints. Caught a 404 on imprint.run/api/webhook in the wild on first run.
integrity
·
email.dns.dkim moat
For each verified Resend domain: fetches the issued DKIM key, resolves the actual DNS TXT record at the selector, reports drift. Catches: rotated keys that never propagated to DNS — the silent deliverability killer that no provider dashboard surfaces.
integrity
·
stripe.api.auth
Hits /v1/balance with STRIPE_SECRET_KEY. Reports key validity and live-vs-test mode. Catches: expired keys, wrong mode, network failures.
reachability
·
host.cli.auth
Runs vercel / netlify / wrangler / fly whoami. Reports authenticated identity. Catches: CLI not installed, expired login, wrong account selected.
reachability
·
env.parity
Diffs keys (not values) across .env, .env.local, .env.production. Catches the classic "works locally, broken in preview" — env vars added to one file but not the others.
drift
03agents

Your agent stops guessing
and starts querying.

cyfyr ships an MCP server. Wire it into Claude Code, Codex, or Cursor and every conversation gets three new tools: cyfyr_doctor_run, cyfyr_doctor_list, cyfyr_doctor_explain.

user
my stripe webhook isn't firing on imprint
tool · cyfyr_doctor_run
category: integrity, cwd: /Users/ltlai/imprint/web
agent
Doctor found it. Your registered webhook endpoint imprint.run/api/webhook returns 404 — Stripe is delivering 6 event types to a dead URL. Three ways to fix:
1. Deploy a handler at /api/webhook
2. Repoint the Stripe endpoint to your actual handler
3. Disable the endpoint in the Stripe dashboard.
// ~/.claude.json (user-scope) — or .mcp.json per project
{
  "mcpServers": {
    "cyfyr-doctor": {
      "command": "node",
      "args": ["/path/to/cyfyr/out/doctor/mcp.js"]
    }
  }
}
04install

One config file.
Two commands.

No package to download, no account to make, no key to generate. cyfyr runs against your existing API credentials — nothing leaves your machine.

# 1. clone & build
$ git clone https://github.com/electjustinoberg/cyfyr ~/cyfyr
$ cd ~/cyfyr && npm install && npm run compile

# 2. declare your stack — one .cyfyr/config.json per project
$ mkdir -p .cyfyr && cat > .cyfyr/config.json <<EOF
{
  "model":    { "provider": "anthropic" },
  "host":     { "provider": "vercel" },
  "db":       { "provider": "supabase" },
  "payments": { "provider": "stripe" },
  "email":    { "provider": "resend" }
}
EOF

# 3. diagnose
$ node ~/cyfyr/out/doctor/cli.js
#    (or wire the MCP server above and ask your agent)