AI & automation

Autonomous trading agents with MCP

How to build AI agents that perceive and act on physical-world data using the NTHMAP MCP server.

The Model Context Protocol (MCP) was designed to let AI agents perceive the real world through structured tools rather than scraping HTML. NTHMAP's MCP server turns that promise into working reality for commodity trading, intelligence, logistics, and risk analysis.

This article walks through three concrete agent patterns built on NTHMAP MCP.

Why agents need physical-world context

Current-generation LLMs are astonishingly good at reasoning over text but fundamentally blind to the physical world. Ask ChatGPT "how much crude oil is near the Strait of Hormuz right now?" and you'll get a plausible hallucination. The model knows what Hormuz is and what a VLCC carries, but it has no sensor to actually count the ships.

NTHMAP MCP is that sensor. A single tool call returns a structured, ground-truth answer:

{
  "tool": "analyze_region",
  "arguments": { "bbox": [54, 25, 58, 28] }
}
{
  "total_vessels": 47,
  "commodity_breakdown": {
    "Crude Tanker": 22,
    "LNG Carrier": 8,
    "Chemical Tanker": 6,
    "Bulk Carrier": 7,
    "LPG Carrier": 4
  },
  "est_cargo_mt": 2054785,
  "events_inside": [],
  "infrastructure_inside": [
    {"name": "Port of Fujairah", "asset_type": "port"},
    {"name": "Jebel Ali Port", "asset_type": "port"}
  ]
}

The agent now knows what's actually in Hormuz right now. Everything downstream — analysis, alerting, decision-making — is grounded in real data.

Setup in 2 minutes

If you have Claude Desktop:

  1. Get a NTHMAP Pro API key (instructions)
  2. pip install nthmap-mcp
  3. Add to ~/Library/Application Support/Claude/claude_desktop_config.json: json { "mcpServers": { "nthmap": { "command": "python", "args": ["-m", "nthmap_mcp"], "env": { "NTHMAP_API_KEY": "ntm_live_..." } } } }
  4. Restart Claude

You should see a 🔧 nthmap chip in the chat input. Ask the agent anything about physical flows and it'll call the right tool. Done.

Full setup for Cursor, custom SDK agents, and self-hosted setups is in the MCP docs.

Pattern 1: Morning briefing agent

The simplest useful pattern: a cron-scheduled agent that generates a daily physical-flow briefing for a commodity desk.

# morning_brief.py
import asyncio
from anthropic import Anthropic
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

BRIEFING_PROMPT = """
You are a physical-flow intelligence analyst for a crude oil trading desk.

Write a morning briefing covering:
1. Current state of all strategic chokepoints
2. Crude oil inbound to Europe (vessels, estimated barrels, avg ETA)
3. Notable events affecting physical flows
4. One actionable observation for the desk

Use the NTHMAP tools to get actual data. Be specific and quantitative.
"""

async def main():
    server = StdioServerParameters(
        command="python", args=["-m", "nthmap_mcp"],
        env={"NTHMAP_API_KEY": "ntm_live_..."}
    )
    async with stdio_client(server) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()

            client = Anthropic()
            response = client.messages.create(
                model="claude-opus-4-6",
                max_tokens=2000,
                tools=[{
                    "name": t.name,
                    "description": t.description,
                    "input_schema": t.inputSchema
                } for t in tools.tools],
                messages=[{"role": "user", "content": BRIEFING_PROMPT}],
            )
            # ... agent loop calling tools until stop_reason == "end_turn"

if __name__ == "__main__":
    asyncio.run(main())

Wrap this in a cron job, pipe to email or Slack. You've just replaced a 30-minute morning research ritual with a 3-minute agent run.

Pattern 2: Alerting agent

A longer-running agent that polls for changes and alerts on pattern matches.

The agent's prompt:

Monitor physical-world conditions relevant to an LNG trading book. Check every 15 minutes. Alert me if any of these conditions become true:

  1. A chokepoint status changes from Normal to anything else
  2. A new conflict event appears within 200 km of an active LNG shipping lane
  3. More than 3 US Gulf LNG carriers change destination mid-voyage in a 15-minute window
  4. Any price spread exceeds its 30-day 2-sigma band

When alerting, include the specific data that triggered the alert and a one-sentence trading implication.

The agent uses the MCP tools to check each condition and sends a structured alert to Slack when something matches. You're not writing rule logic in code — you're describing the rules in English.

Pattern 3: Conversational analyst

The highest-value pattern: a chat agent that lets an analyst ask arbitrary questions and gets real-time answers.

Analyst: What's happening in Panama?

Agent (via NTHMAP MCP):

[calls get_chokepoints, filters for Panama] [calls analyze_region(bbox=[-80.5, 8.5, -79.0, 9.8])]

The Panama Canal is currently flagged Congested. There are 18 vessels in the zone with an average speed of 4.9 knots (vs 5.0 normal). The notes field says "Extended wait times 18-24hrs due to low water levels" — this is the ongoing Gatun Lake drought issue.

Of the 18 vessels, 7 are bulk carriers, 5 are container ships, 4 are chemical tankers, and 2 are LPG carriers. No crude tankers currently in the zone (Panamax-class crude tankers rarely use the canal anyway).

Analyst: How does that compare to last month?

Agent: I don't have historical chokepoint data at this moment — NTHMAP tracks live state, not time-series. I can tell you that 18 vessels queued is at the upper end of what I've seen during current sessions, but I'd recommend checking your firm's historical NTHMAP archive or the Panama Canal Authority weekly reports for the trend.

The agent is honest about what it can and can't do, which is exactly the behavior you want from a tool-using agent.

Practical tips

1. Be specific with bboxes

The agent will pass whatever bbox you give it. "Persian Gulf" in human shorthand is a specific box: [47, 24, 57, 30]. Tell the agent these coordinates in your system prompt or ask it to figure them out from world knowledge.

2. Use analyze_region as a one-shot tool

Rather than having the agent call search_vessels + list_events + list_infrastructure separately, have it call analyze_region once with a polygon. You get all three in a single tool call, and the agent's context window stays cleaner.

3. Cache read-heavy queries

The MCP server doesn't do client-side caching. For agents that run against the same region repeatedly, wrap the MCP client in your own memoization layer with a 60-90 second TTL. This also saves on API key rate limit burn.

4. Think about key scopes

Use a read-scoped API key for read-only agents. Create a separate write key only for agents that need to save views or prompts. Revoke unused keys regularly.

5. Respect rate limits

300 requests/minute is a lot, but a runaway agent in a loop can exhaust it in 60 seconds. Set a max tool-call budget in your agent runner (e.g., "abort after 50 tool calls per conversation") as a safety net.

What doesn't work (yet)

Be honest about the limitations:

  • No streaming — the MCP server returns complete responses, not incremental updates. For sub-15-minute latency on vessel positions, you need a direct AIS feed.
  • No historical queries — you can get 24 hours of vessel track but not a month of fleet movements. Enterprise tier adds longer history.
  • No writes to external systems — NTHMAP MCP reads; it doesn't execute trades or send messages. Combine with a separate MCP server (Slack, Telegram, broker API) to close the loop.

Getting started

  1. Get a Pro API key
  2. Install the MCP server
  3. Point your Claude Desktop (or Cursor, or custom SDK agent) at it
  4. Start asking questions

For more patterns and code examples, see the MCP GitHub repo.