Use the Narwhal API with the Claude Agent SDK

You can use the Claude Agent SDK with Narwhal to ask about holidays, release dates, economics, commodities, FX and predictions. Connect the agent to Narwhal MCP with your API key, then give it a plain question so it can pick the tool.

What you'll set up

The Claude Agent SDK lets you give an agent a question through Python. You will have a script that connects to Narwhal MCP and asks a question for each data area. Its PROMPTS dictionary holds the questions, while ClaudeAgentOptions holds the server connection and tool permissions. The script prints each area name and the messages returned by the agent.

Set your API key

  1. Create a free Narwhal key Create your key at narwhalapi.com/signup. Narwhal uses one account and one API key across its data APIs, so the same key covers the data areas in this script.
  2. Store the key in your environment Put the key in an environment variable named NARWHAL_API_KEY. The Python script reads this variable for the Bearer header, and the Claude Code configuration references it by name. Make the variable available in the environment that starts the agent. Use your key as the environment variable’s value, keeping the Bearer prefix in the header configuration.
    API key environment variable
    export NARWHAL_API_KEY="YOUR_KEY"

Ask through Claude Code

Claude Code users can add Narwhal as an MCP server through a JSON configuration. This is the route for asking questions without writing the Python script. The server address is the same MCP address used by the SDK, and its connection type is http. Use the server configuration for Claude Code and the ClaudeAgentOptions configuration for the Python SDK.

  1. Add the MCP server configuration Add the JSON configuration with narwhal as the server name. Keep the environment variable reference in the Authorization header so the configuration reads your key from NARWHAL_API_KEY.
    MCP server config
    {
      "mcpServers": {
        "narwhal": {
          "type": "http",
          "url": "https://api.narwhalapi.com/mcp",
          "headers": { "Authorization": "Bearer ${NARWHAL_API_KEY}" }
        }
      }
    }
  2. Ask a plain question Ask “Is 25 December 2026 a public holiday in the United States?” The agent picks the tool from the question. The area examples also give questions for release dates, economics, commodities, FX and predictions.

Pull data with code

Install claude-agent-sdk, then use the Python script with your key available in its environment. The mcp_servers setting supplies the MCP URL and Authorization header. The wildcard in allowed_tools lets the agent use every Narwhal tool. Each call to query receives a question and the shared options. The code imports asyncio and os alongside ClaudeAgentOptions and query from the SDK.

Install the SDK
pip install claude-agent-sdk
Claude Agent SDK
import asyncio
import os
from claude_agent_sdk import ClaudeAgentOptions, query

options = ClaudeAgentOptions(
    mcp_servers={
        "narwhal": {
            "type": "http",
            "url": "https://api.narwhalapi.com/mcp",
            "headers": {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"},
        }
    },
    allowed_tools=["mcp__narwhal__*"],
)

PROMPTS = {
    "holidays": "Is 25 December 2026 a public holiday in the United States?",
    "release dates": "When is the US CPI release in November 2026?",
    "economics": "What is the latest US CPI index?",
    "commodities": "What is the Brent spot price in dollars a barrel?",
    "FX": "What are the USD/EUR and USD/IDR rates?",
    "predictions": "What are the Fed rate odds for its next meeting?",
}

async def main():
    for area, question in PROMPTS.items():
        print("##", area)
        async for message in query(prompt=question, options=options):
            print(message)

asyncio.run(main())

Keep the entries in PROMPTS as natural-language questions. They describe the information you want; the agent picks the tool. The loop sends each question separately and prints the messages for that area. To ask about an individual area, use its question with the same options, as in the samples that follow. Inside main, async for prints each message from query before the outer loop moves to another area. The individual samples reuse the imports and options from the full script, with a smaller PROMPTS dictionary containing the area question.

Run it on a schedule

Run the script from cron or a job runner, with NARWHAL_API_KEY available to the scheduled script. Each tool call is one request on the key’s quota. The script loops over the questions in PROMPTS, so a scheduled invocation asks about every area in that dictionary. Keep the questions you want the scheduled agent to ask in that dictionary.

Holidays with the Claude Agent SDK

Ask whether a particular date is a public holiday. This question names both the date and the country. For the REST counterpart, use https://api.narwhalapi.com/v1/calendars/holidays/USA/2026 and read holidays; each entry has date and name. The sample uses the MCP connection already defined in options.

Holiday question
PROMPTS = {
    "holidays": "Is 25 December 2026 a public holiday in the United States?",
}
async def main():
    async for message in query(prompt=PROMPTS["holidays"], options=options):
        print(message)  # REST counterpart field: holidays

asyncio.run(main())

Release dates with the Claude Agent SDK

Ask when a release is scheduled by naming the release and the month. The economic calendar supplies release dates. Its REST counterpart is https://api.narwhalapi.com/v1/economics/calendar?countries=USA&start_date=2026-11-01&end_date=2026-11-30&limit=100. Read releases, whose entries have at, period, topic and status. Use the economics question for the CPI index value.

Release date question
PROMPTS = {
    "release dates": "When is the US CPI release in November 2026?",
}
async def main():
    async for message in query(prompt=PROMPTS["release dates"], options=options):
        print(message)  # REST counterpart field: releases

asyncio.run(main())

Economics with the Claude Agent SDK

Ask for the US CPI index through the economics tools. Narwhal economics also covers inflation, GDP and yields. The CPI REST counterpart is https://api.narwhalapi.com/v1/economics/USA/cpi/observations?start=2025-09, where observations contains entries with period and value. The prompt asks the agent for the index; the REST URL specifies a starting period for observations.

CPI question
PROMPTS = {
    "economics": "What is the latest US CPI index?",
}
async def main():
    async for message in query(prompt=PROMPTS["economics"], options=options):
        print(message)  # REST counterpart field: observations

asyncio.run(main())

Commodities with the Claude Agent SDK

Name the commodity and the units in your question, as the Brent prompt does. The REST counterpart is https://api.narwhalapi.com/v1/commodities/spot/BRENT/USD; read its price field. Narwhal uses spot codes, for example XAU, XAG, XPT, XPD, XCU, BRENT and WTI. This sample keeps the Brent question from the full script.

Brent question
PROMPTS = {
    "commodities": "What is the Brent spot price in dollars a barrel?",
}
async def main():
    async for message in query(prompt=PROMPTS["commodities"], options=options):
        print(message)  # REST counterpart field: price

asyncio.run(main())

FX with the Claude Agent SDK

Ask for the currency pairs you need in the same question. This prompt requests USD/EUR and USD/IDR. The REST counterpart is https://api.narwhalapi.com/v1/fx/rates/USD?currencies=EUR,IDR, which returns rates with currency and rate in each entry. Both the prompt and the URL name the currencies; the MCP agent chooses the tool for the prompt.

Exchange rate question
PROMPTS = {
    "FX": "What are the USD/EUR and USD/IDR rates?",
}
async def main():
    async for message in query(prompt=PROMPTS["FX"], options=options):
        print(message)  # REST counterpart field: rates

asyncio.run(main())

Predictions with the Claude Agent SDK

Ask for Fed rate odds through the predictions tools. The REST counterpart is https://api.narwhalapi.com/v1/predictions/policy-paths/federal-reserve. Read meetings; each entry has resolves_at, p_cut, p_hold and p_hike. These fields describe the resolution time and the cut, hold and hike probabilities. The sample asks the same prediction-market question as the full script.

Fed rate odds question
PROMPTS = {
    "predictions": "What are the Fed rate odds for its next meeting?",
}
async def main():
    async for message in query(prompt=PROMPTS["predictions"], options=options):
        print(message)  # REST counterpart field: meetings

asyncio.run(main())

How do I limit what the agent can call?

Replace the wildcard in allowed_tools with the tool names you want to allow. For CPI, use mcp__narwhal__economics_get_cpi. Set allowed_tools=["mcp__narwhal__economics_get_cpi"] in ClaudeAgentOptions to name that tool explicitly. The full script uses mcp__narwhal__* because its questions span all the data areas.

Do I need my own Claude access?

Yes. The agent needs your own Claude access as well as the Narwhal API key. The Narwhal key authenticates requests to Narwhal, and REST and MCP share that key. For REST requests to the area URLs, send Authorization: Bearer YOUR_KEY; the SDK configuration sends the same header to the MCP address.

Published .