# Bitbop Map integration MCP

This is a read-only Model Context Protocol server built with the official Python MCP SDK (`mcp==2.3.0`), not a REST endpoint pretending to be MCP. It exposes tools, resources and an integration prompt. The same API and access checks serve humans, applications and MCP calls.

## Hosted connection

Configure an MCP client that supports Streamable HTTP with URL `https://map.bitbop.dev/mcp`. This endpoint is **anonymous/public-only**. It exposes documentation, source coverage metadata, H3 and public pilot queries. A protected global sample returns a structured access-required result. Do not attach your Bitbop bearer token to this hosted MCP endpoint: it rejects Authorization headers, never uses a host service key, and never forwards an MCP client's credentials to another resource.

The HTTP server is stateless, uses the SDK protocol lifecycle and JSON responses, bounds incoming bodies to 65,536 bytes, and validates Host/Origin against configured first-party/loopback names. Exact `/mcp` POST works without a slash redirect. Hosting under another name requires updating the explicit allowed-host/origin configuration. GET/DELETE behaviour follows the stateless SDK transport; clients should initialise and invoke tools with POST and the standard MCP headers.

## Local authenticated connection

Install the package into an isolated environment using the repository README. Configure a local stdio MCP process:

```json
{
  "mcpServers": {
    "bitbop-map": {
      "command": "/absolute/path/to/.venv/bin/bitbop-map-mcp",
      "env": {"BITBOP_MAP_ORIGIN": "https://map.bitbop.dev"}
    }
  }
}
```

On Windows the executable is `.venv\\Scripts\\bitbop-map-mcp.exe`. Supply `BITBOP_MAP_API_KEY` through the client's local secret/environment facility when protected queries are needed. Do not commit it in the configuration, include it in tool arguments, paste it into a prompt or put it in a URL. Without that environment variable stdio is also anonymous. The default origin is production; fixture testing can use `http://127.0.0.1:8000` and the development-only `local-allowed` key.

Remote authenticated MCP is deliberately not implemented by accepting arbitrary upstream API keys. It needs a resource-specific OAuth flow, audience validation, client consent and an explicit mapping to Bitbop membership. This is a later identity integration; public remote plus local credential-bearing stdio is the supported boundary today. Official references: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports and https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization ; SDK: https://github.com/modelcontextprotocol/python-sdk .

## Tools

| Tool | Use |
|---|---|
| `get_capabilities()` | Inspect live API version, source resolutions, limits and supported services |
| `list_layers(release?)` | Source/encoding/datum/access inventory for current or pinned release |
| `list_releases(limit=5, offset=0)` | Discover retained releases; at most ten per call |
| `find_coverage(bbox, layers?, release?, offset=0)` | Up to 20 intersecting descriptors; pin the returned release across pages |
| `locate_h3(lat, lon, resolution=9, ring=1)` | Real cell/neighbourhood geometry, explicitly no presence verification |
| `resolve_location(lat, lon, layers?, spacing_m=30, release?)` | Server-reported sample/selection; protected access only with local configured key |
| `get_credits(release)` | Release attribution, provenance and licence notices |
| `integration_guide(application)` | Packaged `api`, `architecture`, `game`, `taxi` or `mcp` guide |
| `integration_example(application)` | Runnable `game`, `taxi` or shared `client` JavaScript source |

All tools are read-only/idempotent. They cannot publish datasets, issue keys, charge users, modify games, dispatch rides, send relay messages or change server configuration. API calls use fixed routes at the operator-configured origin; user-provided arbitrary URLs are not accepted. Network responses are bounded to 2 MiB and time out after 20 seconds. HTTP errors are returned as safe structured status/messages without credential-bearing request diagnostics.

## Resources and prompt

* `bitbop-map://api/openapi` — packaged OpenAPI JSON.
* `bitbop-map://guide/{name}` — the same five guides.
* `bitbop-map://example/{name}` — `game`, `taxi`, `client` source.
* Prompt `integrate_map(application="game"|"taxi")` — discovery-first integration workflow.

Packaged documents describe this MCP software build. A local MCP can be newer than its configured API origin; `get_capabilities` is the live authority and a 404 can mean an older deployment. Do not infer that reading a guide enables its future milestones. Tool results are selected/server-reported data, not a substitute for Ed25519 manifest and SHA-256 client verification. The game example shows that independent verification path.

## Agent workflow

Call capabilities; read the API and application guide; inspect layers/coverage at the requested locations; retrieve the application example and shared client. Generate an application-owned integration preserving authentication, release pinning, source/vertical references, bounded caching, cancellation and attribution. Test invalid credentials, coarse/absent data and a known sample. Keep taxi dispatch, game authority and trust evidence in their own applications. Never ask the model to collect or transmit a user's secret as a tool argument.

## Maintenance and validation

`scripts/build_reference.py` packages the canonical docs and runnable examples into the Python distribution. Run it after edits and use `--check` in CI to prevent drift. Tests exercise the official in-process client, real stdio protocol, HTTP initialisation/tool calls, origin checks and protected/public boundaries. Keep stdout reserved for MCP when running stdio. No access logs or secret-bearing exception text should be emitted.
