Skip to main content
Glama
README.md
# AINumbers MCP Apps Server

[![CI](https://github.com/PostOakLabs/ainumbers-mcp-apps/actions/workflows/ci.yml/badge.svg)](https://github.com/PostOakLabs/ainumbers-mcp-apps/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

An agent calling a fintech tool by name has no way to know if the tool actually ran the math it claims to have run. This server closes that gap for the AINumbers.co suite: every tool call is deterministic, zero PII, and served straight from the suite's own single-file HTML, not a paraphrase of it.

An [MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) (SEP-1865) server that exposes the [AINumbers.co](https://ainumbers.co) fintech tool suite to any MCP host, including Claude, ChatGPT, M365 Copilot, VS Code, and Cursor.

![baas_provider_comparator, one of the flagship widget tools, the same HTML MCP Apps hosts render inline in chat](docs/mcp-widget-demo.gif)

## Quick start

```bash
# Claude: Settings -> Connectors -> Add custom connector
https://mcp.ainumbers.co/mcp

# Inspector
npx @modelcontextprotocol/inspector   # then Streamable HTTP -> the URL above
```

No auth, no API key, no account. Production runs on Cloudflare Workers (`/healthz` reports `runtime: cloudflare-workers`), so there are no cold starts. Cursor and other Open Plugins directories pick this repo up automatically via the root `.mcp.json`, which declares the same endpoint.

**Live endpoint:** `https://mcp.ainumbers.co/mcp` (streamable HTTP) · **Docs:** [ainumbers.co/mcp.html](https://ainumbers.co/mcp.html) · **Registry:** [`co.ainumbers/tools`](https://registry.modelcontextprotocol.io/v0.1/servers?search=co.ainumbers) on the Official MCP Registry

## Run your own (org-hosted)

[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/PostOakLabs/ainumbers-mcp-apps)

Fork this repo and deploy the button above to run the same server inside your own Cloudflare account: no auth to add, no build step at deploy time, the Worker boots straight from the `data/` and `kernels/` already committed here.

Two edits to `wrangler.jsonc` before that first deploy will succeed on a fresh account:

- **`routes`** points at `mcp.ainumbers.co`, a zone this fork doesn't own. Rename `name` and either delete `routes` (ship on the free `workers.dev` subdomain) or point it at a zone in your own account.
- **`queues` / `workflows`** feed an internal analytics loop and are guarded in code (`if (env.EVENTS_QUEUE)`, `if (env.RENEWAL_WATCH_WORKFLOW)`) — the MCP handshake and every tool call work without them. Queues need a Workers Paid plan; drop both blocks to stay free-tier.

Everything else, including the `ASSETS` binding serving the committed tool data, works unmodified. Full write-up (WAF rate-limit recipe, re-vendor cadence, conformance-attestation offer): [ainumbers.co/mcp.html#deploy-your-own](https://ainumbers.co/mcp.html#deploy-your-own).

## Tools

**Read-only MCP tools** — count intentionally not hardcoded here (it drifted stale the last time it was). See `data/counts.json` for the live figure; never hand-type this number, `scripts/surface-parity.mjs` and the site repo's count-drift gate both check against it. The flagship widgets below render as interactive widgets, the rest are ChainGraph compute nodes plus a handful of catalog and discovery utility tools: `list_ainumbers_tools`, `find_tool`, `find_chain`, `build_workflow_links`, `run_chain`, `verify_execution_hash`, `build_chaingraph`, `emit_chaingraph_artifact`, `build_session_receipt`.

Every tool declares `readOnlyHint: true`. No account, no auth, zero PII, nothing mutates state.

### The flagship widgets

Each renders as the actual single-file AINumbers tool, served as a `text/html;profile=mcp-app` resource and driven by the AIN Bridge (prefill, run, Policy Mandate export). This table IS the enumeration — its row count is the widget count, never a number typed elsewhere:

| MCP tool | AINumbers tool |
|---|---|
| `baas_provider_comparator` | T152 BaaS Provider Comparator |
| `validate_ap2_mcp_policy` | T320 AP2 MCP Policy Validator & Bridge |
| `build_google_ap2_mandate` | T285 Google AP2 Checkout/Payment Mandate Builder |
| `score_mcp_readiness` | T288 MCP Developer Readiness Scorecard |
| `agentic_mandate_sandbox` | RBE-06 Agentic Mandate Sandbox |
| `customer_risk_rating` | T110 Customer Risk Rating Engine |
| `ap2_aml_mandate_builder` | T131 AP2 AML Mandate Builder |
| `lint_mcp_tool_definition` | T274 MCP Tool-Definition Linter |
| `validate_mcp_server_json` | T275 MCP server.json Validator |
| `compare_agentic_payment_protocols` | T276 Agentic Payments Protocol Comparator |
| `decode_x402_payment` | T277 x402 Decoder & 402 Flow Simulator |
| `audit_mcp_oauth` | T278 MCP OAuth 2.1 Authorization Auditor |
| `scan_tool_poisoning` | T282 MCP Tool-Poisoning Scanner |
| `validate_a2a_agent_card` | T283 A2A Agent Card Validator |
| `inspect_visa_tap_signature` | T286 Visa TAP Signature Inspector |
| `run_kernel_vm` | Kernel VM Widget |

`list_ainumbers_tools` and `find_tool` search the full catalog (see `data/counts.json` for the current tool count) and return deep-links. Prefill-enabled tools accept `#in=<base64url(JSON of {element_id: value})>[&run=1]` for one-click invocation. `find_chain` and `build_workflow_links` return ordered deep-links for a named multi-tool workflow. `run_chain` executes one server-side; each run returns an OpenTelemetry span document as a resource link (one `execute_tool` span per executed step under an `invoke_agent` parent). `verify_execution_hash` independently re-verifies a returned artifact's hash.

## Architecture

```
../repo (site repo, PostOakLabs/ainumbers)
   |  chaingraph.json, manifests/, pilot.mjs-referenced tool HTML
   |
   v  node generate.mjs (build-time only, cannot run in cloud CI, needs the sibling repo)
data/       vendored: chaingraph.json, catalog.json, manifests, counts.json
kernels/    vendored: server-side compute kernels
   |
   v
worker.mjs  (Cloudflare Workers, this repo's live runtime)
server.mjs  (Node/express variant, local dev only, not deployed)
   |
   v
https://mcp.ainumbers.co/mcp   (the one live endpoint: the Worker, not the express variant)
```

`data/` and `kernels/` are generated, committed artifacts. The Worker boots from what's committed, not from a live read of `../repo`. Any change to `chaingraph.json`, a manifest, `pilot.mjs`, or a kernel in the site repo requires re-running `generate.mjs` here and committing `data/` and `kernels/` in the same push, or the worker deploys stale.

## Deploy flow (CI-owned)

Branch, then PR. CI runs the `validate` job: tool-name collisions, surface-parity, kernel coverage, chain validation, vendor-freshness, and a `wrangler deploy --dry-run`. Merging to `master` runs the `deploy` job, which runs `wrangler deploy` against Cloudflare Workers, then a post-deploy `/mcp` smoke test (a real `initialize` call against the live endpoint). No manual `wrangler deploy`, ever: Cloudflare Workers Builds stays disconnected on purpose, since running both is a double-deployer and has caused outages before. A green CI bundle does not by itself prove the live handshake works; only the smoke step does.

Dependabot auto-merges every dependency update (patch, minor, and major, all CI-gated), so run `git pull --rebase` before pushing any local branch since `master` moves on its own.

## Independent monitoring

[![MCP Queen grade](https://mcpqueen.com/badge/co.ainumbers/tools.svg)](https://mcpqueen.com/s/co.ainumbers/tools)

[MCP Queen](https://mcpqueen.com) is a third-party operational probe: it continuously re-checks the live `/mcp` endpoint's protocol handshake and tool-schema responses and grades what it observes. This is not a security or compliance attestation, ours or theirs — it describes observable server behavior only.

## Develop

```bash
npm install
node generate.mjs   # re-vendor tool HTML + manifests + catalog + kernels from ../repo into data/ + kernels/
npm start           # http://localhost:3300/mcp (+ /healthz), Node/express variant (server.mjs), local dev only
node scripts/check-tool-names.mjs   # verify no mcp_name collision before pushing
node scripts/surface-parity.mjs     # verify counts.json matches the registered surface
```

`pilot.mjs` is the single source of truth for the widget tool set. After changing any pilot tool in the site repo, run `node generate.mjs`, commit `data/` and `kernels/`, and push. CI validates and deploys.

All tool content is client-side, deterministic, and zero PII. Code is MIT licensed (see `LICENSE`); content is CC BY 4.0, Post Oak Labs. See `README-SPEC.md` for architecture and history.

**Transport conformance (MCP-STREAMABLE-HTTP-CONFORMANCE-1).** The `/mcp` door is a full Streamable HTTP endpoint per the MCP spec (2025-03-26 / 2025-06-18): `initialize` issues an `Mcp-Session-Id` (echoed thereafter, never required — the server is stateless behind the scenes), `GET /mcp` with `Accept: text/event-stream` and that session id opens a server-to-client SSE stream with a 25 s keepalive that closes on disconnect (a session-less GET keeps the spec-clean `405` + `Allow` it always gave), `DELETE /mcp` with the session id ends the session with `204` (a bare DELETE stays `405`), an unknown `MCP-Protocol-Version` is a JSON-RPC `400` (never a `500`), and `tools/list` honours `params.cursor`/returns `nextCursor` (page size `TOOLS_LIST_PAGE_SIZE` in `worker.mjs` is deliberately ≥ the whole surface for one release). Verify any door — local (`node server.mjs`) or production — with the zero-dependency six-check script: `bash scripts/transport-conformance.sh [BASE_URL]`.

<!-- automerge-label.yml end-to-end proof, WORKER-VENDOR-LAND-0817-2 addendum, 2026-08-17 -->

TDQS

A3.6/5.0

Scored across 16 tools

Disambiguation4/5

Most tools have clearly distinct purposes, such as MCP validation vs. payment protocol analysis. However, there is slight overlap among AP2-related tools (ap2_aml_mandate_builder, build_google_ap2_mandate, validate_ap2_mcp_policy) and MCP validation tools (lint_mcp_tool_definition, validate_mcp_server_json, score_mcp_readiness, audit_mcp_oauth) that could cause confusion if descriptions are not carefully read.

Naming Consistency3/5

The naming convention is mixed: some tools start with a verb (e.g., 'validate_mcp_server_json', 'scan_tool_poisoning') while others start with a noun (e.g., 'agentic_mandate_sandbox', 'customer_risk_rating'). All use snake_case, which is readable, but the lack of a consistent verb_noun pattern reduces clarity.

Tool Count4/5

With 16 tools, the server covers a broad range of fintech and MCP utilities without being excessive. The count is slightly high for a single domain, but each tool serves a specific purpose and the variety is justified by the toolkit nature of the server.

Completeness3/5

The tool set covers key areas like agentic payments, AML/KYC, MCP validation, and BaaS comparison. However, there are notable gaps: for MCP, only validation tools exist without creation/management tools; for payments, comparison and decoding are present but no payment creation tools. The surface is partially complete for a general fintech toolkit.

Maintenance

ActivityActive
ResponsivenessUnresponsive