Climate MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Climate MCP Serverwhat are the top 5 funds by total pledges?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Climate MCP Server
A Model Context Protocol (MCP) server that exposes 26 structured analytical tools over Climate Finance Update (CFU) datasets. Designed for use with Claude Desktop (STDIO) or any MCP-compatible client.
Overview
The server enables structured queries against three Climate Finance datasets (DuckDB-backed) — funds, pledges, and projects — without requiring the client to write any data access code. All tools return a consistent JSON envelope and emit audit events for full reproducibility.
Key capabilities:
Fund-level financial analysis (stage totals, conversion ratios, gaps)
Portfolio-wide aggregations by fund type, sector, adaptation/mitigation
Contributor/donor ranking across pledge and deposit stages
Data quality diagnostics (missing value reports)
Schema contract introspection
Run-level audit trail with Markdown export
Related MCP server: Snowdrop MCP
Project Report
For a narrative project description (problem statement, architecture, deployment, and validation), see:
docs/PROJECT_REPORT.md
Project Structure
climate_mcp_server/
├── data/ # Optional compatibility exports (legacy CSV aliases)
│ ├── fund.csv
│ ├── pledges.csv
│ └── projects.csv
│
├── ingestion_layer/ # CFU download → DuckDB → CSV (runs at MCP startup unless CLIMATE_MCP_SKIP_CFU_PIPELINE=1)
│ ├── cfu_pipeline.py # Main pipeline: scrape dashboard, download Excel, load DuckDB, export CSVs
│ ├── transform.py # Transform / analytics steps used by the pipeline
│ ├── Requirements.txt # Standalone ingestion dependencies (optional)
│ ├── notification developer.py # Optional notifications (email, etc.)
│ └── data/
│ ├── climate_funds.duckdb # Primary store: raw.* + analytics.* tables
│ ├── manifest.json # Last run: URLs, checksums, paths to exports
│ ├── raw_change_report.json # Diff-style report between ingested versions
│ ├── transform_schema_review.json
│ ├── archive/ # Timestamped Excel workbooks (*.xlsx)
│ ├── raw/ # latest.xlsx + latest.sha256.txt (working copy)
│ ├── raw_snapshots/ # Per-sheet CSV snapshots (*_latest.csv)
│ └── exports/ # Versioned CSVs for inspection / non-DuckDB fallback
│ ├── fund/fund1.csv
│ ├── pledges/pledges1.csv
│ └── projects/projects1.csv
│
├── docs/
│ ├── schema_contract.md # Human-readable governed schema contract
│ └── schema_contract_summary.json # Machine-readable contract summary (LLM validation)
│
├── runs/ # Auto-generated audit run logs
│ └── *.md # One Markdown file per run_id
│
├── mcp_server/
│ ├── finance/
│ │ └── server.py # MCP server entry point (FastMCP initialisation)
│ │
│ ├── tools/ # All 26 MCP tools
│ │ ├── registry.py # Central tool registration (single entry point)
│ │ ├── context.py # Shared singleton context: paths, table loader, audit state, and shared helpers
│ │ ├── audit_tools.py # start_run / get_audit_trail / finalize_run
│ │ ├── contract_tools.py # get_schema_contract / get_schema_contract_summary
│ │ ├── discovery_tools.py # list_datasets / describe_dataset / preview_dataset / list_unique_values / resolve_entity
│ │ ├── summary_tools.py # search_funds / get_fund_details / fund_summary / portfolio_summary / sector_summary /
│ │ │ # fund_type_distribution / adaptation_vs_mitigation_summary / compare_funds / fund_stage_totals
│ │ ├── finance_tools.py # fund_conversion_ratios / rank_entities / rank_by_column / filter_funds_by_threshold / fund_stage_gap
│ │ ├── aggregation_tools.py # avg_projects_per_fund_by_type
│ │ └── quality_tools.py # missing_report
│ │
│ └── data/
│ └── datasets.py # Dataset URI registry (cfu://funds → analytics.fund, etc.)
│
├── mcp_client/ # MCP client package
│ ├── CLIENT_ARCHITECTURE.md
│ ├── __init__.py
│ ├── __main__.py
│ ├── agent.py
│ ├── api.py
│ ├── config.py
│ ├── erasmus.py
│ ├── errors.py
│ └── mcp_tools.py
│
├── tests/
│ └── run_tests.py # Self-contained test runner (111 tests, no pytest required)
│
├── pyproject.toml # Project metadata and dependencies
├── uv.lock # Locked dependency versions
├── .python-version # Python version pin
└── .gitignore
Architecture
MCP Client (ClimateGPT)
│
│ JSON-RPC tool request
▼
MCP Server — FastMCP ("finance")
│
├── Tool Layer (7 modules, 26 tools)
│ audit_tools → run lifecycle management
│ contract_tools → schema governance
│ discovery_tools → dataset exploration
│ summary_tools → fund profiles and aggregations
│ finance_tools → ratios, rankings, gaps, thresholds
│ aggregation_tools→ cross-dataset aggregations
│ quality_tools → data completeness diagnostics
│
├── Shared Context (context.py)
│ Singleton ToolContext — thread-safe, mtime-cached dataset loading
│ Shared helpers: _to_num, _records, _load, _norm
│ Audit state: active_run_id, run_events, log_tool_event()
│ Uniform output envelope: tool_result()
│
├── Dataset Registry (datasets.py)
│ URI resolution: cfu://funds → analytics.fund
│ cfu://pledges → analytics.pledges
│ cfu://projects → analytics.projects
│
└── DuckDB Dataset Tables
analytics.fund · analytics.pledges · analytics.projectsDesign principles:
Every tool returns the same JSON envelope:
{"ok": bool, "data": {...}, "meta": {...}, "error": null | "message"}Dataset tables are loaded once and cached by DuckDB file mtime; no redundant reads across tools
All string comparisons are case-insensitive via
_norm()(lowercase + strip)NaN values are replaced with
nullbefore serialisation via_records()The singleton context is protected by a double-checked lock for thread safety
Datasets
URI | Database Table | Legacy Alias | Primary Key | Grain |
|
|
|
| One row per fund |
|
|
|
| One row per pledge record |
|
|
|
| One row per project |
Financial stages (in pipeline order): pledge → deposit → approval → disbursement
Tools Reference
Audit Tools (3)
Tool | Description |
| Begin a new audit run; clears previous events and returns a |
| Compact view of tools called in the current run with datasets and columns used |
| Write the full run log to |
Contract Tools (2)
Tool | Description |
| Machine-readable JSON schema contract (call before cross-dataset analysis) |
| Full schema contract as Markdown text |
Discovery Tools (5)
Tool | Description |
| All registered datasets with URI, primary key, grain, and description |
| Row count, column names, dtypes, and null counts |
| First N rows (max 25) |
| Sorted unique non-null values in a column (max 200) |
| Fuzzy-match a user string against real column values — call before passing names to other tools |
Summary Tools (9)
Tool | Description |
| Keyword search across fund name, type, focus, and sector |
| Full dataset record for a single fund |
| Profile card: metadata, stage metrics, portfolio share, and conversion ratios |
| Portfolio-wide totals: fund count, four-stage sums, adaptation/mitigation counts |
| Totals and percentage share by |
| Totals and percentage share by |
| Funds bucketed into adaptation-only / mitigation-only / both / neither |
| Side-by-side comparison of multiple funds |
| Stage totals for portfolio / single fund / fund_type / sector |
Finance Tools (5)
Tool | Description |
| Four pipeline ratios for one fund (deposit/pledge, approval/deposit, disbursement/approval, disbursement/pledge) |
| Rank a grouping column by a finance stage; supports wide and long dataset layouts |
| Rank by any numeric column (non-stage columns, ascending order, any dataset) |
| Return funds where a ratio metric falls below a threshold |
| Absolute gaps between consecutive stages (pledge→deposit, deposit→approval, approval→disbursement) |
Aggregation Tools (1)
Tool | Description |
| Average approved projects per fund grouped by |
Quality Tools (1)
Tool | Description |
| Missing-value counts grouped by a column — audit data completeness before analysis |
Setup
Prerequisites
Python 3.12+
uvpackage manager
Install
git clone <YOUR_REPO_URL>
cd climate_mcp_server
uv syncVerify the environment:
uv run python -c "import pandas; print('pandas ok')"
uv run python -c "from mcp.server.fastmcp import FastMCP; print('mcp ok')"Verify the database exists:
ls "ingestion_layer/data"
# climate_funds.duckdb manifest.json archive/ exports/ raw/ raw_snapshots/ ...Running the Server
Local / STDIO (default)
uv run python mcp_server/finance/server.pyThe process stays running and waits for an MCP client connection over STDIO. Stop with Ctrl+C.
HTTP instead of STDIO
The server uses STDIO by default. For a VM or remote client, set CLIMATE_MCP_TRANSPORT:
Transport |
| Client protocol |
STDIO (default) | unset or | Process stdin/stdout (Claude Desktop, local Cursor) |
SSE |
| HTTP: GET event stream + POST messages (classic MCP remote) |
Streamable HTTP |
| Single HTTP MCP endpoint (newer transport) |
Optional:
CLIMATE_MCP_HOST— bind address (default0.0.0.0for HTTP modes so the VM accepts remote connections;127.0.0.1for STDIO).CLIMATE_MCP_PORT— listen port (default 8000).CLIMATE_MCP_MOUNT_PATH— URL prefix (default/). Non-root mounts apply to every path below.
SSE example (reachable from your laptop on the lab network):
export CLIMATE_MCP_TRANSPORT=sse
export CLIMATE_MCP_HOST=0.0.0.0
export CLIMATE_MCP_PORT=8000
uv run python mcp_server/finance/server.pyOn startup, stderr prints the exact GET (SSE) and POST (messages) URLs. Defaults from FastMCP: /sse and /messages/ under the mount path.
Streamable HTTP example:
export CLIMATE_MCP_TRANSPORT=streamable-http
export CLIMATE_MCP_HOST=0.0.0.0
export CLIMATE_MCP_PORT=8000
uv run python mcp_server/finance/server.pyDefault MCP path: /mcp (see stderr line for the full URL).
Security: there is no authentication on these HTTP endpoints unless you add a reverse proxy (TLS, firewall, API keys). Do not expose them to the public internet without hardening.
You can still use FastMCP’s FASTMCP_* settings (see library docs) for fine-grained paths like FASTMCP_SSE_PATH if needed.
Connecting with Claude Desktop
Find your repo root path:
pwdIn Claude Desktop → Settings → MCP Servers, add a new server:
Name:
financeTransport:
stdioCommand:
uvArgs:
run,python,mcp_server/finance/server.pyWorking directory: your repo root path
Restart Claude Desktop. The 26 tools will appear in the tool picker.
Running Tests
uv run python tests/run_tests.py --allThe test runner requires no external test framework. It runs two layers:
Layer 1 — Unit tests for all 26 tools (tool behaviour, error paths, output envelope)
Layer 2 — Smoke tests for real-world research questions and use cases (UC1–UC4)
Expected output: 111 PASS | 0 FAIL
Run individual layers:
uv run python tests/run_tests.py --layer1 # unit tests only
uv run python tests/run_tests.py --layer2 # smoke tests onlyDependencies
Package | Version | Purpose |
| ≥ 1.26.0 | FastMCP server framework |
| ≥ 3.0.0 | DataFrame processing and aggregations |
| ≥ 1.4.0 | Primary dataset storage and table queries |
| ≥ 0.28.1 | HTTP transport support |
Python ≥ 3.12 required.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/bharathvardhan/Climate-Funds-Update-Integration-for-ClimateGPT-Using-Structured-MCP-Tools'
If you have feedback or need assistance with the MCP directory API, please join our Discord server