GeoAgent MCP Server
Exposes tools and resources for human-supervised geological modelling from borehole data, including validation, 3D implicit model construction with GemPy, and uncertainty analysis, with a deterministic audit trail.
README
GeoAgent-MVP
A human-supervised geological modelling agent that inspects borehole data, validates it with deterministic geological rules, pauses for human approval, and then builds an implicit 3D model with GemPy.

Example cross-section generated from nine synthetic boreholes. The workflow converted logged intervals into contact points, fitted surface orientations, and constructed the model only after human approval.
Scope: GeoAgent-MVP is a research and portfolio prototype. It demonstrates a supervised agentic workflow over a real geological modelling engine; it is not a production geomodelling platform.
Why this project exists
Engineering agents should not allow a language model to invent calculations, silently repair data, or bypass consequential decisions.
GeoAgent-MVP separates orchestration, explanation, and computation:
| Component | Responsibility |
|---|---|
| LangGraph | Persists workflow state, applies deterministic routing, and enforces the human approval interrupt |
| Optional LLM narrator | Explains structured findings in plain language |
| Deterministic Python tools | Inspect data, validate geology, extract contacts, fit orientations, build the GemPy model, compute uncertainty, and write the report |
| Human supervisor | Approves, modifies, or cancels the proposed modelling configuration |
| MCP server | Exposes the same capabilities as reusable resources, tools, and a prompt |
The LLM does not calculate geological values or decide whether invalid data should be accepted. The complete workflow runs without an API key by using a deterministic narration fallback.
Workflow
Borehole CSV
|
v
Inspect data -------------------- unreadable input ----> halt
|
v
Validate geology ---------------- blocking errors -----> halt + report
|
v
Propose configuration
|
v
+--------------------------------------------------+
| HUMAN APPROVAL GATE |
| approve / modify / cancel |
| LangGraph interrupt() persists the graph state |
+--------------------------------------------------+
|
| approve
v
Revalidate before build --------- new errors ----------> halt + report
|
v
Build GemPy model --------------- tool failure --------> report; invent nothing
|
v
Optional uncertainty ensemble
|
v
Markdown report + figures + audit trail
The approval gate is a real LangGraph interrupt(). The graph pauses before
model construction, and its state is stored by a checkpointer. Nothing
downstream runs until a human decision resumes the same thread.
Geological validation
The validator distinguishes between a blocking data fault and a geological warning requiring interpretation.
Blocking errors
| Code | Meaning |
|---|---|
MISSING_COLUMN |
A required field is absent |
MISSING_COORDINATE |
A record cannot be located in space |
MISSING_DEPTH |
An interval cannot be positioned downhole |
MISSING_LITHOLOGY |
The unit is missing and will not be guessed |
DUPLICATE_RECORD |
An interval record is exactly duplicated |
NEGATIVE_DEPTH |
Downhole depth is negative |
REVERSED_INTERVAL |
depth_from >= depth_to |
OVERLAPPING_INTERVAL |
One depth belongs to multiple logged intervals |
UNKNOWN_LITHOLOGY |
A unit is absent from the declared stratigraphic column |
Warnings for human review
| Code | Meaning |
|---|---|
STRATIGRAPHIC_ORDER_CONFLICT |
A borehole contradicts the majority sequence; this may indicate structure or a logging problem |
INCONSISTENT_LITHOLOGY_LABEL |
Equivalent spelling variants were normalized |
DEPTH_GAP |
An unlogged interval weakens contact constraints |
ISOLATED_BOREHOLE |
The borehole constrains no contact |
SPARSE_CONTACT_SUPPORT |
A surface has fewer than three supporting points |
Lithology identifiers are normalized internally. For example, Unit-A,
UNIT_A, and unit a map to the stable key unit_a.
From boreholes to GemPy
GemPy requires surface points and orientations rather than interval tables. GeoAgent-MVP performs this conversion explicitly.
-
For consecutive intervals where unit
Toverlies unitU, the shared boundary is extracted at:Z = z_collar - contact_depth -
The contact is assigned to the upper unit
T, because it represents the base boundary of that unit in the GemPy structural model. -
The deepest unit is represented as basement rather than as another interpolated surface.
-
Where measured structural orientations are unavailable, a plane is fitted through each surface's contact points and its pole is used as the model orientation.
The fitted orientation is an assumption, not a field measurement. It is shown in the approval configuration and recorded in the final report.
Uncertainty analysis
The optional ensemble perturbs contact elevations using Gaussian noise, rebuilds the model for multiple realizations, and calculates normalized information entropy for each grid cell:
H = -sum_k(p_k * log(p_k)) / log(K)
H = 0: all realizations agree.- Larger
H: greater disagreement between realizations. - The entropy figure highlights the areas most sensitive to contact-elevation uncertainty.
This analysis propagates uncertainty in contact elevations only. It does not represent uncertainty in structural interpretation, fault geometry, or model topology.

Example entropy section. The displayed section is selected where the ensemble contains the strongest uncertainty signal.
MCP interface
mcp_server/server.py exposes GeoAgent through the Model Context Protocol.
Resources
borehole://datasetsborehole://dataset/{name}
Tools
inspect_datasetvalidate_datasetpropose_modelling_configbuild_modelanalyse_uncertainty
Prompt
supervised_validate_and_model
The MCP layer confines file access to the data/ directory, rejects unsafe
filenames, validates datasets before modelling, and requires explicit approval
for consequential modelling and uncertainty operations.
Launch the MCP Inspector with:
npx -y @modelcontextprotocol/inspector python mcp_server/server.py
On Windows, using the virtual-environment interpreter explicitly is also supported:
npx -y @modelcontextprotocol/inspector .venv\Scripts\python.exe mcp_server\server.py
Quick start
Windows Command Prompt
git clone https://github.com/<your-username>/geoagent-mvp.git
cd geoagent-mvp
python -m venv .venv
.venv\Scripts\activate.bat
python -m pip install --upgrade pip
pip install -r requirements.txt
python data\make_datasets.py
Linux or macOS
git clone https://github.com/<your-username>/geoagent-mvp.git
cd geoagent-mvp
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
python data/make_datasets.py
Run the workflow
Interactive approval:
python run_demo.py --dataset data/valid_boreholes.csv
Approved run with uncertainty:
python run_demo.py \
--dataset data/valid_boreholes.csv \
--approve \
--realisations 10
Approved run without uncertainty:
python run_demo.py \
--dataset data/valid_boreholes.csv \
--approve \
--no-uncertainty
Blocking-data demonstration:
python run_demo.py --dataset data/incomplete_boreholes.csv
Cancellation demonstration:
python run_demo.py \
--dataset data/valid_boreholes.csv \
--cancel
An ANTHROPIC_API_KEY is optional. Without it, the explanation node uses a
deterministic fallback while all modelling behaviour remains unchanged.
Outputs
A successful run writes artifacts under outputs/, including:
outputs/
├── figures/
│ ├── model cross-section
│ └── uncertainty entropy section
└── reports/
└── timestamped Markdown modelling report
The report records:
- dataset summary;
- validation errors and warnings;
- normalized stratigraphic order;
- proposed modelling extent and resolution;
- assumptions presented to the human supervisor;
- approval decision;
- GemPy model metadata;
- uncertainty statistics;
- generated figure paths;
- tool-call audit history and timings;
- limitations and outstanding warnings.
Testing
Run the complete suite:
pytest -q
The current test suite contains 29 tests covering:
- valid and invalid schema handling;
- missing coordinates and depths;
- duplicate and overlapping intervals;
- lithology normalization;
- unknown units;
- stratigraphic conflicts and sparse support;
- contact extraction and fitted orientations;
- proposed extent;
- workflow halting;
- genuine human interruption;
- approval, modification, invalid modification, and cancellation;
- audit history;
- repeated-run reproducibility;
- explicit model failure handling;
- rejection of unrecognized approval decisions.
Before publishing a release, record the actual local result rather than a hard-coded historical timing:
29 passed in <environment-dependent time>
Repository layout
geoagent-mvp/
├── run_demo.py
├── requirements.txt
├── README.md
├── SETUP.md
├── data/
│ ├── make_datasets.py
│ ├── valid_boreholes.csv
│ ├── incomplete_boreholes.csv
│ └── inconsistent_boreholes.csv
├── geoagent/
│ ├── graph.py
│ ├── state.py
│ ├── schemas.py
│ └── explain.py
├── tools/
│ ├── data_inspection.py
│ ├── geological_validation.py
│ ├── gempy_modelling.py
│ ├── uncertainty.py
│ └── report_generator.py
├── mcp_server/
│ └── server.py
├── outputs/
│ ├── figures/
│ └── reports/
└── tests/
├── test_validation.py
└── test_agent_workflow.py
Limitations
- The prototype assumes one conformable stratigraphic series.
- Faults, unconformities, intrusions, and overturned structures are not modelled.
- Orientations are inferred from contact geometry when measurements are unavailable.
- The included datasets are synthetic.
- Real projects commonly require separate collar, survey, and lithology tables.
- Deviated boreholes require desurveying, which is not implemented.
- The uncertainty ensemble perturbs contact elevation independently and is not a Bayesian inversion.
- Model quality still depends on data coverage, geological assumptions, and human interpretation.
Planned extensions
- ingest separate collar, survey, and lithology tables;
- desurvey deviated boreholes;
- accept measured dip and azimuth;
- use fitted orientations only as a documented fallback;
- add spatially correlated contact perturbations;
- support faults and unconformities through GemPy structural groups;
- add a lightweight web interface for reviewing the approval payload;
- persist production runs in a durable database-backed checkpointer.
Responsible-use statement
GeoAgent-MVP is a decision-support prototype. Human approval does not guarantee geological correctness, and model outputs should not be used for engineering design, safety-critical decisions, resource estimation, or investment decisions without qualified professional review and validation against project data.
Licence
MIT.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。