# Connect an agent to Proof of Use

## Connection details

- **Name:** Proof of Use PDF Tool Matcher
- **Endpoint:** `https://proof.hammerhandworks.com/api/v1/mcp`
- **Transport:** Streamable HTTP over HTTPS
- **Authentication:** none; public, read-only service
- **Tool:** `match_pdf_tools`
- **Price:** free prototype, `amount_minor: 0`, `payments_enabled: false`

In an MCP client that supports remote Streamable HTTP, add the endpoint above as the server URL and select no authentication. Client configuration syntax varies. No API key, account or local server process is required by this service. The endpoint is an MCP transport, so opening it in a browser with GET returns 405; that is expected. Use the exact `/api/v1/mcp` path: this hosting platform intercepts the root `/mcp` path before the application.

The same deterministic matcher powers the [human form](/tool-match/) and the [JSON API](/tool-match/API.md). The MCP tool ranks five documentation-reviewed configurations against seven preferences. It returns qualified matches, exclusions, unknowns, source links and check dates, or a valid abstention. It does not extract PDFs or claim measured comparative accuracy.

The original endpoint, `https://proof-of-use.vinnyd329.chatgpt.site/api/v1/mcp`, remains supported for existing clients and the Glama submission. Both endpoints serve the same tool without redirects.

## Tool contract

`tools/list` returns the complete input and output schemas. The input is exactly the existing [request schema](/tool-match/request.schema.json); the result follows the report portion of the [response schema](/tool-match/response.schema.json).

Example arguments:

```json
{
  "pdf_type": "digital",
  "os": "macos",
  "hardware": "cpu_only",
  "local_only": true,
  "commercial_use": true,
  "programming": "python",
  "table_type": "ruled",
  "max_results": 3
}
```

Seven fields are required. `max_results` is optional, defaults to 3, and cannot exceed 5. Unknown fields are rejected. Do not send PDFs, document text, URLs, credentials or personal data. There is no URL-fetching tool, upload, extraction job, mutation or payment tool.

The tool declares `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, and `openWorldHint: false`. These annotations describe behavior; clients should still validate results and preserve source dates, caveats and unknowns. An `abstained` report is a successful result, not an error or an invitation to invent a fallback. `commercial_use: false` removes that screening requirement; it grants no licensing rights.

## Official JavaScript client

This server uses the official MCP TypeScript server SDK, pinned to 2.3.1. Dependency license text is available in the [third-party notices](/tool-match/THIRD_PARTY_NOTICES.txt). A client using the matching package can connect as follows (Node.js 22+ recommended):

```sh
npm install --save-exact @modelcontextprotocol/client@2.3.1
```

Save as `match.mjs` and run `node match.mjs`:

```js
import {Client, StreamableHTTPClientTransport} from '@modelcontextprotocol/client';

const client = new Client(
  {name: 'pdf-workflow-example', version: '1.0.0'},
  {versionNegotiation: {mode: 'auto'}}
);
try {
  await client.connect(new StreamableHTTPClientTransport(
    new URL('https://proof.hammerhandworks.com/api/v1/mcp')
  ));
  console.log(await client.listTools());
  const result = await client.callTool({
    name: 'match_pdf_tools',
    arguments: {
      pdf_type: 'digital', os: 'macos', hardware: 'cpu_only',
      local_only: true, commercial_use: true,
      programming: 'python', table_type: 'ruled', max_results: 3
    }
  });
  console.log(JSON.stringify(result, null, 2));
} finally {
  await client.close();
}
```

This tool returns the full report in `structuredContent` and a serialized text copy in `content` for compatibility. The official SDK handles the negotiated response envelope. Inspect the tool's advertised output schema rather than parsing a human summary.

## Reproduce the 2025 initialization flow with curl

The current SDK also supports stateless legacy Streamable HTTP. These requests use `2025-11-25`; they do not create a session. Legacy responses can be a finite `text/event-stream` message, so use a client that understands SSE or inspect the `data:` JSON line.

```sh
URL=https://proof.hammerhandworks.com/api/v1/mcp

curl -sS "$URL" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl-example","version":"1.0.0"}}}'

curl -sS "$URL" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","method":"notifications/initialized"}'

curl -sS "$URL" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

curl -sS "$URL" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"match_pdf_tools","arguments":{"pdf_type":"digital","os":"macos","hardware":"cpu_only","local_only":true,"commercial_use":true,"programming":"python","table_type":"ruled","max_results":3}}}'
```

## Protocol and operational boundaries

- Current protocol: **2026-07-28**, with per-request metadata, `server/discover`, and mirrored `MCP-Protocol-Version`, `Mcp-Method` and `Mcp-Name` headers
- Compatibility: SDK-provided stateless **2025-11-25 / 2025-06-18 / 2025-03-26** Streamable HTTP; `initialize`, `notifications/initialized`, `ping`, `tools/list` and `tools/call`
- One JSON-RPC message per POST; no batching or compressed request bodies
- Maximum envelope: **8,192 bytes**, including client metadata; matcher arguments remain limited to **4,096 bytes**
- No session IDs, background jobs, subscriptions, server-initiated actions, OAuth, keys, cookies or credentials
- GET, DELETE and other non-POST methods return 405; no legacy standalone SSE endpoint
- Origin and Host validation prevent browser-origin/DNS-rebinding access. Each explicitly allowed production origin permits its own same-origin browser requests and non-browser clients without an Origin header. Cross-origin browser clients are not enabled
- No application storage or analytics. The service processes only preferences; the hosting provider may maintain normal access logs. Do not treat this as an air-gap or security certification
- No SLA, application-level quota system or paid tier. Each request has bounded input and fixed-size local work; hosting limits still apply

## Examples and verification

Read the [reproducible examples](/tool-match/examples/README.md), inspect the [expected matcher outputs](/tool-match/examples/expected-summary.json), or download the [self-contained examples source ZIP](/tool-match/examples-source.zip). Four cases cover qualified matches, true no-match abstention, and the unresolved model-license gate. The separate synthetic pdfplumber smoke check actually ran on one invented ruled-table PDF and an image-only negative control; it does not establish broad extraction accuracy or change the documentation-only status of the five compatibility profiles.

From the full source checkout:

```sh
npm --prefix pdf-tool-service ci
npm run build
npm run check
node --test pdf-tool-service/examples/test.mjs
npm run preview
# In a second terminal, verify both official SDK generations against the built Worker:
node pdf-tool-service/scripts/smoke-mcp.mjs http://127.0.0.1:4173/api/v1/mcp
# Use the public /api/v1/mcp URL instead to verify a deployed version.
```

The test suite checks real HTTP connections with official clients, schema parity with the existing matcher, deterministic results, abstention, invalid arguments, request limits, method/header/version failures, Origin/Host validation, and disabled sessions. Local tests do not by themselves prove a public deployment is live.

Primary implementation references (reviewed 2026-10-14):
- [MCP 2026-07-28 Streamable HTTP](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http)
- [MCP 2025-11-25 transports](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports)
- [Official TypeScript SDK HTTP serving guide](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/docs/serving/http.md)
- [Official TypeScript SDK web-standard runtime guide](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/docs/serving/web-standard.md)
