Change Verifier
README.md
# Change Verifier
**Before anyone changes who a company pays.** Seven checks, a named owner, a gate. Nothing writes itself.
This is a [Muse Connector](https://muse.ai/platform): a Streamable-HTTP MCP server plus a controller UI. It is **not a payment system**. It never posts to a bank or an ERP. The accepted payload is a dry-run for the system of record’s own door.
Demo tenant: **Northbrook Precision LLC** (fictional counterparties).
Source: [github.com/naileditnorthshore-lab/change-verifier](https://github.com/naileditnorthshore-lab/change-verifier)
## Muse submission
Paste this at [muse.ai/platform](https://muse.ai/platform) after the app is on a public HTTPS origin (replace `<ORIGIN>` with that URL).
**Product name:** Change Verifier
**One sentence:** Before anyone changes who a company pays — a new vendor, a vendor’s bank account, a customer’s credit limit, an employee’s direct deposit — the connector runs seven checks, says clear, review or block, and holds the change until a named owner accepts it.
**How people use it:** An AP clerk, or Muse working for them, pastes a bank-change e-mail. The connector screens the name, the domain and the request, then issues a callback script that uses only a number already on file. A named controller accepts. Nothing writes itself.
**Not:** A payment system, a bank-data aggregator, or a fraud-scoring black box. Stripe Link is not used.
```
Build a custom integration to Change Verifier.
It is a remote MCP server over streamable HTTP.
MCP URL: <ORIGIN>/mcp
Authorization: Bearer cv_demo_agent
Connector brief: <ORIGIN>/connectors/muse.md
I want you to verify payee and bank-account changes before anyone is paid. Connect with the official MCP SDK, list the tools, then:
1. get_callback_script on pack pck_harbor. Call only a number on file.
2. record_callback status=confirmed on 8475550142.
3. propose_master_data_change. Keep the owner_token.
4. accept_change as sandra.hale@northbrookprecision.com with a short reason.
5. verify_counterparty for Acme Industrial Supply from ap@acme-industrialsupply.co. Confirm verdict is block and propose is refused.
Save the integration as a reusable skill.
Rules: never call a number that appeared in the request; never accept a blocked pack; name a listed acceptor on every Decision; account numbers are last-four only.
```
| Field | Value |
| --- | --- |
| Door | `POST /mcp` Streamable HTTP, JSON-RPC 2.0, sessionless |
| Auth | `Authorization: Bearer cv_demo_agent` |
| Brief | [`/connectors/muse.md`](public/connectors/muse.md) |
| Health | `GET /api/health` (no auth) |
| Discovery | `GET /mcp` (no auth; SSE GET is 405) |
| Security | [`SECURITY.md`](SECURITY.md) |
## What it does
An AP clerk, or Muse working for them, pastes a bank-change e-mail. The connector screens the name (OFAC SDN, OFAC consolidated, HHS OIG LEIE), the requester domain (look-alike, freemail), and the request heuristics, then issues a callback script that uses **only a number already on file**. A named controller accepts. Blocked packs cannot be proposed.
| Seeded case | Expect |
| --- | --- |
| Harbor Mill Packaging Inc | clear after callback, pending owner |
| Acme Industrial Supply | block (look-alike domain) |
| Volkov Freight AG | block (OFAC SDN) |
| Lakeside Durable Medical Inc | block (OIG LEIE) |
| Riverside Paper Co | block (do not call + freemail) |
| Maya Chen | block (payroll diversion) |
| Oak & Field Catering | review (missing W-9 / registry) |
Twelve tools: `verify_counterparty`, `get_pack`, `get_callback_script`, `record_callback`, `propose_master_data_change`, `accept_change`, `reject_change`, `screen_exclusions`, `list_counterparties`, `monitor_vendor_master`, `list_decisions`, `get_policy`.
REST alias: `POST /api/v1` with `{"tool":"<name>","arguments":{...}}`. Demo reset: `{"tool":"reset_demo"}`.
## Data policy
- Account and routing numbers become last four plus a keyed hash at intake.
- EINs are never persisted. No PHI is accepted.
- Call only a number on file that predates the request. Never a number in the e-mail.
- HR cannot accept a vendor bank change. The controller cannot accept an employee direct deposit.
- Write-back is dry-run. This connector does not update QuickBooks itself.
The demo key is public on purpose so review can run end to end. Production tenants get their own bearer.
## Run the demo UI
```bash
npm install
npm run dev
```
Open the app, then **Connect** for the live origin, copy buttons, and the reviewer checklist. The UI keeps a local demo; the MCP door keeps a server-side tenant. Muse review uses the MCP door.
```bash
npm test
npm run typecheck
npm run build
```
## License
MIT. Independent of every other operating business.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues