Skip to main content
Glama
org.agentshopping/intent-catalog

org.agentshopping/intent-catalog

README.md
# agentshopping-mcp

An MCP server that exposes the [AgentShopping](https://agentshopping.org) buyer-intent catalog to any MCP-compatible agent.

It is **read-only**. It holds no funds, places no orders, and writes nothing. It returns dated, sourced facts — and states plainly what it does *not* know.

## Two ways to use it

### 1. Remote endpoint (recommended, zero install)

```
https://agentshopping.org/mcp
```

MCP Streamable HTTP. Point any MCP client at the URL:

```json
{
  "mcpServers": {
    "agentshopping": {
      "url": "https://agentshopping.org/mcp"
    }
  }
}
```

This endpoint is listed in the **official MCP Registry**:

| Field | Value |
|---|---|
| Name | `org.agentshopping/intent-catalog` |
| Version | `0.1.1` |
| Namespace | domain reverse-DNS of `agentshopping.org` (HTTP authentication) |
| Status | `active` |
| Published | 2026-11-08T13:47:55Z |
| Source | https://github.com/wken2238-byte/agentshopping-mcp |

Verify it yourself:

```bash
curl 'https://registry.modelcontextprotocol.io/v0.1/servers?search=agentshopping'
```

### 2. Local stdio server (runs on your machine)

```bash
node src/index.js
```

```json
{
  "mcpServers": {
    "agentshopping": {
      "command": "node",
      "args": ["/absolute/path/to/agentshopping-mcp/src/index.js"]
    }
  }
}
```

> **Not on npm yet.** The `agentshopping-mcp` package name is reserved but the package has not been published to the registry, so `npm install -g agentshopping-mcp` does not work yet. Until it does, run it from a checkout as shown above.

### Pointing it at a different catalog

The stdio server reads `AGENTSHOPPING_API_BASE` if set, and falls back to `https://agentshopping.org`. Use it to run against a self-hosted or mirrored catalog:

```json
{
  "mcpServers": {
    "agentshopping": {
      "command": "node",
      "args": ["/path/to/agentshopping-mcp/src/index.js"],
      "env": { "AGENTSHOPPING_API_BASE": "https://your-mirror.example" }
    }
  }
}
```

## The tools

| Tool | Returns |
|---|---|
| `list_intents` | 100 buyer transaction intents with supply status |
| `get_intent` | One intent's required context, decision factors, honest supply status |
| `list_offers` | Supply catalog with dated verified facts and explicit unverified fields |
| `match_workload` | Deterministic, explainable match or rejection for a workload |

`match_workload` returns matches **and rejections with reasons**. It does not rank, score, or declare a "best" option — a rejection is a first-class answer, not a failure.

## Honest limitations

- **99 of 100 intents have no verified supply partner.** Every response says so explicitly.
- **No prices, specifications, vendors, or availability are asserted.** Unknown fields are listed under `unverified_fields` rather than guessed.
- Intent ordering is editorial, **not measured demand**.
- One supply partner exists today. This is a protocol skeleton, not a marketplace.
- Outbound provider links require an informed human click. No auto-redirect, no iframe.
- The registry listing does not mean anyone is using it. It means it *can* be found.

## Running the remote endpoint yourself

The deployed endpoint is `src/http-server.py` — Python 3 standard library only, no dependencies:

```bash
MCP_PORT=8787 MCP_DATA_ROOT=/path/to/site python3 src/http-server.py
```

Design constraints it holds to:

- Binds to `127.0.0.1` only. Publish it behind a TLS reverse proxy.
- Reads static JSON from disk. **No outbound network calls, no polling, no background work.**
- Request body capped at 64 KB; path allowlist with traversal protection.
- Threaded with a concurrency cap and a per-connection timeout, so one slow client cannot block the others.
- Runs under systemd with `MemoryMax=64M` and `CPUQuota=10%`.

`src/http-server.cjs` is the same server in Node, kept for reference. The deployed instance is the Python one.

## Protocol details

- **Remote:** MCP Streamable HTTP over `POST /mcp`. `GET` returns `405` — no SSE stream is held open.
- **Local:** newline-delimited JSON-RPC over stdin/stdout (MCP stdio transport). Logs go to stderr only. Requires Node.js >= 18.
- Supported methods: `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list` (empty), `prompts/list` (empty). Notifications are ignored without a response.

## Manual test

```bash
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_intent","arguments":{"id":"book-flight"}}}' \
  | node src/index.js
```

## Publishing a change to the registry

```bash
npm i -g mcp-publisher
cd agentshopping-mcp
./publish.sh 0.1.1     # bumps the version in server.json, then publishes
```

`publish.sh` authenticates with **HTTP authentication** — it signs a challenge with a local ECDSA P-384 key and the registry fetches the public key from `https://agentshopping.org/.well-known/mcp-registry-auth`. Nothing human needs to click anything.

Note the registry's own JWT lives for only 5 minutes, so the login and publish steps are chained with no gap between them. The script handles that, plus a retry for the occasional network stall.

The full walkthrough, including how the proof file and key pair are produced, is in [`发布指引.md`](./发布指引.md) (Chinese).

## License

MIT — see [LICENSE](./LICENSE).