Skip to main content
Glama
drillsite-mcp

drillsite-mcp

drillsite-mcp

A production-ready Model Context Protocol (MCP) server in Python, built on the official MCP Python SDK. It lets an AI agent (Claude Desktop, Claude Code, or any MCP client) query a drill-site prospectivity API through validated tools, resources and a prompt.

The sample backend is a small FastAPI service that scores mining exploration zones, modelled on the prospectivity platform I run at Metalgenomic. The data here is synthetic.

MCP client (Claude, Inspector)
        │  stdio  |  SSE  |  streamable HTTP
        ▼
drillsite-mcp  (MCPServer: tools · resources · prompt)
        │  httpx, API key, timeouts, safe error mapping
        ▼
Drill-site Prospectivity API  (FastAPI + Pydantic)

FastMCP → MCPServer. In SDK v2 the FastMCP class was renamed MCPServer (from mcp.server.mcpserver import MCPServer). The decorator API is the same. To run this on SDK v1, use from mcp.server.fastmcp import FastMCP and pin mcp<2.

What it exposes

Kind

Name

What it does

Tool

list_zones(min_score, region)

Zones at or above a score, best first (read-only)

Tool

get_zone(zone_id)

One zone with score, drivers and field notes (read-only)

Tool

rank_zones(top_n)

Top N zones to drill first, with the main driver of each (read-only)

Tool

add_field_note(zone_id, note)

Writes a field observation to the backend

Resource

zones://all

All zones as JSON

Resource template

zones://{zone_id}

One zone as JSON

Prompt

drill_plan(top_n)

Asks the agent for a drilling order grounded in the tools

Related MCP server: Earth Grounding MCP

Production concerns handled

  • Input validation before any request leaves the server. Zone ids must match Z-000, scores are bounded 0–1, top_n 1–20, notes ≤ 500 characters. Invalid input is rejected by the SDK's Pydantic validation and never reaches the API.

  • One shared HTTP client created in the server lifespan and closed on shutdown, with connect/read timeouts and the API key sent as a header.

  • Safe error mapping. Timeouts, 401/403, 404, 422 and 5xx become short ToolError messages. Status codes, URLs and keys are logged to stderr, never returned to the model.

  • Prompt-injection mitigation. Text written by people (field notes) comes back under untrusted_field_notes, with control characters stripped and length capped. The server instructions and the drill_plan prompt tell the agent to treat it as data.

  • Tool annotations (readOnlyHint, destructiveHint, …) so clients can decide which calls need user confirmation.

  • stdout is reserved for the protocol under stdio; logs go to stderr.

  • End-to-end tests run MCP client → server → httpx → FastAPI in one process.

Quick start

Requires Python 3.11+.

python -m venv .venv
source .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
pytest                               # 10 tests, all in-process

Run the API (terminal 1):

export DRILLSITE_API_KEY=dev-key     # Windows PowerShell: $env:DRILLSITE_API_KEY="dev-key"
drillsite-api                        # http://127.0.0.1:8000  (docs at /docs)

Run the MCP server (terminal 2), on either transport:

drillsite-mcp --transport stdio                    # for Claude Desktop / Claude Code
drillsite-mcp --transport sse --port 8001          # SSE at http://127.0.0.1:8001/sse
drillsite-mcp --transport streamable-http --port 8001   # http://127.0.0.1:8001/mcp

Configuration (environment variables):

Variable

Default

Purpose

DRILLSITE_API_URL

http://127.0.0.1:8000

Backend base URL

DRILLSITE_API_KEY

dev-key

Sent as X-API-Key

MCP_TRANSPORT / MCP_HOST / MCP_PORT

stdio / 127.0.0.1 / 8001

Defaults for the CLI flags

LOG_LEVEL

INFO

stderr log level

Connect from Claude Desktop or Claude Code (stdio)

{
  "mcpServers": {
    "drillsite": {
      "command": "/absolute/path/to/.venv/bin/drillsite-mcp",
      "args": ["--transport", "stdio"],
      "env": { "DRILLSITE_API_KEY": "dev-key" }
    }
  }
}

Claude Code: claude mcp add drillsite -- /absolute/path/to/.venv/bin/drillsite-mcp --transport stdio

Debugging with the MCP Inspector

The MCP Inspector is the official tool for exercising an MCP server by hand. It needs Node.js. Keep the API running.

1. UI mode over stdio. The Inspector launches the server for you:

npx @modelcontextprotocol/inspector -e DRILLSITE_API_KEY=dev-key drillsite-mcp --transport stdio

Open the URL it prints. Click Connect, then:

  • Tools → List Tools: you should see the four tools with their JSON schemas.

  • Run rank_zones with top_n = 2 → Z-001, Z-004.

  • Run get_zone with zone_id = ../admin → a validation error. The request never reached the API (check terminal 1: no log line).

  • Resources: read zones://all, then the template zones://{zone_id} with Z-003.

  • Prompts: get drill_plan.

2. UI mode over SSE. Start the server with --transport sse --port 8001, then in the Inspector choose transport SSE and URL http://127.0.0.1:8001/sse.

3. CLI mode (scriptable, good for CI smoke tests):

npx @modelcontextprotocol/inspector --cli drillsite-mcp --transport stdio --method tools/list
npx @modelcontextprotocol/inspector --cli drillsite-mcp --transport stdio \
  --method tools/call --tool-name rank_zones --tool-arg top_n=2
npx @modelcontextprotocol/inspector --cli drillsite-mcp --transport stdio \
  --method resources/read --uri zones://Z-001

Common problems

Symptom

Likely cause

Inspector connects, then the server dies at once

Something printed to stdout. Under stdio only protocol messages may go there; use logging (stderr).

Every tool returns "not authorised"

DRILLSITE_API_KEY differs between the API and the MCP server.

"The prospectivity API is unreachable"

The API is not running, or DRILLSITE_API_URL is wrong.

SSE connects but tools time out

Wrong URL: SSE is /sse, streamable HTTP is /mcp.

Set LOG_LEVEL=DEBUG to see every backend call in stderr.

Docker

docker build -t drillsite-mcp .
docker run --rm -p 8001:8001 -e DRILLSITE_API_URL=http://host.docker.internal:8000 drillsite-mcp

The image runs the server over SSE on port 8001 as a non-root user.

Project layout

src/drillsite_mcp/api.py      sample FastAPI backend
src/drillsite_mcp/server.py   MCP server: tools, resources, prompt, transports
tests/test_server.py          end-to-end tests through a real MCP client

License

MIT

Available Tools

4 tools
add_field_noteA

Attach a short field observation to a zone. This writes to the backend.

Inputs: note (required), zone_id (required). Returns: object

get_zoneA
Read-only

Get one zone with its score, the drivers behind it, and field notes.

Inputs: zone_id (required). Returns: object

list_zonesA
Read-only

List candidate drill zones at or above a score, best first.

Inputs: region, min_score. Returns: result

rank_zonesA
Read-only

Rank the top N zones to drill first, with the main driver of each score.

Inputs: top_n. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 4 tools

    Disambiguation3/5

    list_zones and rank_zones both return zones ordered by score, so an agent may hesitate between threshold-based listing and top-N ranking. The descriptions do distinguish filtering from ranking and driver emphasis, but the overlap is real. get_zone and add_field_note are clearly distinct.

    Naming Consistency5/5

    All tools follow a consistent snake_case verb_noun pattern: list_zones, get_zone, rank_zones, add_field_note. Singular/plural use is also predictable for one-zone versus many-zone operations.

    Tool Count5/5

    Four tools is well-scoped for a drill-zone ranking and field-note server. Each tool supports a distinct part of the workflow without excessive surface area.

    Completeness4/5

    The core workflow of finding, inspecting, ranking, and annotating zones is covered. The main gap is that field notes are append-only, with no update or delete operation, which is a minor but noticeable lifecycle limitation.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to interact with the OSDU® data platform through Model Context Protocol, providing tools for search, storage, schema management, and dataset operations.
      2
      Apache 2.0
    • F
      license
      B
      quality
      C
      maintenance
      Enables AI agents to query verifiable physical-world ground truth for any point on Earth — water availability, seismic and space-weather hazard, ground stability, and resource indications — with every answer backed by a Bitcoin-anchored provenance record that can be independently verified. It also lets agents check whether an Earth-science hypothesis has already been tested, list documented nulls and retractions, and run bounded controlled tests that return UNTESTABLE rather than fabricate a result.
      11
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables LLM agents to access third-party APIs through a least-privilege set of audited tools with allowlists, per-caller scopes, label gates, write confirmation, limits, and PII-masked logging. It restricts reads to labeled data, prevents sending or destructive actions, and records every allowed or denied call.
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to validate and desurvey drillhole tables, compute host-filtered log-ratio fractionation gradients with confidence cones and significance tests, propose step-out boreholes (or explicitly decline when the direction is unresolved), and screen surface anomalies with immobile-ratio and tau mass-transfer checks.
      MIT