RecallDesk
README.md
# RecallDesk
RecallDesk helps a household move from a possible U.S. consumer-product recall match to a source-backed follow-up plan that can be reopened later. It keeps product-label evidence, source dates, explicit identification confirmation and user-reported progress together in a local case history.
The included web interface is our own guided conversational simulator and a real Model Context Protocol (MCP) client. It uses the official TypeScript SDK to connect to the local MCP server over Streamable HTTP, negotiating **2025-11-25**. It is not connected to an Alexa+ device or Amazon's gated developer simulator. No paid model, AWS account, external API key or paid runtime service is required.
## Run locally
Use **Node.js 24.6.0 or later** and npm. Run these commands from the directory containing this `package.json`:
```sh
npm ci
npm test
npm run build
npm start
```
Open **http://127.0.0.1:4318**. Use that exact address: the server deliberately rejects other Host/Origin values, including the `localhost` alias. The application serves the built `dist/` directory; rebuild after changing the web client.
Package installation needs internet access. Once dependencies and the web build are present, the fictional demo works offline. Live searches additionally need the public CPSC service. Node may print an experimental SQLite warning; that warning is separate from a failing test or application error.
Stop the server with Ctrl+C. Restarting rotates the local MCP bearer token and browser sessions; saved cases remain in the local SQLite database. Use **Reconnect** in an already-open page after restarting.
## Five-minute judge walkthrough
1. Choose **Try a fictional case**, then **Find possible notices**. The two notices are visibly fictional Harbor Home kettles, models `HH-200` and `HH-200S`; neither has an invented official link.
2. Enter `Harbor Home` and `HH-200` in the product-label fields, then **Save label details**. Review both notices to see why the extra `S` matters. A brand/model text match only supplies candidate evidence; it does not certify applicability.
3. Select the `HH-200` notice and **Prepare follow-up plan**. Read its source-backed steps and identification conditions. Check the explicit confirmation box, then **Confirm identification & save plan**.
4. Mark a step complete, choose your own follow-up date, and download a case packet or calendar reminder. These are local file downloads. No manufacturer is contacted, no refund claim is filed, and no calendar is changed automatically.
5. Choose **Revise fictional notice**. The fictional remedy changes, earlier confirmation/progress is invalidated, and a new review is required. **Refresh source**, reopen the saved case or reconnect to see that state persists beyond an MCP session.
The demo's source-change operation applies the change and invalidation immediately. The subsequent refresh checks that the revised source remains stable; it is not what first activates the change.
Open the collapsible **MCP inspector** to inspect the actual negotiated protocol, discovered tools and request trace. Its downloadable trace contains method/tool names, HTTP status, protocol version, timing and timestamps—not credentials, product arguments or case contents.
## What the MCP layer does
The browser calls `GET /api/session` for an HttpOnly, SameSite=Strict local cookie. It then uses the SDK's `Client` and `StreamableHTTPClientTransport` to initialize `/mcp`, discover tools and call them. The server uses the SDK's `McpServer` and `StreamableHTTPServerTransport`; the workflow is not a REST endpoint presented as MCP.
Twelve tools cover the case journey:
| Purpose | Tools |
| --- | --- |
| Start and identify | `case_start`, `case_label` |
| Find and inspect evidence | `recall_search`, `recall_review` |
| Prepare and explicitly confirm | `plan_prepare`, `plan_confirm` |
| Reopen and follow through | `case_get`, `case_list`, `case_progress`, `case_refresh` |
| Export and exercise a changed source | `case_export`, `demo_source_update` |
Independent local MCP clients can use the startup bearer token in `.runtime/auth-token`. Keep that file private. The [protocol and security notes](docs/protocol-and-security.md) include the exact bootstrap contract, a real SDK client example, tool arguments and error behavior.
## Conflicts and confirmation
All authenticated clients operate on the same single-owner case store. Mutating tools require the case version the caller reviewed. If another tab or MCP client changes a case, a stale write is rejected instead of overwriting newer evidence. An exact previously processed command can return the current case without applying it again.
After a failed or uncertain action, the web client performs read-only recovery, clears derived review and checkbox state, and displays the error. It does not automatically replay the write. A preview is bound to its case version, ID and source hash; even an unchanged-source refresh can advance the case version and require preparing the preview again.
Confirmation records the user's declaration that they checked the complete identification conditions. The server cannot inspect a physical label or prove that a human supplied the declaration. Other MCP clients must obtain that confirmation rather than invent it.
## Live CPSC mode and practical limits
Live mode makes bounded GET requests to the U.S. CPSC public recall API. It sends only the product search term or stored recall number, plus the JSON format parameter. Product-label fields remain in the local case store; the adapter does not send them as separate brand/model/serial query parameters.
The source response is limited to **25 records, 512 KiB and 12 seconds**. A broad, unavailable or malformed response is reported explicitly; it is not silently treated as an empty result. The app does not paginate past the bound or accept arbitrary source URLs.
- CPSC coverage is not worldwide product-safety clearance. No results do not mean a product is safe or unaffected.
- Brand/model token evidence is deliberately conservative. Serial, lot, date and other restrictions still require checking the full official notice.
- Live plan preparation refreshes the selected source. Confirmation checks that stored preview; it does not perform another network fetch. There is no background monitoring.
- Content changes—including fields beyond the displayed summary—can invalidate earlier confirmation even when the publication date is unchanged. Historical snapshots remain available in the case packet.
- Completed steps record user-reported follow-through, not an official recall status or a safety certification.
## Local data and release boundaries
The default `.runtime/` directory contains `cases.sqlite`, possible SQLite WAL/SHM companions and `auth-token`. The database retains product labels, optional serial notes, normalized source evidence, snapshots and events until the local owner removes or manages that data. There is no automatic retention expiry or deletion UI. Filesystem permissions protect default runtime files; the app does not encrypt the database itself.
JSON packets include case history, and ICS files contain case/product context. Treat exported files as personal data when deciding where to share them. The application never uploads these exports automatically.
This is a **single-owner loopback prototype**. Do not expose it through a public tunnel, reverse proxy or remote bind and assume the same authentication is suitable. A remote or multi-user service would need a different authentication and isolation design.
The existing `.gitignore` excludes default runtime/data directories, environment files, dependencies, builds and test output. A public source package should contain source, tests, package manifests/lockfile, build configuration and these docs. Exclude runtime credentials, databases, personal exports and source/downloaded data. Custom paths and manually copied exports need an explicit packaging review; `.gitignore` alone is not a release allowlist.
## Validation
Validation snapshot, **18 October 2026: 33 tests passing**—21 domain/source tests and 12 transport tests. Tests use fictional or injected provider responses; they do not depend on live CPSC availability.
```sh
npm test
npm run typecheck
npm run build
```
Focused transport and persistence checks:
```sh
node --test test/transport*.test.ts
```
Coverage includes exact/near model identifiers, missing identity, changed or missing source notices, hash changes without a new publication date, overlapping writes, idempotent recovery, safe exports, real SDK negotiation/list/call, browser and bearer authentication, Host/Origin rejection, request bounds, session limits, and SQLite persistence across sessions and a server restart. Passing these tests is not a claim of Alexa+ device integration or product-safety validation.
Desktop browser QA also verified a live CPSC flow with seven candidates and plan preparation, missing/near-model guards, explicit fictional confirmation, local downloads, reconnect persistence and two-client stale-write recovery. Mobile viewport verification is not claimed. The [implementation friction log](docs/friction-log.md) separates those observations from published-only constraints and controlled regression tests.
## Layout and contributing
| Path | Responsibility |
| --- | --- |
| `src/web/` | Guided web client and optional protocol inspector |
| `src/server.ts` | Loopback server, local authentication and Streamable HTTP routing |
| `src/mcp/tools.ts` | Twelve SDK tools and argument validation |
| `src/domain/` | Case state, CPSC adapter, fictional fixtures and file exports |
| `src/contract.ts` | Shared client/transport/domain types |
| `test/` | Offline domain/source tests and real local MCP transport tests |
For changes, add focused regression coverage around the behavior being changed, retain explicit demo/source distinctions, preserve version checks and never include a runtime database or credential in a patch. Run the validation commands before sharing the change.
## License
Original application code and documentation are licensed under the [MIT license](LICENSE), copyright 2026 Aashutosh Bhattad. Dependencies retain their own licenses. CPSC notices, names, links and other third-party source material are not relicensed by this repository's MIT license. The Harbor Home demo is invented test content, not a real recall or endorsement.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues