mirror of
https://github.com/Sea-Haven-Industries/sh-mcp.git
synced 2026-10-06 19:22:04 +00:00
82 lines
2.6 KiB
Markdown
82 lines
2.6 KiB
Markdown
|
|
# sh-mcp-finance
|
||
|
|
|
||
|
|
Finance-tier Sea Haven MCP server. Exposes the **finance** tool registry
|
||
|
|
(qbo `search_vendors`, payments `lookup_payment_by_*` — see `docs/design.md §3`)
|
||
|
|
over the same two interfaces as `sh-mcp-ops` (MCP Streamable HTTP + OpenAPI 3.1),
|
||
|
|
through the same shared dispatch path.
|
||
|
|
|
||
|
|
Finance is **sensitive, read-only, and fully audited**: every tool call emits a
|
||
|
|
structured audit record and the response is redacted on egress (bank account /
|
||
|
|
routing / card / SSN / tax-id masked) before it leaves the server
|
||
|
|
(`docs/design.md §2.5, §7.3`).
|
||
|
|
|
||
|
|
## Run locally (no AWS, no Cognito)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm install
|
||
|
|
npm run build
|
||
|
|
|
||
|
|
SH_MCP_ENV=local PORT=8082 npm run start -w @sh-mcp/server-finance
|
||
|
|
# or: SH_MCP_ENV=local npm run dev -w @sh-mcp/server-finance
|
||
|
|
```
|
||
|
|
|
||
|
|
### Endpoints
|
||
|
|
|
||
|
|
Identical shape to `sh-mcp-ops`: `GET /healthz`, `GET /openapi.json` (both
|
||
|
|
unauthenticated), `POST /mcp`, and `POST /tools/:name` (both authenticated).
|
||
|
|
|
||
|
|
### Dev bearer tokens (local only)
|
||
|
|
|
||
|
|
| Token | Identity | Scopes |
|
||
|
|
| ------------------- | -------------------------- | ------------------------------------------- |
|
||
|
|
| `dev-finance` | accounting@seahavenind.com | `ops:read`, `finance:read` |
|
||
|
|
| `dev-finance-admin` | adam@seahavenind.com | `ops:read`, `finance:read`, `finance:admin` |
|
||
|
|
|
||
|
|
Ops-tier tokens (`dev-ops-only`, `dev-assistant`) are **rejected** by this server
|
||
|
|
(audience binding).
|
||
|
|
|
||
|
|
### Sample curl — redaction on egress
|
||
|
|
|
||
|
|
```bash
|
||
|
|
TOKEN=dev-finance
|
||
|
|
|
||
|
|
curl -s -X POST localhost:8082/tools/lookup_payment_by_vendor \
|
||
|
|
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||
|
|
-d '{"vendor":"Harbor"}' | jq
|
||
|
|
# → bankAccountNumber / bankRoutingNumber / cardNumber are "[REDACTED]";
|
||
|
|
# vendor, amount, invoice number are intact.
|
||
|
|
```
|
||
|
|
|
||
|
|
Each call writes one structured audit line to stdout (CloudWatch in Lambda):
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"kind": "audit",
|
||
|
|
"sub": "...",
|
||
|
|
"tool": "lookup_payment_by_vendor",
|
||
|
|
"argsHash": "<sha256>",
|
||
|
|
"decision": "allow",
|
||
|
|
"result": "ok",
|
||
|
|
"ts": "..."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Args are **hashed, never logged raw** — secrets never reach the audit log.
|
||
|
|
|
||
|
|
### MCP Inspector
|
||
|
|
|
||
|
|
Point it at `http://localhost:8082/mcp` (Streamable HTTP) with
|
||
|
|
`Authorization: Bearer dev-finance`.
|
||
|
|
|
||
|
|
## Environment
|
||
|
|
|
||
|
|
Same as `sh-mcp-ops` plus `PAYMENTS_TABLE` (aws mode). Finance additionally
|
||
|
|
applies the **15-minute TTL ceiling** on `finance:*` tokens in `aws` mode
|
||
|
|
(`docs/design.md §2.5`). `aws` mode is not runtime-exercised in Phase 1.
|
||
|
|
|
||
|
|
## CDK
|
||
|
|
|
||
|
|
`cdk/app.ts` is a **synth-only** placeholder (no real IAM/Cognito/WAF) — the
|
||
|
|
finance least-privilege role and audit wiring land in a later phase behind the
|
||
|
|
mandatory IAM cross-review.
|