nod-mcp-server
by opennod
README.md
# nod-mcp-server
This is how AI agents will interact with businesses — not by scraping, but by reading structured manifests. This reference MCP server teaches any MCP-compatible client (Claude Desktop, agent frameworks, IDEs) to read a business's [`nod.json`](https://opennod.ai/protocol) manifest at `https://{domain}/.well-known/nod.json` and answer real questions about what the business can do: order food, book an appointment, search products, check pricing, and more.
It exposes two tools — `lookup_nod` and `check_capability` — and bundles four demo manifests served locally so the demo works out of the box with zero external dependencies.
## Install
```bash
git clone <this repo> nod-mcp-server
cd nod-mcp-server
npm install
npm run build
```
Requires Node.js 20+.
## Run the demo manifest server
Almost no real sites publish `nod.json` yet, so this repo bundles four example manifests (restaurant, e-commerce, SaaS, healthcare) and serves them locally.
```bash
npm run demo:manifests
```
You should see:
```
NOD demo manifest server listening on http://localhost:3456
http://localhost:3456/demo-restaurant.localhost/nod.json
http://localhost:3456/demo-shop.localhost/nod.json
http://localhost:3456/demo-saas.localhost/nod.json
http://localhost:3456/demo-health.localhost/nod.json
```
Leave this terminal running during the demo. The MCP server automatically routes any `*.localhost` domain to this server.
## Configure Claude Desktop
Open (or create) `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS (or `%APPDATA%\Claude\claude_desktop_config.json` on Windows) and add:
```json
{
"mcpServers": {
"nod": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/nod-mcp-server/dist/index.js"]
}
}
}
```
Replace `/ABSOLUTE/PATH/TO/nod-mcp-server` with the full path to this checkout on your machine (e.g. `<your-home>/projects/nod-mcp-server`). Restart Claude Desktop. You should now see the `nod` server listed in Claude's tool picker with two tools: `lookup_nod` and `check_capability`.
## 60-second demo script
With the demo manifest server running in one terminal and Claude Desktop configured, paste these prompts into Claude one after another.
### 1. "Look up the NOD manifest for demo-restaurant.localhost"
Claude calls `lookup_nod({ domain: "demo-restaurant.localhost" })` and returns something like:
```
# Pike Place Noodle House (restaurant)
Hand-pulled noodles, dumplings, and regional Chinese classics...
- URL: https://demo-restaurant.localhost
- Manifest: http://localhost:3456/demo-restaurant.localhost/nod.json
## Declared capabilities
- purchase
- booking
- view_menu
- order_food
- book_table
## Supported actions
- purchase → https://demo-restaurant.localhost/api/orders [auth: api_key]
- booking → https://demo-restaurant.localhost/api/reservations [auth: api_key]
- search → https://demo-restaurant.localhost/api/menu/search [auth: none]
```
### 2. "Can I order food from demo-restaurant.localhost?"
Claude calls `check_capability({ domain: "demo-restaurant.localhost", action: "order_food" })`:
```
YES — demo-restaurant.localhost supports "order_food".
Manifest declares "order_food" under discovery.mcp_server.capabilities.
Endpoint: POST https://demo-restaurant.localhost/api/orders
Authentication: api_key
Matched via: discovery.mcp_server.capabilities
Constraints:
{ "require_human_confirmation": { "purchases_above": 150, ... },
"rate_limits": { "transactions": { "requests": 10, "period": "minute" } },
"allow_automated_purchases": true }
```
### 3. "What actions does demo-shop.localhost support?"
Claude calls `lookup_nod({ domain: "demo-shop.localhost" })` and summarizes: product search, pricing, inventory checks, and OAuth2-protected order placement — with a human-confirmation threshold at $500 and a 60-day returns policy.
### Bonus prompts
- `"Book an appointment at demo-health.localhost — what does that flow require?"` → returns the booking endpoint, required fields (patient_name, DOB, reason, provider_id, preferred_date), OAuth2 scopes, and the cancellation policy.
- `"Does demo-saas.localhost allow automated purchases?"` → returns NO with the human-fallback URL, because the manifest sets `allow_automated_purchases: false`.
## Tool reference
### `lookup_nod`
| Input | Type | Description |
|-------|------|-------------|
| `domain` | string | Domain only (no scheme, no path). `*.localhost` domains are routed to the bundled demo server. |
Fetches `https://{domain}/.well-known/nod.json`, falling back to `https://{domain}/nod.json`. Returns a structured summary: business identity, declared capabilities, supported actions (with endpoints + auth), API endpoints, and contact methods. Returns a clear "no manifest found" message on failure.
### `check_capability`
| Input | Type | Description |
|-------|------|-------------|
| `domain` | string | Domain only. |
| `action` | string | Common values: `order_food`, `place_order`, `view_menu`, `book_table`, `book_appointment`, `search_products`, `find_provider`, `get_pricing`, `check_inventory`, `check_status`, `create_account`, `get_docs`, `contact_support`. |
Fetches the manifest and checks the action against `transactions.capabilities`, `discovery.mcp_server.capabilities`, `support.contact.mcp_server.capabilities`, and the structural endpoints (`transactions.purchase`, `discovery.search`, `information.pricing`, etc.). Returns a yes/no verdict, the endpoint URL, authentication method, and policy constraints (rate limits, human-confirmation thresholds).
## How `*.localhost` routing works
When the MCP server receives a domain ending in `.localhost`, it fetches from `http://localhost:3456/{domain}/nod.json` instead of the normal well-known URL. This makes the demo self-contained — you can point Claude at `demo-restaurant.localhost` and get real results without any DNS or HTTPS setup.
Env vars:
- `NOD_LOCAL_PORT` — port the demo manifest server listens on (default `3456`)
- `NOD_LOCAL_MANIFEST_SERVER` — base URL the MCP server uses for `.localhost` lookups (default `http://localhost:3456`)
- `NOD_FORCE_LOCAL=1` — route *every* domain through the local manifest server (useful for contributors testing new example manifests)
## What's next
Publish a `nod.json` for your own business using the NOD Protocol spec at [opennod.ai/protocol](https://opennod.ai/protocol). A minimal, valid manifest takes about 30 minutes to write — and once it's live at `https://yourdomain.com/.well-known/nod.json`, any agent using this MCP server (or any other NOD-aware client) will be able to discover your business and act on its capabilities.
## License
MIT
TDQS
A3.9/5.0
Scored across 2 tools
Disambiguation5/5
Both tools deal with NOD manifests but have distinct purposes: lookup_nod retrieves the full manifest and check_capability queries a specific action. No overlap.
Naming Consistency5/5
Both tool names follow a consistent verb_noun pattern with underscore_case: check_capability and lookup_nod.
Tool Count4/5
Two tools is appropriate for a focused purpose. While minimal, they cover the core operations for querying NOD manifests without unnecessary complexity.
Completeness4/5
The tools cover the main operations: retrieving the manifest and checking a specific capability. Missing tools for writing or updating manifests, but that seems out of scope.
Maintenance
ActivityInactive
ResponsivenessNo issues