How to integrate Nasa MCP with Vercel AI SDK v6

Trusted by
AWS
Glean
Zoom
Airtable

30 min · no commitment · see it on your stack

Nasa logo
Vercel AI SDK logo
divider

Introduction

This guide walks you through connecting Nasa to Vercel AI SDK v6 using the Composio tool router. By the end, you'll have a working Nasa agent that can show me mars rover photos from curiosity on sol 1000, list recent natural disaster events worldwide, find all eonet event categories available through natural language commands.

This guide will help you understand how to give your Vercel AI SDK agent real control over a Nasa account through Composio's Nasa MCP server.

Before we dive in, let's take a quick look at the key ideas and tools involved.

Also integrate Nasa with

TL;DR

Here's what you'll learn:
  • How to set up and configure a Vercel AI SDK agent with Nasa integration
  • Using Composio's Tool Router to dynamically load and access Nasa tools
  • Creating an MCP client connection using HTTP transport
  • Building an interactive CLI chat interface with conversation history management
  • Handling tool calls and results within the Vercel AI SDK framework

What is Vercel AI SDK?

The Vercel AI SDK is a TypeScript library for building AI-powered applications. It provides tools for creating agents that can use external services and maintain conversation state.

Key features include:

  • streamText: Core function for streaming responses with real-time tool support
  • MCP Client: Built-in support for Model Context Protocol via @ai-sdk/mcp
  • Step Counting: Control multi-step tool execution with stopWhen: stepCountIs()
  • OpenAI Provider: Native integration with OpenAI models

What is the Nasa MCP server, and what's possible with it?

The Nasa MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to NASA's public data APIs. It provides structured and secure access to a wealth of Earth science, planetary, and event data, so your agent can search datasets, fetch Mars rover photos, explore natural events, and visualize scientific information on your behalf.

  • Search NASA science data collections: Empower your agent to query and filter massive datasets from the Common Metadata Repository (CMR) by spatial, temporal, or metadata criteria.
  • Retrieve Mars rover imagery: Ask your agent to fetch stunning photos captured by Mars rovers for specific Martian days, enabling research and exploration right from your workflow.
  • Monitor natural events worldwide: Let your agent pull up-to-date lists of global natural events—like wildfires, storms, or volcanic activity—using NASA's EONET feeds in ATOM or RSS formats.
  • Visualize and analyze event categories and layers: Direct your agent to explore available data layers and event categories for advanced event visualization and filtering in scientific research.
  • Access detailed event source and magnitude data: Have your agent retrieve metadata about event sources and magnitudes, making it easier to understand the context and scale of natural phenomena tracked by NASA.

Supported Tools & Triggers

Tools
Browse Near Earth ObjectsBrowse the complete NASA near-Earth object (asteroid) dataset with pagination support.
Create Graph RequestTool to create orbital and position graphs for NASA satellites using the Satellite Situation Center (SSC) web service.
Delete CMR AssociationTool to delete an existing association between concepts in NASA's Common Metadata Repository.
Delete CMR ACLTool to delete an Access Control List (ACL) from NASA's Common Metadata Repository.
Download Citation DocumentDownloads a document file from a NASA NTRS (NASA Technical Reports Server) citation.
Get AGAGE Data FilesTool to retrieve information about AGAGE (Advanced Global Atmospheric Gases Experiment) data files.
Get AGAGE Data by File NameSearch for AGAGE (Advanced Global Atmospheric Gases Experiment) data files by file name.
Get AGAGE Data JSON for GraphRetrieve AGAGE atmospheric composition data in JSON format optimized for graphing.
Get AGAGE Data VersionsTool to retrieve information on all AGAGE (Advanced Global Atmospheric Gases Experiment) data versions.
Get Astronomy Picture of the DayRetrieves NASA's Astronomy Picture of the Day (APOD) for a specified date or today.
Get Citation by IDTool to retrieve detailed citation information from NASA Technical Reports Server (NTRS) by citation ID.
Get Citation DownloadsTool to retrieve all available download links for a NASA technical report or publication by citation ID.
Get Citation Revision IDTool to retrieve citation revision IDs from NASA Common Metadata Repository (CMR) GraphQL API.
Get Citations AutocompleteTool to get autocomplete suggestions from NASA NTRS (Technical Reports Server) citations.
Get Citations RedistributionsTool to retrieve redistributed citations from NASA's Technical Reports Server (NTRS).
Get CMR CollectionsTool to retrieve collections from the Common Metadata Repository (CMR).
Get CMR GranulesSearch for data granules in NASA's Common Metadata Repository (CMR).
Get AGAGE CompoundsTool to retrieve information on all data compounds available in NASA's AGAGE (Advanced Global Atmospheric Gases Experiment) API.
Get Data by File NameGet information about specific TOLNet (Tropospheric Ozone Lidar Network) data files by file name.
Get AGAGE Data DownloadDownload AGAGE (Advanced Global Atmospheric Gases Experiment) data files by ID.
Get Data FrequenciesRetrieves all available data frequency options from NASA's AGAGE (Advanced Global Atmospheric Gases Experiment) mission.
Get TOLNet Data JSONTool to retrieve JSON versions of TOLNet (Tropospheric Ozone Lidar Network) data by ID.
Get TOLNet Data JSON for GraphTool to retrieve JSON versions of TOLNet data including O3_Number_Density (ozone mixing ratio) and temporal boundaries.
Get DocumentTool to retrieve metadata for a single TOLNet (Tropospheric Ozone Lidar Network) document by ID.
Get Document DownloadDownload a single TOLNet (Tropospheric Ozone Lidar Network) document by ID.
Get TOLNet DocumentsTool to retrieve document information from NASA's TOLNet (Tropospheric Ozone Lidar Network) archive.
Get DONKI CME DataTool to retrieve Coronal Mass Ejection (CME) data from NASA's DONKI database.
Get DONKI CME AnalysisTool to retrieve Coronal Mass Ejection (CME) analysis data from NASA's DONKI (Database Of Notifications, Knowledge, Information) system.
Get DONKI Geomagnetic StormsTool to retrieve Geomagnetic Storm (GST) data from NASA's Space Weather Database Of Notifications, Knowledge, Information (DONKI).
Get DONKI HSS DataTool to retrieve High Speed Stream (HSS) data from NASA's DONKI space weather database.
Get DONKI IPS DataTool to retrieve Interplanetary Shock (IPS) data from NASA's DONKI space weather database.
Get DONKI Magnetopause Crossing DataTool to retrieve Magnetopause Crossing (MPC) events from NASA's DONKI space weather database.
Get DONKI Space Weather NotificationsTool to retrieve space weather notifications from NASA's DONKI (Space Weather Database Of Notifications, Knowledge, Information).
Get DONKI Radiation Belt Enhancement EventsRetrieves Radiation Belt Enhancement (RBE) events from NASA's DONKI Space Weather Database.
Get DONKI SEP EventsGet Solar Energetic Particle (SEP) events from NASA's DONKI space weather database.
Get DONKI Solar FlaresTool to retrieve Solar Flare (FLR) events from NASA's DONKI (Space Weather Database Of Notifications, Knowledge, Information).
Get DONKI WSA-ENLIL SimulationsRetrieve WSA-ENLIL solar wind model simulation data from NASA's DONKI system.
Get EONET CategoriesTool to retrieve a list of all event categories from EONET.
Get EONET Category EventsTool to retrieve natural events filtered by a specific category from NASA's EONET.
Get EONET Event by IDTool to retrieve a specific natural event by its unique ID from NASA's Earth Observatory Natural Event Tracker (EONET).
Get EONET EventsTool to retrieve natural events from NASA's Earth Observatory Natural Event Tracker (EONET).
Get EONET Events (ATOM)Tool to retrieve a list of natural events in ATOM format.
Get EONET Events GeoJSONTool to retrieve natural events from NASA's Earth Observatory Natural Event Tracker (EONET) in GeoJSON format.
Get EONET Events RSSRetrieve natural events from NASA's Earth Observatory Natural Event Tracker (EONET) in RSS/GeoRSS XML format.
Get EONET LayersRetrieves NASA EONET imagery layers for visualizing natural events.
GET EONET MagnitudesTool to retrieve a list of available event magnitudes and their descriptions.
Get EONET SourcesRetrieves the complete list of event data sources available in NASA's EONET (Earth Observatory Natural Event Tracker) system.
Get EPIC Aerosol Imagery MetadataTool to retrieve metadata for the most recent aerosol index imagery from NASA's DSCOVR EPIC camera.
Get EPIC Aerosol Imagery by DateRetrieves metadata for aerosol index imagery from NASA's EPIC camera for a specific date.
Get EPIC Cloud Fraction ImageryRetrieve metadata for the most recent cloud fraction imagery from NASA's DSCOVR EPIC camera.
Get EPIC Cloud Imagery by DateGet metadata for cloud fraction imagery from DSCOVR EPIC camera for a specific date.
Get EPIC Enhanced Color ImageryRetrieves metadata for the most recent enhanced color Earth imagery from the DSCOVR EPIC camera.
Get EPIC Enhanced Color Imagery by DateRetrieves metadata for enhanced color Earth imagery from DSCOVR EPIC for a specific date.
Get EPIC Natural Color ImageryRetrieve metadata for the most recent natural color Earth imagery from NASA's DSCOVR EPIC camera.
Get EPIC Natural Color Images by DateRetrieves metadata for natural color Earth imagery from DSCOVR EPIC for a specific date.
Get File TypesTool to retrieve information on all data file types from NASA's TOLNET API.
Get GeneLab Data System FilesRetrieves file metadata from NASA's GeneLab Data System (GLDS) for specified dataset IDs.
Get ICESat-2 TracksRetrieves a list of ICESat-2 satellite tracks (Reference Ground Tracks - RGTs) within a specified geographic bounding box.
Get Image Asset ManifestRetrieve a media asset's manifest from the NASA Image and Video Library, including links to all available sizes and formats.
Get Image Metadata LocationRetrieve the location URL of a media asset's metadata manifest from the NASA Image and Video Library.
Get InSight Mars Weather DataRetrieves Mars weather data from NASA's InSight lander at Elysium Planitia.
Get Instruments GroupsTool to retrieve information on all instrument groups from NASA's TOLNET API.
Get Landing PageTool to retrieve the NASA STAC API landing page (root endpoint).
Get ICESat-2 Level-3A DataTool to access ICESat-2 Level-3A product data from OpenAltimetry.
Get Mars Rover PhotosRetrieves photos taken by NASA Mars rovers (Perseverance, Curiosity, Opportunity, Spirit) on a specific Martian sol (day).
Get NEO LookupLookup a specific asteroid by its NASA SPK-ID.
Get OSDR BiospecimenTool to retrieve detailed information about a specific biospecimen from NASA's Open Science Data Repository (OSDR).
Get OSDR ExperimentRetrieve detailed information about a specific OSDR (Open Science Data Repository) experiment by its identifier.
Get OSDR HardwareRetrieve detailed information about specific hardware from NASA's Open Science Data Repository (OSDR).
Get OSDR Study MetadataRetrieve complete metadata for an OSDR (Open Science Data Repository) study dataset.
Get OSDR Mission DetailsRetrieve detailed information about a specific space mission from NASA's Open Science Data Repository (OSDR).
Get OSDR Payload DetailsRetrieve detailed metadata for a specific OSDR payload by its identifier.
Get OSDR Subject InformationRetrieve detailed information about a specific subject (biospecimen) from NASA's Open Science Data Repository (OSDR).
Get OSDR Vehicle InformationRetrieve detailed information about a specific vehicle from NASA's Open Science Data Repository (OSDR).
Get POWER Climatology DataRetrieves long-term climatology data for a specific location from NASA POWER (Prediction Of Worldwide Energy Resources).
Get POWER Daily DataRetrieves daily average solar and meteorological data from NASA POWER (Prediction Of Worldwide Energy Resources).
Get POWER Daily Regional DataTool to retrieve daily average solar and meteorological data for a regional bounding box from NASA POWER (Prediction Of Worldwide Energy Resources).
Get POWER Monthly DataRetrieves monthly average solar and meteorological data for a specific location from NASA POWER (Prediction Of Worldwide Energy Resources).
Get POWER Hourly Temporal DataRetrieves hourly climate and meteorological data from NASA POWER (Prediction of Worldwide Energy Resources) API for a specific location and date range.
Get Processing TypesTool to retrieve information on all data instruments from NASA's AGAGE mission.
Get Product TypesTool to retrieve all data product types from NASA's TOLNET (TOLNet Ozone Lidar Network) API.
Get Satellite LocationsRetrieves satellite location data from NASA's Satellite Situation Center (SSC).
Get AGAGE Data StationsTool to retrieve information on all AGAGE (Advanced Global Atmospheric Gases Experiment) data stations.
Get TechPort ProjectRetrieves detailed information about a specific NASA technology project from TechPort.
Get TOLNet DataTool to retrieve information about TOLNet (Tropospheric Ozone Lidar Network) data files.
Get TOLNet Data CalendarTool to retrieve a date-driven list of all available TOLNet (Tropospheric Ozone Lidar Network) data.
Get Video CaptionsRetrieves the location URL of caption files for NASA video assets from the NASA Image and Video Library.
List EPIC Aerosol DatesTool to retrieve a list of all dates with available aerosol index EPIC imagery.
List EPIC Cloud Fraction DatesRetrieve a listing of all dates with available cloud fraction Earth imagery from DSCOVR EPIC.
List EPIC Enhanced Color DatesRetrieves a listing of all dates with available enhanced color Earth imagery from NASA's DSCOVR EPIC (Earth Polychromatic Imaging Camera).
List EPIC Natural Color DatesRetrieve a listing of all dates with available natural color Earth imagery from DSCOVR EPIC.
List Ground StationsRetrieves the complete list of ground stations available from NASA's Satellite Situation Center (SSC).
List Satellite Locations (GSE/GEO)Retrieves satellite/observatory location data in GSE and GEO coordinate systems from NASA's SSC (Satellite Situation Center).
List ObservatoriesTool to retrieve descriptions of all observatories available from NASA's Satellite Situation Center (SSC).
List OSDR BiospecimensTool to retrieve a list of all biospecimens from the NASA Open Science Data Repository (OSDR).
List OSDR ExperimentsTool to retrieve a list of all experiments from NASA's Open Science Data Repository (OSDR).
List OSDR HardwareTool to retrieve a list of all hardware from NASA's Open Science Data Repository (OSDR).
List OSDR MissionsTool to retrieve a list of all space missions from the NASA Open Science Data Repository (OSDR).
List OSDR PayloadsTool to retrieve a list of all payloads from the NASA Open Science Data Repository (OSDR).
List OSDR SubjectsTool to retrieve a list of all subjects from the NASA Open Science Data Repository (OSDR).
List OSDR VehiclesTool to retrieve a list of all vehicles from the NASA Open Science Data Repository (OSDR).
Query CitationTool to query citation metadata from NASA's GraphQL Earthdata API.
Query Citations via GraphQLTool to query NASA Common Metadata Repository (CMR) GraphQL API for collection citations.
Query CMR CollectionTool to query a single collection from NASA's Common Metadata Repository using its unique concept ID.
Query CMR CollectionsTool to query multiple collections from NASA's Common Metadata Repository via GraphQL.
Query CMR Granule by Concept IDQuery for a single granule (individual data file) from NASA's Common Metadata Repository using its unique concept ID.
Query CMR GranulesTool to query for multiple granules (individual data files) from NASA's Common Metadata Repository via GraphQL.
Query CMR GridsQuery for multiple grids from NASA's Common Metadata Repository (CMR) via GraphQL.
Query CMR ServiceTool to query a single service from NASA's Common Metadata Repository using its unique concept ID.
Query CMR ServicesTool to query for multiple services from NASA's Common Metadata Repository via GraphQL.
Query CMR SubscriptionTool to query a single subscription from NASA's Common Metadata Repository using its unique concept ID.
Query CMR SubscriptionsQuery for multiple subscriptions from NASA's Common Metadata Repository (CMR).
Query CMR ToolTool to query a single tool from NASA's Common Metadata Repository using its unique concept ID.
Query CMR ToolsTool to query multiple tools from NASA's Common Metadata Repository using GraphQL.
Query CMR VariableTool to query a single variable from NASA's Common Metadata Repository using its unique concept ID.
Query Collection DraftTool to query a NASA Earthdata collection draft by ID using the GraphQL API.
Query Data Quality SummariesQuery data quality summaries from NASA's Common Metadata Repository (CMR) GraphQL API.
Query Data Quality SummaryQuery for a single Data Quality Summary from NASA's Common Metadata Repository (CMR) using GraphQL.
Query Exoplanet ArchiveTool to query NASA's Exoplanet Archive NSTED API for exoplanet and related astronomical data.
Query Order OptionTool to query a single order option from NASA Earthdata GraphQL API.
Query Order OptionsTool to query order options for a NASA Earthdata collection using the GraphQL API.
Query PermissionsTool to query permissions from NASA's Common Metadata Repository (CMR) GraphQL API.
Query CMR ProvidersTool to query for a list of data providers from NASA's Common Metadata Repository via GraphQL.
Query Tag DefinitionsTool to query tag definitions from NASA's Common Metadata Repository (CMR) GraphQL API.
Query Tool DraftTool to query a tool draft from NASA's Common Metadata Repository (CMR) GraphQL API.
Query VisualizationTool to query a single visualization from NASA's Common Metadata Repository using its unique concept ID.
Query VisualizationsTool to query for visualizations from NASA's Common Metadata Repository via GraphQL.
Restore Citation RevisionTool to restore a previous version of a citation record within NASA's Common Metadata Repository.
Restore Collection RevisionTool to restore a collection to a previous revision in NASA's Common Metadata Repository.
Restore Visualization RevisionTool to restore a previous revision of a visualization in NASA's Common Metadata Repository.
Search NTRS CitationsTool to search NASA Technical Reports Server (NTRS) citations database.
Search Near Earth ObjectsSearch for near-Earth objects (asteroids) by their closest approach date to Earth.
Search OSDRTool to search NASA Open Science Data Repository (OSDR) for space biology experiments and studies.
Search Public Space DocumentsSearch NASA public space technical documents in the NTRS (NASA Technical Reports Server) repository.
Search SVS VisualizationsTool to search for visualizations in the Scientific Visualization Studio (SVS).
Search Technology Transfer SoftwareSearch NASA's Technology Transfer software catalog for available tools and applications.

What is the Composio tool router, and how does it fit here?

What is Composio SDK?

Composio's Composio SDK helps agents find the right tools for a task at runtime. You can plug in multiple toolkits (like Gmail, HubSpot, and GitHub), and the agent will identify the relevant app and action to complete multi-step workflows. This can reduce token usage and improve the reliability of tool calls. Read more here: Getting started with Composio SDK

The tool router generates a secure MCP URL that your agents can access to perform actions.

How the Composio SDK works

The Composio SDK follows a three-phase workflow:

  1. Discovery: Searches for tools matching your task and returns relevant toolkits with their details.
  2. Authentication: Checks for active connections. If missing, creates an auth config and returns a connection URL via Auth Link.
  3. Execution: Executes the action using the authenticated connection.

Step-by-step Guide

Prerequisites

Before you begin, make sure you have:
  • Node.js and npm installed
  • A Composio account with API key
  • An OpenAI API key

Getting API Keys for OpenAI and Composio

OpenAI API Key
  • Go to the OpenAI dashboard and create an API key. You'll need credits to use the models, or you can connect to another model provider.
  • Keep the API key safe.
Composio API Key
  • Log in to the Composio dashboard.
  • Navigate to your API settings and generate a new API key.
  • Store this key securely as you'll need it for authentication.

Install required dependencies

bash
npm install @ai-sdk/openai @ai-sdk/mcp @composio/core ai dotenv

First, install the necessary packages for your project.

What you're installing:

  • @ai-sdk/openai: Vercel AI SDK's OpenAI provider
  • @ai-sdk/mcp: MCP client for Vercel AI SDK
  • @composio/core: Composio SDK for tool integration
  • ai: Core Vercel AI SDK
  • dotenv: Environment variable management

Set up environment variables

bash
OPENAI_API_KEY=your_openai_api_key_here
COMPOSIO_API_KEY=your_composio_api_key_here
COMPOSIO_USER_ID=your_user_id_here

Create a .env file in your project root.

What's needed:

  • OPENAI_API_KEY: Your OpenAI API key for GPT model access
  • COMPOSIO_API_KEY: Your Composio API key for tool access
  • COMPOSIO_USER_ID: A unique identifier for the user session

Import required modules and validate environment

typescript
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { Composio } from "@composio/core";
import * as readline from "readline";
import { streamText, type ModelMessage, stepCountIs } from "ai";
import { createMCPClient } from "@ai-sdk/mcp";

const composioAPIKey = process.env.COMPOSIO_API_KEY;
const composioUserID = process.env.COMPOSIO_USER_ID;

if (!process.env.OPENAI_API_KEY) throw new Error("OPENAI_API_KEY is not set");
if (!composioAPIKey) throw new Error("COMPOSIO_API_KEY is not set");
if (!composioUserID) throw new Error("COMPOSIO_USER_ID is not set");

const composio = new Composio({
  apiKey: composioAPIKey,
});
What's happening:
  • We're importing all necessary libraries including Vercel AI SDK's OpenAI provider and Composio
  • The dotenv/config import automatically loads environment variables
  • The MCP client import enables connection to Composio's tool server

Create Tool Router session and initialize MCP client

typescript
async function main() {
  // Create a tool router session for the user
  const session = await composio.create(composioUserID!, {
    toolkits: ["nasa"],
  });

  const mcpUrl = session.mcp.url;
What's happening:
  • We're creating a Tool Router session that gives your agent access to Nasa tools
  • The create method takes the user ID and specifies which toolkits should be available
  • The returned mcp object contains the URL and authentication headers needed to connect to the MCP server
  • This session provides access to all Nasa-related tools through the MCP protocol

Connect to MCP server and retrieve tools

typescript
const mcpClient = await createMCPClient({
  transport: {
    type: "http",
    url: mcpUrl,
    headers: session.mcp.headers, // Authentication headers for the Composio MCP server
  },
});

const tools = await mcpClient.tools();
What's happening:
  • We're creating an MCP client that connects to our Composio Tool Router session via HTTP
  • The mcp.url provides the endpoint, and mcp.headers contains authentication credentials
  • The type: "http" is important - Composio requires HTTP transport
  • tools() retrieves all available Nasa tools that the agent can use

Initialize conversation and CLI interface

typescript
let messages: ModelMessage[] = [];

console.log("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
console.log(
  "Ask any questions related to nasa, like summarize my last 5 emails, send an email, etc... :)))\n",
);

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: "> ",
});

rl.prompt();
What's happening:
  • We initialize an empty messages array to maintain conversation history
  • A readline interface is created to accept user input from the command line
  • Instructions are displayed to guide the user on how to interact with the agent

Handle user input and stream responses with real-time tool feedback

typescript
rl.on("line", async (userInput: string) => {
  const trimmedInput = userInput.trim();

  if (["exit", "quit", "bye"].includes(trimmedInput.toLowerCase())) {
    console.log("\nGoodbye!");
    rl.close();
    process.exit(0);
  }

  if (!trimmedInput) {
    rl.prompt();
    return;
  }

  messages.push({ role: "user", content: trimmedInput });
  console.log("\nAgent is thinking...\n");

  try {
    const stream = streamText({
      model: openai("gpt-5"),
      messages,
      tools,
      toolChoice: "auto",
      stopWhen: stepCountIs(10),
      onStepFinish: (step) => {
        for (const toolCall of step.toolCalls) {
          console.log(`[Using tool: ${toolCall.toolName}]`);
          }
          if (step.toolCalls.length > 0) {
            console.log(""); // Add space after tool calls
          }
        },
      });

      for await (const chunk of stream.textStream) {
        process.stdout.write(chunk);
      }

      console.log("\n\n---\n");

      // Get final result for message history
      const response = await stream.response;
      if (response?.messages?.length) {
        messages.push(...response.messages);
      }
    } catch (error) {
      console.error("\nAn error occurred while talking to the agent:");
      console.error(error);
      console.log(
        "\nYou can try again or restart the app if it keeps happening.\n",
      );
    } finally {
      rl.prompt();
    }
  });

  rl.on("close", async () => {
    await mcpClient.close();
    console.log("\n👋 Session ended.");
    process.exit(0);
  });
}

main().catch((err) => {
  console.error("Fatal error:", err);
  process.exit(1);
});
What's happening:
  • We use streamText instead of generateText to stream responses in real-time
  • toolChoice: "auto" allows the model to decide when to use Nasa tools
  • stopWhen: stepCountIs(10) allows up to 10 steps for complex multi-tool operations
  • onStepFinish callback displays which tools are being used in real-time
  • We iterate through the text stream to create a typewriter effect as the agent responds
  • The complete response is added to conversation history to maintain context
  • Errors are caught and displayed with helpful retry suggestions

Complete Code

Here's the complete code to get you started with Nasa and Vercel AI SDK:

typescript
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { Composio } from "@composio/core";
import * as readline from "readline";
import { streamText, type ModelMessage, stepCountIs } from "ai";
import { createMCPClient } from "@ai-sdk/mcp";

const composioAPIKey = process.env.COMPOSIO_API_KEY;
const composioUserID = process.env.COMPOSIO_USER_ID;

if (!process.env.OPENAI_API_KEY) throw new Error("OPENAI_API_KEY is not set");
if (!composioAPIKey) throw new Error("COMPOSIO_API_KEY is not set");
if (!composioUserID) throw new Error("COMPOSIO_USER_ID is not set");

const composio = new Composio({
  apiKey: composioAPIKey,
});

async function main() {
  // Create a tool router session for the user
  const session = await composio.create(composioUserID!, {
    toolkits: ["nasa"],
  });

  const mcpUrl = session.mcp.url;

  const mcpClient = await createMCPClient({
    transport: {
      type: "http",
      url: mcpUrl,
      headers: session.mcp.headers, // Authentication headers for the Composio MCP server
    },
  });

  const tools = await mcpClient.tools();

  let messages: ModelMessage[] = [];

  console.log("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
  console.log(
    "Ask any questions related to nasa, like summarize my last 5 emails, send an email, etc... :)))\n",
  );

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: "> ",
  });

  rl.prompt();

  rl.on("line", async (userInput: string) => {
    const trimmedInput = userInput.trim();

    if (["exit", "quit", "bye"].includes(trimmedInput.toLowerCase())) {
      console.log("\nGoodbye!");
      rl.close();
      process.exit(0);
    }

    if (!trimmedInput) {
      rl.prompt();
      return;
    }

    messages.push({ role: "user", content: trimmedInput });
    console.log("\nAgent is thinking...\n");

    try {
      const stream = streamText({
        model: openai("gpt-5"),
        messages,
        tools,
        toolChoice: "auto",
        stopWhen: stepCountIs(10),
        onStepFinish: (step) => {
          for (const toolCall of step.toolCalls) {
            console.log(`[Using tool: ${toolCall.toolName}]`);
          }
          if (step.toolCalls.length > 0) {
            console.log(""); // Add space after tool calls
          }
        },
      });

      for await (const chunk of stream.textStream) {
        process.stdout.write(chunk);
      }

      console.log("\n\n---\n");

      // Get final result for message history
      const response = await stream.response;
      if (response?.messages?.length) {
        messages.push(...response.messages);
      }
    } catch (error) {
      console.error("\nAn error occurred while talking to the agent:");
      console.error(error);
      console.log(
        "\nYou can try again or restart the app if it keeps happening.\n",
      );
    } finally {
      rl.prompt();
    }
  });

  rl.on("close", async () => {
    await mcpClient.close();
    console.log("\n👋 Session ended.");
    process.exit(0);
  });
}

main().catch((err) => {
  console.error("Fatal error:", err);
  process.exit(1);
});

Conclusion

You've successfully built a Nasa agent using the Vercel AI SDK with streaming capabilities! This implementation provides a powerful foundation for building AI applications with natural language interfaces and real-time feedback.

Key features of this implementation:

  • Real-time streaming responses for a better user experience with typewriter effect
  • Live tool execution feedback showing which tools are being used as the agent works
  • Dynamic tool loading through Composio's Tool Router with secure authentication
  • Multi-step tool execution with configurable step limits (up to 10 steps)
  • Comprehensive error handling for robust agent execution
  • Conversation history maintenance for context-aware responses

You can extend this further by adding custom error handling, implementing specific business logic, or integrating additional Composio toolkits to create multi-app workflows.

How to build Nasa MCP Agent with another framework

FAQ

What are the differences in Tool Router MCP and Nasa MCP?

With a standalone Nasa MCP server, the agents and LLMs can only access a fixed set of Nasa tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Nasa and many other apps based on the task at hand, all through a single MCP endpoint.

Can I use Tool Router MCP with Vercel AI SDK v6?

Yes, you can. Vercel AI SDK v6 fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right Nasa tools.

Can I manage the permissions and scopes for Nasa while using Tool Router?

Yes, absolutely. You can configure which Nasa scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your Nasa data and credentials are handled as safely as possible.

Used by agents from

Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai

Never worry about agent reliability

We handle tool reliability, observability, and security so you never have to second-guess an agent action.