Climate MCP Server

Climate MCP Server

Exposes 26 structured analytical tools over Climate Finance Update datasets, enabling fund-level financial analysis, portfolio aggregations, and data quality diagnostics without requiring the client to write data access code.

Category
访问服务器

README

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

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.projects

Design 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 null before 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
cfu://funds analytics.fund fund.csv fund_id One row per fund
cfu://pledges analytics.pledges pledges.csv pledge_id One row per pledge record
cfu://projects analytics.projects projects.csv project_id One row per project

Financial stages (in pipeline order): pledge → deposit → approval → disbursement


Tools Reference

Audit Tools (3)

Tool Description
start_run(query) Begin a new audit run; clears previous events and returns a run_id
get_audit_trail() Compact view of tools called in the current run with datasets and columns used
finalize_run(query?, extra_notes?) Write the full run log to runs/<run_id>.md and clear memory

Contract Tools (2)

Tool Description
get_schema_contract_summary() Machine-readable JSON schema contract (call before cross-dataset analysis)
get_schema_contract() Full schema contract as Markdown text

Discovery Tools (5)

Tool Description
list_datasets() All registered datasets with URI, primary key, grain, and description
describe_dataset(filename?, dataset_uri?) Row count, column names, dtypes, and null counts
preview_dataset(n?, filename?, dataset_uri?) First N rows (max 25)
list_unique_values(column, limit?, filename?, dataset_uri?) Sorted unique non-null values in a column (max 200)
resolve_entity(column, query, top_k?, filename?, dataset_uri?) Fuzzy-match a user string against real column values — call before passing names to other tools

Summary Tools (9)

Tool Description
search_funds(query, limit?) Keyword search across fund name, type, focus, and sector
get_fund_details(fund_id) Full dataset record for a single fund
fund_summary(fund_id) Profile card: metadata, stage metrics, portfolio share, and conversion ratios
portfolio_summary() Portfolio-wide totals: fund count, four-stage sums, adaptation/mitigation counts
sector_summary(metric?, top_n?) Totals and percentage share by fund_focus_sector
fund_type_distribution(metric?, top_n?) Totals and percentage share by fund_type
adaptation_vs_mitigation_summary(metric?) Funds bucketed into adaptation-only / mitigation-only / both / neither
compare_funds(fund_ids, metrics?) Side-by-side comparison of multiple funds
fund_stage_totals(scope, fund_id?, value?) Stage totals for portfolio / single fund / fund_type / sector

Finance Tools (5)

Tool Description
fund_conversion_ratios(fund_name, ...) Four pipeline ratios for one fund (deposit/pledge, approval/deposit, disbursement/approval, disbursement/pledge)
rank_entities(filename, group_by, stage, top_k?, ...) Rank a grouping column by a finance stage; supports wide and long dataset layouts
rank_by_column(filename, group_by, value_column, top_k?, ascending?, filters?) Rank by any numeric column (non-stage columns, ascending order, any dataset)
filter_funds_by_threshold(filename, ratio_metric, threshold, ...) Return funds where a ratio metric falls below a threshold
fund_stage_gap(filename?, fund_col?, fund_name?) Absolute gaps between consecutive stages (pledge→deposit, deposit→approval, approval→disbursement)

Aggregation Tools (1)

Tool Description
avg_projects_per_fund_by_type(source?, agg?, filters_json?) Average approved projects per fund grouped by fund_type; supports fund-table fast path or projects-table fine-grained path with filters

Quality Tools (1)

Tool Description
missing_report(filename, group_by, columns, limit?) Missing-value counts grouped by a column — audit data completeness before analysis

Setup

Prerequisites

  • Python 3.12+
  • uv package manager

Install

git clone <YOUR_REPO_URL>
cd climate_mcp_server
uv sync

Verify 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.py

The 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 CLIMATE_MCP_TRANSPORT Client protocol
STDIO (default) unset or stdio Process stdin/stdout (Claude Desktop, local Cursor)
SSE sse or http HTTP: GET event stream + POST messages (classic MCP remote)
Streamable HTTP streamable-http Single HTTP MCP endpoint (newer transport)

Optional:

  • CLIMATE_MCP_HOST — bind address (default 0.0.0.0 for HTTP modes so the VM accepts remote connections; 127.0.0.1 for 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.py

On 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.py

Default 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

  1. Find your repo root path:

    pwd
    
  2. In Claude Desktop → Settings → MCP Servers, add a new server:

    • Name: finance
    • Transport: stdio
    • Command: uv
    • Args: run, python, mcp_server/finance/server.py
    • Working directory: your repo root path
  3. Restart Claude Desktop. The 26 tools will appear in the tool picker.


Running Tests

uv run python tests/run_tests.py --all

The 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 only

Dependencies

Package Version Purpose
mcp[cli] ≥ 1.26.0 FastMCP server framework
pandas ≥ 3.0.0 DataFrame processing and aggregations
duckdb ≥ 1.4.0 Primary dataset storage and table queries
httpx ≥ 0.28.1 HTTP transport support

Python ≥ 3.12 required.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选