{
  "markdown": "<!-- mcp-name: com.mireye/earth -->\n\n# mireye-mcp\n\n> Developed in a private monorepo. This repository\n> ([Mireye-Labs/mireye-earth-mcp](https://github.com/Mireye-Labs/mireye-earth-mcp))\n> is the published source of the `mireye-mcp` PyPI package, snapshot-synced\n> on every release. Issues and PRs are welcome here (changes are applied upstream\n> and re-synced; the test suite runs in the monorepo); releases land via PyPI.\n\nExpose Mireye Earth's `/v1/ask` and `/v1/fetch` endpoints to MCP clients\nthat need a local stdio adapter (Claude Desktop, Cursor, custom agents\nbuilt on the `mcp` Python SDK) as native tools — no HTTP wiring required.\n\nThis is a standalone PyPI package (`mireye-mcp`) with only two\nruntime dependencies — `httpx` and `mcp`. It does not pull in the\ngeospatial backend, so there's no GDAL / rasterio / DuckDB build step.\n\nThe server is a local stdio adapter with no geospatial business logic:\ntool handlers POST to the deployed Mireye HTTP API, while read-only MCP\nresources fetch and cache the public field catalog.\n\nMireye also exposes a hosted remote MCP endpoint at\n`https://api.mireye.com/mcp` for clients that support Streamable\nHTTP and native OAuth. Use that hosted endpoint for Claude Code so `/mcp`\nopens the browser sign-in flow. This package remains the local stdio path;\nit uses `mireye-mcp login` or `MIREYE_BEARER_TOKEN` for credentials.\n\n---\n\n## What the agent gets\n\nSix tools, all prefixed `mireye_` so they sort together and don't\ncollide with generic `ask` / `fetch` tools from other MCP servers:\n\n| Tool             | When the agent should call it                                                                  |\n|------------------|------------------------------------------------------------------------------------------------|\n| `mireye_ask`     | The caller asked a question about a US place (\"is this in a flood zone?\", \"wildfire risk?\").   |\n| `mireye_fetch`   | The caller wants specific named fields (\"elevation and slope here\") or is powering a workflow. |\n| `mireye_geocode` | The caller gave an address and just wants the coordinate + its quality, nothing else. |\n| `mireye_lookup` | The input might be ambiguous, isn't a clean address (a coordinate or an APN), or a parcel is wanted. |\n| `mireye_request_field` | The catalog doesn't have the field the caller needs — describe it in plain language plus example locations and either get a live match now or a `request_id` to build it. |\n| `mireye_field_request_status` | Poll a `request_id` from `mireye_request_field` for status, queue position, ETA, and (once `live`) the `resume` call. |\n\nCatalog context is exposed as MCP resources instead of extra tools:\n\n| Resource | What it returns |\n|----------|-----------------|\n| `mireye://catalog/fields` | Full field catalog. |\n| `mireye://catalog/presets` | Preset names and field expansions. |\n| `mireye://catalog/us-envelope` | Supported coordinate bounds. |\n| `mireye://field/{name}` | One field definition. |\n| `mireye://preset/{name}` | One preset expansion. |\n\nWorkflow prompts are also registered — 22 in total. Claude Code surfaces\nMCP prompts as slash commands under the form `/mcp__<server>__<prompt>`.\n\n| Prompt | What it does |\n|--------|--------------|\n| `mireye_ask` | Call `mireye_ask` with a lat/lng and question. |\n| `mireye_fetch` | Call `mireye_fetch` with a lat/lng and optional fields/preset. |\n| `mireye_lookup` | Call `mireye_lookup` with an address/`lat,lng`/APN, noting the `disposition` handling. |\n| `mireye_request_field` | File a field request with `mireye_request_field`, noting the `disposition` handling. |\n| `mireye_field_request_status` | Poll a field request's status with `mireye_field_request_status`. |\n| `mireye_fields` | Browse or search the field catalog. |\n| `mireye_pick_fields` | Choose the smallest useful field set for a free-text question. |\n| `mireye_site_report` | Site report via the `site_selection` preset. |\n| `mireye_flood_check` | Flood-relevant signals via the `flood_risk` preset. |\n| `mireye_wildfire_underwrite` | Wildfire underwriting signals via the `wildfire_underwrite` preset. |\n| `mireye_terrain_report` | Terrain signals via the `terrain` preset. |\n| `mireye_land_cover_report` | Land cover signals via the `land_cover` preset. |\n| `mireye_building_lookup_report` | Primary building details via the `building_lookup` preset. |\n| `mireye_points_of_interest_report` | Nearby amenities via the `points_of_interest` preset. |\n| `mireye_utilities_report` | Utility infrastructure via the `utilities` preset. |\n| `mireye_boundaries_report` | Political/census boundaries via the `boundaries` preset. |\n| `mireye_solar_siting_report` | Solar siting signals via the `solar_siting` preset. |\n| `mireye_wind_siting_report` | Wind siting signals via the `wind_siting` preset. |\n| `mireye_storage_siting_report` | Battery storage siting signals via the `storage_siting` preset. |\n| `mireye_data_center_siting_report` | Data center siting signals via the `data_center_siting` preset. |\n| `mireye_grid_interconnect_report` | Interconnection signals via the `grid_interconnect` preset. |\n| `mireye_natural_hazard_report` | Natural hazard signals via the `natural_hazard` preset. |\n\nThere is no third `list_fields` tool. Agents that need the catalog should\nread the MCP resources above; the stdio adapter backs them with\n`GET /v1/meta/fields` and a 1-hour ETag-aware cache.\n\n---\n\n## Install local stdio — one command with `uvx`\n\n```bash\nuvx mireye-mcp\n```\n\nThat's it. `uvx` (bundled with [`uv`](https://docs.astral.sh/uv/))\ndownloads the package into a managed cache, runs the entry point, and\nthe next invocation is instant. No venv to manage, no `pip install`,\nno native builds.\n\nIf you don't have `uv`:\n\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\nPlain pip also works:\n\n```bash\npip install mireye-mcp\nmireye-mcp  # entry point\n```\n\n---\n\n## Official MCP Registry\n\nThis server is published to the\n[Official MCP Registry](https://registry.modelcontextprotocol.io) as\n**`com.mireye/earth`** — the entry is live (the publish job ships from\n`release.yml`), and `mireye-mcp` 0.2.0 is on PyPI. The registry entry\ncarries both distributions:\n\n- the **PyPI package** `mireye-mcp` (local stdio, run via `uvx`), and\n- the **hosted remote** `https://api.mireye.com/mcp` (Streamable HTTP +\n  OAuth) for clients that prefer a remote server.\n\nBecause the entry is live, registry-aware clients (VS Code, the GitHub MCP\nRegistry, and anything else that reads the official registry) can\ndiscover and install it from there — no manual config required.\n\n---\n\n## Wire it into Claude Desktop\n\nFirst authenticate the local adapter:\n\n```bash\nmireye-mcp login\n```\n\nFor non-interactive hosts, set `MIREYE_BEARER_TOKEN` instead.\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json`\n(macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows):\n\n```json\n{\n  \"mcpServers\": {\n    \"mireye-earth\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mireye-mcp\"]\n    }\n  }\n}\n```\n\nRestart Claude Desktop. The six tools (`mireye_ask`, `mireye_fetch`,\n`mireye_geocode`, `mireye_lookup`, `mireye_request_field`,\n`mireye_field_request_status`)\nappear under the 🔌 menu, with catalog resources and prompts available to\nclients that surface those MCP primitives.\n\nTo point at a self-hosted deployment instead of the default Fly URL:\n\n```json\n{\n  \"mcpServers\": {\n    \"mireye-earth\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mireye-mcp\"],\n      \"env\": {\n        \"MIREYE_BASE_URL\": \"https://your-deploy.example.com\"\n      }\n    }\n  }\n}\n```\n\n---\n\n## Wire it into Claude Code\n\nUse the hosted HTTP MCP endpoint instead of this local stdio package:\n\n```bash\nclaude mcp remove mireye-earth -s user   # only needed if an old stdio entry exists\nclaude mcp add --transport http --scope user mireye-earth https://api.mireye.com/mcp\n```\n\nRestart Claude Code, run `/mcp`, and follow the browser OAuth flow.\nSlash commands appear as:\n\n- `/mcp__mireye-earth__mireye_ask <lat> <lng> <question>`\n- `/mcp__mireye-earth__mireye_fetch <lat> <lng> [fields] [preset]`\n\nOr just chat naturally — Claude Code will call the tool when relevant.\n\n---\n\n## Wire it into Cursor\n\nCursor's MCP config lives at `~/.cursor/mcp.json` (global) or\n`<repo>/.cursor/mcp.json` (workspace). Same shape as Claude Desktop:\n\n```json\n{\n  \"mcpServers\": {\n    \"mireye-earth\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mireye-mcp\"]\n    }\n  }\n}\n```\n\nOpen **Cursor → Settings → MCP** and confirm `mireye-earth` shows the two\ngreen tools. Catalog resources and prompts appear when the client supports\nthose MCP primitives.\n\n---\n\n## Wire it into a custom agent\n\nIf you're building an MCP client with the `mcp` Python SDK, point its\n`StdioServerParameters` at the installed entry point:\n\n```python\nfrom mcp import ClientSession, StdioServerParameters\nfrom mcp.client.stdio import stdio_client\n\nparams = StdioServerParameters(command=\"uvx\", args=[\"mireye-mcp\"])\n\nasync with stdio_client(params) as (read, write):\n    async with ClientSession(read, write) as session:\n        await session.initialize()\n        tools = await session.list_tools()\n        # tools.tools is [mireye_ask, mireye_fetch]\n        resources = await session.list_resources()\n        prompts = await session.list_prompts()\n\n        result = await session.call_tool(\n            \"mireye_ask\",\n            {\"lat\": 40.7128, \"lng\": -74.0060, \"question\": \"elevation?\"},\n        )\n```\n\n---\n\n## Configuration\n\n| Env var            | Default                          | Purpose                          |\n|--------------------|----------------------------------|----------------------------------|\n| `MIREYE_BASE_URL`  | `https://api.mireye.com`   | HTTP base URL the tools POST to. Stored login credentials only attach when they were created against this same URL. |\n| `MIREYE_TIMEOUT_S` | `120`                            | Per-request timeout in seconds (must exceed the ~110 s `/v1/ask` deadline). |\n| `MIREYE_BEARER_TOKEN` | unset | Optional Mireye bearer token. Overrides stored credentials for tool calls; `status` reports on the stored login first. |\n| `MIREYE_MCP_CREDENTIALS_FILE` | `~/.config/mireye-mcp/credentials.json` | Stored token path used by `login` / `status` / `logout`. |\n\n## Authentication\n\nThe local stdio adapter does not perform native MCP OAuth discovery.\nThe HTTP API requires bearer auth for `/v1/ask` and `/v1/fetch`, so run\nthe device login helper once:\n\n```bash\nmireye-mcp login\n```\n\nThe command prints a verification URL and code, waits for approval in\nthe Mireye account page, and stores a Mireye API token locally. You can\nalso provide a token directly:\n\n```json\n{\n  \"mcpServers\": {\n    \"mireye-earth\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mireye-mcp\"],\n      \"env\": {\n        \"MIREYE_BEARER_TOKEN\": \"eyJ...\"\n      }\n    }\n  }\n}\n```\n\nCheck or remove local credentials:\n\n```bash\nmireye-mcp status\nmireye-mcp logout\nmireye-mcp logout --revoke\n```\n\n### Credentials are bound to their base URL\n\n`login` records the `MIREYE_BASE_URL` it ran against, and the stored\ntoken is only ever sent to that same URL. If `MIREYE_BASE_URL` later\npoints somewhere else, tool calls behave as logged out and the error\nnames both URLs — re-run `mireye-mcp login` against the new URL,\nor set `MIREYE_BEARER_TOKEN` explicitly. Credentials files without a\nrecorded `base_url` (e.g. hand-written) are treated as bound to the\ndefault `https://api.mireye.com`.\n\nTwo more guardrails:\n\n- Tokens of any kind are never sent over plain `http://`, except to\n  loopback hosts (`localhost` / `127.0.0.1` / `[::1]`) for local\n  development.\n- `status` and `logout --revoke` operate on the **stored** base URL, so\n  you can always inspect or revoke a stored login even while\n  `MIREYE_BASE_URL` points elsewhere.\n\nFor native MCP OAuth, configure your client to use the hosted remote MCP\nURL `https://api.mireye.com/mcp` instead of launching this stdio\nbinary. The remote endpoint advertises OAuth metadata and uses browser\nOAuth 2.1 + PKCE.\n\n---\n\n## Troubleshooting\n\n**Server doesn't appear in Claude Desktop.** Check that `uvx` resolves\non the PATH used by the GUI app (macOS launches GUI apps with a minimal\nPATH). Test from a terminal: `which uvx`. If empty, install `uv`:\n`curl -LsSf https://astral.sh/uv/install.sh | sh`. If `uvx` lives at\n`/Users/you/.local/bin/uvx`, use the absolute path in `command`.\n\n**Tools not appearing under the 🔌 menu after restart.** Watch\n`~/Library/Logs/Claude/mcp-server-mireye-earth.log`. The server logs to\nstderr on startup; you should see `[mireye-mcp] starting\nbase_url=…`. If there's no log, `uvx` isn't being invoked — usually a\nPATH issue.\n\n**`ConnectError` / `ReadTimeout`** on the first tool call. The hosted\nAPI keeps its machines running, but calls right after a backend deploy\ncan be slow while geospatial sources warm in the background, and some\nfields depend on slow upstream federal services. The default\n`MIREYE_TIMEOUT_S` (120 s) already exceeds the ~110 s `/v1/ask` deadline, so a\ncold start fits; only raise it further (never below 120) if you still time out.\n\n**HTTP 400 `coord_out_of_bounds`.** Mireye is US-only in V1. The accepted\nenvelope is `lat ∈ [18, 72]`, `lng ∈ [-180, -65]` — covering the lower 48,\nAlaska, Hawaii, and US territories.\n\n**HTTP 400 `fields_unknown`.** The field name is not in the catalog. Hit\n`https://api.mireye.com/v1/meta/fields` to see the canonical list.\nCommon surprises: `elevation_m` is `elevation`, `floodplain` is\n`within_floodplain_polygon`.\n\n**HTTP 4xx/5xx in general.** Tool errors include actionable JSON fields\nsuch as `code`, `message`, `http_status`, `request_id`, `tool`, and\n`retryable`. Agents should retry only when `retryable` is true.\n\n**Auth errors.** `401` means the MCP server has no token, the token\nexpired, or the token was revoked. Run `mireye-mcp login` again,\nor set `MIREYE_BEARER_TOKEN`. `403` means the signed-in account is not\nallowed by the backend account policy.\n\n---\n\n## What this server does NOT do\n\n- **No data-result caching.** The HTTP API has its own response cache\n  (local disk, plus a shared Redis tier in production). The stdio adapter\n  only caches the public field catalog resource.\n- **No geospatial business logic.** The adapter validates obvious MCP input\n  bounds and field-count limits, but source orchestration stays in the API.\n- **No streaming.** MCP streaming responses are V1.5.\n- **No Firebase validation in MCP.** The MCP package forwards bearer\n  tokens; the HTTP API owns token verification and account policy.\n- **No in-process imports of `mireye_earth`.** The server talks to the API\n  over HTTP only, so it ships as a separate slim PyPI package\n  (`mireye-mcp`) and can be installed without the data backend.\n\n---\n\n## Releasing\n\nThis package is published from this directory on every `v*` tag on the\nmain repo. To release locally:\n\n```bash\ncd mcp_server\npython -m build\ntwine upload dist/*\n```\n",
  "bytes": 14855,
  "sha": "2c120457595a24abeacdd6b4e2a2b2a4e051a3870e3bbd28cbb7693dd8e95029",
  "repo_slug": "mireye-labs/mireye-earth-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_mireye_earth_6a0299e8/readme"
}