To add a new capability to the Earthdata MCP server, follow these steps to build and register a new tool.
Create a new folder under tools/ with your tool's name (e.g., tools/get_weather/).
You must include at least three files in your new directory:
A. manifest.json
This file defines the tool's metadata for the MCP client. The loader automatically registers the tool using this file.
{
"name": "get_weather",
"description": "A detailed description of when the LLM should use this tool.",
"version": "0.1.0",
"entry_function": "get_weather"
}- Important: You MUST include a
"version"string following Semantic Versioning (SemVer).
B. tool.py
The actual Python implementation.
- The primary function name must exactly match the
"entry_function"in yourmanifest.json. - The function MUST be synchronous (
def, notasync def). The server automatically wraps it in an async handler.
from models.tools.get_weather import GetWeatherInput, GetWeatherOutput
def get_weather(location: str) -> dict:
"""Fetches the weather for a location."""
# FastMCP infers the input schema from the function signature.
# Using Pydantic parameters (or GetWeatherInput) is recommended.
return GetWeatherOutput(status="success", temperature=72).model_dump()C. output_model.py
A Pydantic output model. Keep exactly one BaseModel subclass in this file; the loader registers the first matching model it finds when inspecting the module.
from pydantic import BaseModel
class GetWeatherOutput(BaseModel):
status: str
temperature: intIf you added a new root-level Python directory (e.g., you created a prompts/ or config/ folder outside of tools/), you MUST update both the Dockerfile and the .dockerignore file.
If you forget either of these, the AWS ECS container will crash with a ModuleNotFoundError on startup because the strict ignore policy will strip the files from the build context!
1. Add to McpServerDockerfile:
COPY models/ models/
COPY tools/ tools/
COPY util/ util/
COPY new_folder/ new_folder/ # Add your new folder here!2. Allowlist in McpServerDockerfile.dockerignore:
# util/
!util/
# new_folder/
!new_folder/ # Add your new folder here!
Every tool must include a "version" string in its manifest.json following Semantic Versioning (SemVer). You must bump this version whenever you change the tool's inputs, outputs, or LLM-facing behavior.
See Versioning Methodology for detailed policies on when to bump Major, Minor, or Patch versions for individual tools vs. the entire MCP Server.
- Run the server locally (
uv run server.py http). - Launch the MCP inspector (
npx @modelcontextprotocol/inspector) to verify the LLM can see your tool's schema. - Write
pytestcoverage under thetests/directory.