Skip to content

v1.1.0 — hosted HTTP endpoint

Choose a tag to compare

@bensynapse bensynapse released this 22 Jul 05:38
61d3581

Adds a Streamable-HTTP transport, so the server can be reached over HTTP by clients and directories that cannot run a local stdio process.

https://mcp.livetennisapi.com/mcp

Tools are listable without a key so directories can introspect; calling one needs a key. Send it as Authorization: Bearer twjp_…, X-API-Key:, or ?token=.

Multi-tenant by construction

The stdio server reads one key from the environment into one long-lived client — correct for stdio, catastrophic over HTTP, where it would serve every anonymous caller on the operator's key at the operator's tier, silently and permanently.

So the HTTP transport builds a fresh server per request bound to that request's key, runs stateless so no session map can hand one caller another's server, and has no fallback to LIVETENNISAPI_KEY. The systemd unit clears that variable outright as defence in depth.

Rate limiting

60 req/min anonymous, 300 keyed, tunable via MCP_RATE_LIMIT_ANON / MCP_RATE_LIMIT_KEYED. Keyed on API key rather than IP — behind a Cloudflare tunnel every request arrives from 127.0.0.1, so an IP-keyed limiter would put every user in one bucket.

Tests that can fail

npm run test:mutation reintroduces each bug the tests claim to catch and asserts the suite goes red. The first version of the rate-limit test passed while the limiter bucketed globally; it now reads the RateLimit header and asserts a fresh caller starts with a full budget.

The stdio server is unchanged. If you use npx livetennisapi-mcp, nothing about your setup changes and your key still never leaves your machine.

Full changelog: https://github.com/livetennisapi/livetennisapi-mcp/blob/main/CHANGELOG.md