Skip to main content
Glama
AllenHoem

allenhoem-mcp

by AllenHoem
README.md
# allenhoem-mcp

A remote **Model Context Protocol** server exposing tools that enrich Allen R.
Hoem's professional record beyond what allenhoem.com hosts. Runs on Cloudflare
Workers (Agents SDK `McpAgent`, Durable Object–backed) and is usable by any MCP
client — Claude Desktop, ChatGPT, Slack — and by the allenhoem.com chat panel via
Anthropic's MCP connector.

**Live:** `https://allenhoem-mcp.allenhoem.workers.dev`
**MCP endpoint (Streamable HTTP):** `https://allenhoem-mcp.allenhoem.workers.dev/mcp`

## Tools

| Tool | What it does |
|------|--------------|
| `list_allen_media` | Lists Allen's patents (fetchable via `get_patent`) and his talk/demo videos with watch links. |
| `get_patent` | Fetches full patent detail — abstract, inventors, assignee, dates, claims — from Google Patents. Works for any US publication number; Allen's are `US20250086403A1` and `US20240303280A1`. KV-cached 30 days. |
| `send_contact_request` | Logs a message to Allen (name, email, message, intent). Reviewed via the script below. Daily-capped. |

### Deferred: `get_youtube_transcript`

Code is in `src/youtube.ts` but the tool is **not registered**. YouTube's 2026
"poToken" gate makes reliable transcript extraction from a datacenter IP
infeasible (verified: the `timedtext` endpoint returns an empty body without a
poToken, even from a residential IP with a valid caption-track list). To enable
later, pick one: pre-bake Allen's ~6 talk transcripts into KV, or wire a
third-party transcript API and re-register the tool.

## Connect a client

**Claude Desktop** — add to `claude_desktop_config.json`:
```json
{
  "mcpServers": {
    "allenhoem": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://allenhoem-mcp.allenhoem.workers.dev/mcp"]
    }
  }
}
```

**ChatGPT** (Developer mode / connectors) or **Slack** (custom MCP integration):
add the server URL `https://allenhoem-mcp.allenhoem.workers.dev/mcp` (Streamable
HTTP). Some legacy clients need SSE — use `/sse` instead.

**Anthropic API (how the website consumes it):** pass the server in the request
with beta `mcp-client-2025-11-20`:
```jsonc
"mcp_servers": [{ "type": "url", "url": ".../mcp", "name": "allenhoem" }],
"tools": [{ "type": "mcp_toolset", "mcp_server_name": "allenhoem" }]
```

## Review contact requests

```bash
./scripts/contacts.sh
```

Or enable the authed HTTP view: `npx wrangler secret put ADMIN_TOKEN`, then GET
`https://allenhoem-mcp.allenhoem.workers.dev/admin/contacts?token=<token>`.

## Tool-use logging

Every tool call increments `toolcount:<date>:<tool>` and writes a `toollog:<ts>`
record (90-day TTL) in the `MCP_CACHE` KV namespace. Inspect with:
```bash
npx wrangler kv key list --namespace-id 2bc85e810484488eb740611f403c6a85 --remote | grep toolcount
```

## Develop & deploy

```bash
npm install
npm run typecheck
npx wrangler kv namespace create MCP_CACHE   # first time — paste id into wrangler.jsonc
npm run deploy
```

Local dev: `npm run dev`, then point `test-client.mjs` at `http://localhost:8787/mcp`.