@gera-services/mcp-gera-verify 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # Gera Verify MCP Server — "Proof-of-Real"
2
+
3
+ [![A Gera Systems product](https://img.shields.io/badge/Gera-Systems-0a7?style=flat)](https://gera.services)
4
+
5
+ An [MCP](https://modelcontextprotocol.io) server that lets any AI agent — Claude
6
+ Desktop, ChatGPT with tools, Cursor, Windsurf, or any MCP client — answer
7
+ **"is this real / how trustworthy is this?"** about a UK business, food
8
+ establishment, or care provider, grounded in **real verified data Gera already
9
+ owns**.
10
+
11
+ It is seeded with first- and third-party verified datasets that Gera already
12
+ renders on its products:
13
+
14
+ | Signal | Source | Records (this snapshot) |
15
+ |---|---|---|
16
+ | Food-hygiene ratings | **FSA Food Hygiene Rating Scheme (FHRS/FHIS)** — as used by [GeraEats](https://geraeats.com) | 10,266 establishments |
17
+ | Care-provider registry | **CQC** (Care Quality Commission) — as used by [GeraClinic](https://geraclinic.com) | 5,411 providers |
18
+ | Verified providers | **Gera's own crawled verified-provider set** | 25 providers |
19
+ | Public doctor listings | Practo public profiles | 406 doctors |
20
+
21
+ **Everything is offline.** The data is a committed on-disk snapshot, so the
22
+ server gives the same verified answer the Gera products give and runs anywhere
23
+ with **no backend, no network, no auth**.
24
+
25
+ > **Honesty contract.** Every signal is source-attributed with an as-of date.
26
+ > When a subject is **not** in our records, the tools say so plainly
27
+ > (`not_in_our_records`) — they **never invent** a rating or status. Signals we
28
+ > do not hold (e.g. CQC's categorical overall rating) are returned as
29
+ > `"unknown"`, never guessed.
30
+
31
+ ## Tools
32
+
33
+ | Tool | What it does |
34
+ |------|--------------|
35
+ | `check_business_trust` | **Flagship.** Given a business name (+ optional city/postcode/type), returns *every* real verified signal Gera holds — FSA hygiene rating, CQC registration, Gera verified-provider presence — each source-attributed. Returns `overall_verification` = `verified` or `not_in_our_records`. |
36
+ | `lookup_food_hygiene` | Real FSA food-hygiene rating for a UK food business: FHRS 0–5 (England/Wales/NI) or FHIS Pass/Improvement-Required (Scotland), with establishment, business type, local authority, and rating date. |
37
+ | `lookup_care_rating` | Confirms a UK care/health provider is in the **CQC** registry; returns registered name, address, service types, last-inspection date, region, and a link to the live CQC profile. CQC's overall rating is **categorical** (Outstanding/Good/Requires improvement/Inadequate) and not in this snapshot, so it is honestly returned as `unknown` with a live link. |
38
+ | `verify_provider` | Checks Gera's own crawled **verified-provider / Passport** set; returns type, specialty, location, website, crawl source + date. |
39
+ | `get_trust_summary` | Aggregates the above into a short, **citation-ready sentence** (plus structured signals) for an agent to quote a grounded "what we can verify about X" answer. |
40
+ | `issue_attestation` | **Gera Vouch.** Runs the same real verification and returns a **cryptographically signed (Ed25519) attestation receipt** an agent can present to a counterparty (who verifies it with the public key). Verdict is `pass` (a strong, source-attributed verifying signal exists) or `unverified` (not in our records — never a guess). A signed *proof-of-diligence receipt*; indemnity/underwriting is roadmap and is never implied. |
41
+ | `get_vouch_public_key` | Returns the Ed25519 public key + `key_id` + verification recipe so **any party can independently verify** an `issue_attestation` receipt without trusting the transport. |
42
+
43
+ A typical agent flow: `check_business_trust` (or `get_trust_summary`) → drill
44
+ into `lookup_food_hygiene` / `lookup_care_rating` / `verify_provider` for the
45
+ source-attributed detail behind any signal → `issue_attestation` to get a
46
+ **signed receipt** before the agent acts (book / pay / recommend).
47
+
48
+ ### Gera Vouch — signed attestations (the agent trust layer)
49
+
50
+ `issue_attestation` is the keystone of [Gera Labs](https://gera.services/labs)'
51
+ agent-trust spine: AI agents can't be liable, so before an agent takes a
52
+ real-world action it calls Vouch for a signed verdict it (and the counterparty)
53
+ can verify. The signature covers the canonical (sorted-key UTF-8) JSON of the
54
+ `attestation` object; verify with the key from `get_vouch_public_key`. Set
55
+ `GERA_VOUCH_SEED` (base64, 32+ bytes) in production; without it a deterministic,
56
+ stable **dev** key is used so signatures verify out-of-the-box (`is_production_key`
57
+ flags which). Vouch only attests a `pass` on a **strong** name match (the record
58
+ name contains the full query), stricter than the read-only lookup tools.
59
+
60
+ ## Install & run
61
+
62
+ ```bash
63
+ # Run directly (no global install) once published to npm:
64
+ npx -y @gera-services/mcp-gera-verify
65
+
66
+ # Or from this repo:
67
+ cd packages/mcp-gera-verify
68
+ npm run build:data # extract the real on-disk datasets -> src/data/*.json (committed)
69
+ npm run build # tsc --noCheck -> dist/ + copy datasets to dist/data
70
+ node bin/cli.js # starts on stdio
71
+ ```
72
+
73
+ > The datasets are committed (`src/data/*.json`), so you only need
74
+ > `npm run build:data` if you want to re-snapshot from the latest
75
+ > `apps/*/src/data/*.generated.ts` sources.
76
+
77
+ ## Client configuration
78
+
79
+ ### Claude Desktop / Claude Code (`claude_desktop_config.json`)
80
+
81
+ ```json
82
+ {
83
+ "mcpServers": {
84
+ "gera-verify": {
85
+ "command": "npx",
86
+ "args": ["-y", "@gera-services/mcp-gera-verify"]
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ Local (unpublished) variant — point at the built CLI:
93
+
94
+ ```json
95
+ {
96
+ "mcpServers": {
97
+ "gera-verify": {
98
+ "command": "node",
99
+ "args": ["/Users/armen/Gera/packages/mcp-gera-verify/bin/cli.js"]
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Cursor / Windsurf (`.cursor/mcp.json` etc.)
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "gera-verify": {
111
+ "command": "npx",
112
+ "args": ["-y", "@gera-services/mcp-gera-verify"]
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## Hosted transport (Streamable HTTP / SSE — for ChatGPT Apps & remote MCP clients)
119
+
120
+ **Live now:** `https://gera-verify-mcp-production.up.railway.app/mcp`
121
+ (POST JSON-RPC, `Accept: application/json, text/event-stream`; `GET /health` →
122
+ `ok`). All 7 tools — including the signed `issue_attestation` (Gera Vouch) — are
123
+ callable over HTTP today, no install. A branded `verify-mcp.gera.services`
124
+ domain is next.
125
+
126
+ The same seven tools are served over the MCP **Streamable HTTP** transport, so
127
+ remote MCP clients and **ChatGPT Apps** can connect to a public URL instead of
128
+ spawning a local stdio process. The HTTP server reuses the exact same tool
129
+ handlers — it just swaps the transport.
130
+
131
+ ```bash
132
+ cd packages/mcp-gera-verify
133
+ npm run build # tsc --noCheck -> dist/ (builds both transports)
134
+ npm run start:http # or: node bin/http.js
135
+ # -> listening on http://0.0.0.0:3400/mcp (POST JSON-RPC; GET /health)
136
+ ```
137
+
138
+ Endpoints:
139
+
140
+ | Method & path | Purpose |
141
+ |---|---|
142
+ | `POST /mcp` | MCP JSON-RPC (and SSE streaming). This is the MCP endpoint clients connect to. |
143
+ | `GET /health` | Plain-text liveness probe (`ok`) — exempt, never gated. |
144
+ | `GET /mcp` | `405` — stateless mode has no server-initiated stream to open. |
145
+
146
+ It runs **stateless** (a fresh server per request, no session id) — correct for
147
+ a read-only, offline lookup service with no cross-call state, and safe to host
148
+ behind a serverless function or a horizontally-scaled container.
149
+
150
+ Configure host/port via env vars: `PORT` (or `MCP_HTTP_PORT`, default `3400`)
151
+ and `HOST` (default `0.0.0.0`).
152
+
153
+ ### Connecting a remote MCP client
154
+
155
+ ```json
156
+ {
157
+ "mcpServers": {
158
+ "gera-verify": {
159
+ "type": "streamable-http",
160
+ "url": "https://verify.gera.services/mcp"
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ For **ChatGPT Apps** / remote-MCP connectors, register the same
167
+ `https://verify.gera.services/mcp` URL as the server endpoint. No auth is
168
+ required — the lookups are read-only and offline.
169
+
170
+ > Quick check once running:
171
+ > `curl -s http://localhost:3400/health` → `ok`
172
+ > `curl -s -X POST http://localhost:3400/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'`
173
+
174
+ ## Verify it works
175
+
176
+ ```bash
177
+ npm run build
178
+ node scripts/smoke.mjs
179
+ ```
180
+
181
+ The smoke test speaks raw MCP JSON-RPC over stdio (`initialize` → `tools/list`
182
+ → several `tools/call` against **real** records) and asserts the responses,
183
+ including the honesty checks (a fake business → `not_in_our_records`; CQC
184
+ categorical rating → `unknown`, never invented). Expected output ends with
185
+ `ALL SMOKE CHECKS PASSED`.
186
+
187
+ ## Example
188
+
189
+ Ask your agent: *"Is Etci Mehmet Steak House in Birmingham a real, hygienic
190
+ restaurant?"*
191
+
192
+ The agent calls `check_business_trust` / `lookup_food_hygiene` and gets back:
193
+
194
+ ```json
195
+ {
196
+ "found": true,
197
+ "best_match": {
198
+ "establishment": "Etci Mehmet Steak House",
199
+ "address": "Unit 16, Star City, Watson Road, Birmingham",
200
+ "postcode": "B7 5SA",
201
+ "businessType": "Restaurant/Cafe/Canteen",
202
+ "localAuthority": "Birmingham",
203
+ "scheme": "FHRS",
204
+ "rating": 5,
205
+ "rating_date": "2026-05-29",
206
+ "source": "Source: FSA Food Hygiene Rating Scheme, local authority \"Birmingham\", as of 2026-06-12."
207
+ }
208
+ }
209
+ ```
210
+
211
+ ## Data & attribution
212
+
213
+ - **FSA FHRS/FHIS** — Contains public sector information licensed under the Open
214
+ Government Licence v3.0. <https://ratings.food.gov.uk>
215
+ - **CQC** — Source: Care Quality Commission www.cqc.org.uk. Licensed under the
216
+ Open Government Licence v3.0.
217
+ - **Gera verified-provider set** — Gera's own supplier crawler.
218
+ - **Doctor listings** — public Practo professional profiles.
219
+
220
+ Snapshots are extracted by `scripts/build-data.mjs` from the same on-disk
221
+ `*.generated.ts` files that GeraEats and GeraClinic render — no data is
222
+ invented; every record traces to a source row.
223
+
224
+ ## License
225
+
226
+ MIT © Gera Systems Ltd
package/bin/cli.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for the Gera Verify MCP server.
4
+ * Starts the server on stdio. Intended to be launched by an MCP client
5
+ * (Claude Desktop, ChatGPT-with-tools, Cursor, etc.) — not run interactively.
6
+ */
7
+ import { main } from '../dist/server.js';
8
+
9
+ main().catch((err) => {
10
+ console.error('Fatal:', err);
11
+ process.exit(1);
12
+ });
package/bin/http.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for the HOSTED Gera Verify MCP server.
4
+ * Starts the Streamable HTTP / SSE transport so remote MCP clients and
5
+ * ChatGPT Apps can connect over HTTP. Listens on PORT (default 3400) at /mcp.
6
+ */
7
+ import { main } from '../dist/http.js';
8
+
9
+ main().catch((err) => {
10
+ console.error('Fatal:', err);
11
+ process.exit(1);
12
+ });