MCP server by nasa
earthdata-mcp
MCP Server — Project Overview
This repository implements a modular MCP (Model Context Protocol) server with support for multiple transport modes (STDIO, HTTP, SSE). Tools are organized under the tools/ directory, and each tool is self-contained with its own Python implementation and manifest.
Project Structure
mcp/
│
├── tools/ # All MCP tools live here
│ └── <toolname>/ # Each tool is fully self-contained
│ ├── tool.py # Python implementation of the tool
│ ├── manifest.json # MCP tool metadata (incl. entry function)
│
├── tests/ # All Pytest test files live here
│ ├── test_<tool>.py
│
├── util/ # Any utility functions common to all tools.
│
├── loader.py # Discovers tools, loads manifest, registers functions
├── server.py # Entry point for STDIO / HTTP / SSE server
├── pyproject.toml # Dependencies & project configuration
└── README.md # This file
Quick Start
Installation
-
Clone the repository and navigate to the MCP folder:
cd mcp -
Create and activate virtual environment:
python3 -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate -
Install dependencies:
uv sync
Running the MCP Server
The server supports three primary modes: STDIO, HTTP, and SSE.
HTTP Mode (Development & Testing)
Run the server as a web server using Uvicorn:
PYTHONPATH=.. uv run server.py http
PYTHONPATH=..ensures imports work from project roothttptells the server to run in HTTP mode- Server runs at
http://127.0.0.1:5001/mcp
STDIO Mode
Follow the fastmcp integrations to integrate with you AI of choice
SSE Mode
Note: SSE had been deprecated by fastmcp and been replaced with streamable http
Testing
Run All Tests
pytest
Test File Structure
All tests now live in:
mcp/tests/test_*.py
Example Pytest
import pytest
from mcp.server.fastmcp import FastMCP
from tools.my_new_tool.tool import my_new_tool, MyInput
@pytest.mark.asyncio
async def test_my_new_tool_direct():
result = await my_new_tool(MyInput(input_text="Hello"))
assert "Hello" in result[0]
@pytest.mark.asyncio
async def test_my_new_tool_via_mcp():
mcp = FastMCP("test_server")
mcp.register_tool("my_new_tool", my_new_tool)
result = await mcp.call_tool("my_new_tool", {"input_text": "Test"})
assert result
Test via MCP Inspector (Interactive Testing) (RECOMMENDED)
The MCP Inspector provides a visual interface for testing tools:
-
Start the MCP server in HTTP mode:
PYTHONPATH=.. uv run server.py http -
Launch MCP Inspector:
npx @modelcontextprotocol/inspectorOpens at
http://localhost:6274 -
Connect to your MCP server:
- Streamable HTTP
- Transport Type: Streamable HTTP
- URL:
http://localhost:5001/mcp - Connection Type: Direct
- STDIO
- Transport Type: STDIO
- Command: uv
- Arguments: run server.py stdio
-
Test your tools:
- Click "List Tools" to see all available tools
- Select a tool to test
- Enter input parameters
- Click "Run Tool"
- Debug errors and validate output
Test via Chainlit Application
Test your tools in a chat interface:
-
Navigate to the chat application:
cd ../chat -
Activate Chainlit environment:
source .chainlit/bin/activate -
Run the Chainlit app:
NOMINATIM_USER_AGENT=chainlit chainlit run app.py -w -
Connect to MCP in browser:
- Open
http://localhost:8000 - Click the tools icon (🔧)
- Click "Connect an MCP"
- Enter settings:
- Type: streamable-http
- Name: cmr-mcps
- HTTP URL:
http://localhost:5001/mcp
- Open
-
Your tools will appear under "Tools" menu
How Tools Get Loaded
loader.py automatically:
- Scans the
tools/directory - Validates each
manifest.json - Imports the tool's
tool.py - Loads the function specified in "entry"
- Registers it with the MCP server
No manual configuration needed! Just add your tool folder and it's automatically discovered.
Troubleshooting
Import Errors
- Ensure
PYTHONPATH=..is set when running - Check all dependencies are installed
- Verify virtual environment is activated
Contributing
When adding a new tool:
- ✅ Follow the folder structure
- ✅ Include
manifest.jsonandtool.py - ✅ Ensure manifest specifies "entry"
- ✅ Write pytest files under tests/
- ✅ Test with MCP Inspector
- ✅ Run pytest before committing