{
  "checker": {
    "claims": [
      {
        "claim": "The server is read-only and cannot send WhatsApp messages",
        "command": "",
        "evidence": "Needs an OAuth token from /authorize, which only completes after a WhatsApp phone is linked (src/index.ts proceed(): token is returned only when isPaired()). No Cloudflare account and no phone in this guest.",
        "expected": "cannot be checked without an authenticated MCP session",
        "input": "none (no send tool in the MCP tool list; no authenticated call possible here)",
        "kind": "claim",
        "outcome": "Needs an OAuth token from /authorize, which only completes after a WhatsApp phone is linked (src/index.ts proceed(): token is returned only when isPaired()). No Cloudflare account and no phone in this guest.",
        "source": "It can't send anything.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "blocked"
      },
      {
        "claim": "Setup needs a Cloudflare Workers Paid account, Node 20+, and a phone",
        "command": "",
        "evidence": "Prerequisites missing in this disposable guest: no Cloudflare account, no Workers Paid plan, no phone to scan the WhatsApp QR code. Node 22 was installed and npm install succeeded; the deploy step (npm run deploy / wrangler deploy) was not run.",
        "expected": "deploy and link with a real account and phone",
        "input": "none",
        "kind": "claim",
        "outcome": "Prerequisites missing in this disposable guest: no Cloudflare account, no Workers Paid plan, no phone to scan the WhatsApp QR code. Node 22 was installed and npm install succeeded; the deploy step (npm run deploy / wrangler deploy) was not run.",
        "source": "You need a Cloudflare account on the Workers Paid plan (see the note below), Node 20 or later, and your phone.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "blocked"
      },
      {
        "claim": "Read tools top up from WhatsApp when the stored copy is older than ten minutes",
        "command": "",
        "evidence": "Needs a linked WhatsApp account and an authenticated MCP session; both require a phone scan and a Cloudflare deployment, neither available here.",
        "expected": "a read tool returns messages after a pull",
        "input": "none",
        "kind": "claim",
        "outcome": "Needs a linked WhatsApp account and an authenticated MCP session; both require a phone scan and a Cloudflare deployment, neither available here.",
        "source": "Every read tool first tops up from WhatsApp if the stored copy is more than ten minutes old.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "blocked"
      }
    ],
    "cycle_checks": [
      {
        "claim": "Daily pull of WhatsApp messages at 04:00 UTC",
        "command": "",
        "evidence": "Missing prerequisite: the account must be linked to WhatsApp before the cron pulls anything; no Cloudflare deployment and no phone here.",
        "expected": "a daily pull of stored messages",
        "input": "none",
        "kind": "cycle",
        "method": "not run: the scheduled() handler in src/index.ts only pulls when isPaired() is true, and this guest has no paired account; wrangler dev's local scheduled endpoint would be the substitute",
        "outcome": "Missing prerequisite: the account must be linked to WhatsApp before the cron pulls anything; no Cloudflare deployment and no phone here.",
        "schedule": "cron 0 4 * * * (04:00 UTC daily)",
        "source": "wrangler.jsonc",
        "verdict": "blocked"
      }
    ],
    "details": {
      "checks": [
        {
          "check": "credentials_error",
          "details": {
            "argv": [
              "npm",
              "run",
              "dev",
              "--",
              "--port",
              "8787",
              "--ip",
              "127.0.0.1"
            ],
            "credentials_error": "Remote MCP authentication required (HTTP 401)",
            "hosting": "local",
            "kind": "mcp_http",
            "needs_credentials": true,
            "scope": "local MCP initialize + tools/list",
            "transport": "streamable-http",
            "url": "http://127.0.0.1:8787/mcp",
            "working": false
          },
          "optional": false,
          "status": "PASS"
        }
      ],
      "scope": "partial checks",
      "working": false
    },
    "evidence_strength": "nothing_checked",
    "example_checks": [
      {
        "claim": "The repo's own offline test suite passes",
        "command": "npm test",
        "deferred": false,
        "evidence": " comes first\nok   last thing THEY said, not me\nok   unnamed count\nok   save reports saved and which have chats\nok   named chat leaves the unnamed list\nok   new name shows in chat list\nok   sender name used in messages\nok   empty name removes it\nok   group message sender resolves to custom name\nok   toJid(\"+972 52-421-9320\", undefined)\nok   toJid(\"052-421-9320\", 972)\nok   toJid(\"052-421-9320\", undefined)\nok   toJid(\"00972524219320\", undefined)\nok   toJid(\"524219320\", 972)\nok   toJid(\"<email>\", undefined)\nok   toJid(\"abc\", 972)\nok   toJid(\"+1 (818) 917-7834\", 972)\n\nall passed",
        "expected": "all tests pass",
        "input": "none",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "package.json scripts.test",
        "verdict": "yes"
      }
    ],
    "status": "PASS"
  },
  "deviations": [
    "apt nodejs 18.19 failed the Baileys and wrangler engine checks; installed Node 22.23.4 with npm i -g n",
    "README has no local run instructions; used package.json script 'npm run dev' (wrangler dev) on 127.0.0.1:8787 for local checks",
    "Local OAuth attempt: wrote a random OWNER_PASSWORD to .dev.vars (wrangler local secret file, deleted afterwards), registered an OAuth client and started the consent flow; my helper's regex did not match the consent link, so I stopped there. The token path is gated on WhatsApp pairing per src/index.ts proceed() (read from source, not observed).",
    "No browser used; no external services contacted except the local dev server."
  ],
  "fault_owner": "prerequisite",
  "main_blocker": "No Cloudflare account and no phone for the WhatsApp QR link in this disposable guest.",
  "operation": "Run the whatsapp-mcp server and have an MCP client read WhatsApp messages through its tools",
  "operation_scope": "Local guest only. Needs a Cloudflare account on the Workers Paid plan for deployment, and a real phone to scan the WhatsApp linking QR code. Nothing was deployed or linked.",
  "outcome": "needs_credentials",
  "plain_failure": "The server can only be used after it is deployed to a Cloudflare account and linked to a real WhatsApp phone. This guest has neither, so I could run the code locally and confirm it refuses unauthenticated requests, but I could not read any messages.",
  "steps": [
    "Install Node 20+ (Ubuntu apt nodejs is 18; installed Node 22 via npm i -g n && n 22)",
    "npm install (includes scripts/vendor-bridge.mjs, postinstall: OK)",
    "npm test (offline suite: all passed)",
    "npm run typecheck (tsc --noEmit: OK)",
    "npx wrangler kv namespace create OAUTH_KV (not run: needs Cloudflare login)",
    "npx wrangler secret put OWNER_PASSWORD (not run: needs Cloudflare login)",
    "npm run deploy (not run: needs Cloudflare account)",
    "Open deployed /, link WhatsApp by QR (not run: needs phone)",
    "claude mcp add --transport http whatsapp <url>/mcp (not run: no deployed URL)"
  ],
  "stuck_step": "Deploy to Cloudflare and link WhatsApp (README 'Set it up', steps 1-3 and 'Link WhatsApp')",
  "suggested_fix": "Document a local development path in the README (npm run dev plus a .dev.vars password) and state clearly that the MCP token is only issued after the WhatsApp phone link is complete. Otherwise the local run can't reach any tool."
}
