v1.1.0 — hosted HTTP endpoint
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