nasa

nasa

MCP server that wraps three NASA public APIs (Astronomy Picture of the Day, Mars rover photos, and near-Earth objects) as tools for AI assistants.

Category
Visit Server

README

NASA MCP Server

A small but complete Model Context Protocol (MCP) server you can deploy to Google Cloud Run. It wraps three of NASA's free public APIs as tools an AI assistant can call.

This is built as a learning project, so the code and these notes explain the why, not just the how.


What is an MCP server, briefly

MCP is a standard way to expose tools (callable functions), resources (readable data), and prompts (templates) to an AI model. Think of it as a web API designed specifically for LLMs. This project uses tools only.

There are two transports:

  • stdio — the server runs as a local subprocess. Used by desktop apps (Claude Desktop, Cursor, IDE plugins). Not what we want here.
  • streamable HTTP — the server runs as a normal web service reachable over a URL. This is the one you use to host on Cloud Run. All MCP traffic flows through a single endpoint at /mcp.

Project structure

nasa-mcp-server/
├── server.py          # the MCP server + 3 NASA tools
├── requirements.txt   # mcp + httpx
├── Dockerfile         # container image for Cloud Run
└── .dockerignore

The three tools:

Tool What it does
get_astronomy_picture NASA's Astronomy Picture of the Day (optionally for a past date)
get_mars_photos Photos from a Mars rover on a given Earth date
get_near_earth_objects Asteroids passing near Earth in a date range

Step 1 — Get a NASA API key

  1. Go to https://api.nasa.gov/ and fill in the short form (name + email).
  2. The key is emailed to you within a few minutes. No credit card. Registered keys allow ~1,000 requests/hour.

You can skip this at first: the code falls back to NASA's shared DEMO_KEY, which works instantly but is heavily rate-limited (you'll see 429 errors fast).

Do not paste your key into source code or share it in chat. The server reads it from the NASA_API_KEY environment variable. Locally that's an export; on Cloud Run it's a Secret Manager secret (Step 4).


Step 2 — Run it locally

cd nasa-mcp-server
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

export NASA_API_KEY=your_key_here     # omit to use DEMO_KEY
python server.py

The server starts on http://localhost:8080/mcp.


Step 3 — Test with the MCP Inspector

The Inspector is the official tool for poking at an MCP server by hand. With the server running, in another terminal:

npx @modelcontextprotocol/inspector

In the Inspector UI: set transport to Streamable HTTP, URL to http://localhost:8080/mcp, connect, then open the Tools tab and run get_astronomy_picture with no arguments. You should get back today's picture.


Step 4 — Deploy to Google Cloud Run

Prerequisites: a GCP project with billing enabled and the gcloud CLI installed and authenticated (gcloud auth login).

# Set your project and a region close to you
gcloud config set project YOUR_PROJECT_ID
gcloud config set run/region australia-southeast1   # Sydney; pick your own

# Enable the services we need
gcloud services enable run.googleapis.com \
                       cloudbuild.googleapis.com \
                       secretmanager.googleapis.com

4a. Store your NASA key in Secret Manager

Never bake the key into the image. Create a secret instead:

printf '%s' 'YOUR_NASA_KEY' | gcloud secrets create nasa-api-key --data-file=-

4b. Deploy from source

gcloud builds the container from the Dockerfile and deploys it in one step:

gcloud run deploy nasa-mcp \
  --source . \
  --allow-unauthenticated \
  --set-secrets=NASA_API_KEY=nasa-api-key:latest

When prompted to grant the runtime service account access to the secret, say yes (or run gcloud secrets add-iam-policy-binding nasa-api-key --member="serviceAccount:$(gcloud run services describe nasa-mcp --format='value(spec.template.spec.serviceAccountName)')" --role="roles/secretmanager.secretAccessor").

Notes:

  • You do not set PORT — Cloud Run injects it and server.py reads it.
  • On success you get a URL like https://nasa-mcp-xxxxxxxx.run.app. Your MCP endpoint is that URL plus /mcp.

Quick check it's alive:

curl -X POST https://nasa-mcp-xxxxxxxx.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

A JSON response with "serverInfo":{"name":"nasa",...} means you're live.


Step 5 — Connect it to Claude

Point the MCP Inspector at your live https://.../mcp URL first to confirm the tools work remotely. To use it in Claude, add it as a custom connector in Claude's settings (Settings → Connectors), pasting your /mcp URL. The exact menu wording changes over time — see the current connector docs at https://support.claude.com. Then ask Claude something like "what's NASA's astronomy picture of the day?" and it will call your tool.


⚠️ About --allow-unauthenticated

The deploy command above makes your server publicly reachable by anyone with the URL. For a learning project that's fine, but be aware: strangers could call it and burn through your NASA rate limit. Before relying on it, lock it down. Reasonable next steps, easiest first:

  1. Require a bearer token — add a check in the server for a shared secret in the Authorization header, and supply that header from the client.
  2. Keep the service private (drop --allow-unauthenticated) and require Google IAM auth, putting an authenticating proxy in front for Claude.
  3. Full OAuth 2.1, which the MCP spec defines for remote servers. FastMCP has helpers for this — it's the "proper" answer but the most work.

How the code maps to MCP concepts

  • FastMCP(name="nasa", ...) creates the server. stateless_http=True and json_response=True are the recommended settings for a scalable HTTP deployment — Cloud Run may run several container instances, and stateless mode means none of them rely on in-memory session state.
  • Each @mcp.tool() function becomes a callable tool. The docstring is the description the model sees, and the type hints become the input schema — so writing clear docstrings and precise types is the single highest-leverage thing you can do for tool quality.
  • mcp.run(transport="streamable-http") serves everything at /mcp.

Ideas to extend it

  • Add a tool for NASA's EPIC (full-disc Earth imagery) or EONET (natural-event tracking) endpoints — same _nasa_get helper, new path.
  • Swap NASA for a different free API (weather, exchange rates, etc.) — only the tool bodies change; the server scaffolding and deployment stay identical.
  • Add an MCP resource (read-only data) alongside the tools.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured