Skip to main content

Using Claude Agent SDK with DataDoe MCP

This tutorial shows how to build a small TypeScript app with @anthropic-ai/claude-agent-sdk and connect it to DataDoe MCP. The sample app asks DataDoe for sales data, lets Claude analyze it, and writes a structured JSON report to ./response/.

What you will build

By the end, you will have a simple agent that:

  • connects to DataDoe MCP from Claude Agent SDK
  • uses a local MCP server for the app’s helper tools
  • asks DataDoe for export data, then analyzes it in the agent
  • writes the final result as JSON on disk

Prerequisites

  • Completion of the DataDoe MCP Overview (opens in a new tab) setup with an MCP key
  • Node.js 24 or later
  • A DataDoe organization with an MCP key
  • An Anthropic API key
  • yarn (bundled via Corepack — run corepack enable if needed)

Step 1: Clone and install

Start by installing the project:

bash
1git clone https://github.com/Deltologic/datadoe-mcp-claude-agent-sdk.git
2cd datadoe-mcp-claude-agent-sdk
3yarn install

Step 2: Configure your keys

Copy the example environment file and add your keys:

bash
1cp .env.example .env

Set these values in .env:

  • DATADOE_MCP_KEY: your DataDoe MCP key
  • ANTHROPIC_API_KEY: your Anthropic API key

The app reads the DataDoe key from the environment and sends it to the hosted MCP server.

Step 3: Understand the Claude entry point

The app logic lives in src/index.ts. The important idea is that Claude Agent SDK handles the agent loop, while DataDoe MCP provides the Amazon data.

Here is the core shape:

ts
1import { createSdkMcpServer, query } from '@anthropic-ai/claude-agent-sdk';
2
3import { systemPrompt } from './prompts/system.prompt.ts';
4import { outputTools } from './tools/output.tools.ts';
5import { sleepTools } from './tools/sleep.tools.ts';
6
7const localServer = createSdkMcpServer({
8    name: 'local-tools',
9    tools: [...sleepTools, ...outputTools]
10});
11
12const messages = query({
13    prompt: 'Analyze the Delto UK account for the last 7 days. Find the top 3 ASINs by total units sold.',
14    options: {
15        model: 'sonnet',
16        systemPrompt,
17        mcpServers: {
18            datadoe: {
19                type: 'http',
20                url: 'https://api.datadoe.com/mcp/v1',
21                headers: {
22                    'datadoe-mcp-key': process.env.DATADOE_MCP_KEY ?? ''
23                }
24            },
25            'local-tools': localServer
26        },
27        allowedTools: ['mcp__datadoe__*', 'mcp__local-tools__*'],
28        maxTurns: 10
29    }
30});

There are three parts to notice:

  • query(...) starts the Claude run.
  • mcpServers.datadoe connects Claude to the hosted DataDoe MCP endpoint.
  • createSdkMcpServer(...) exposes local helper tools in the same agent session.

The allowedTools list keeps the agent focused, and maxTurns prevents the run from spinning forever.

Step 4: Why the system prompt matters

The system prompt in src/prompts/system.prompt.ts tells Claude how to use the tools:

ts
1export const systemPrompt = `You are an expert Amazon marketplace data analyst. You have access to DataDoe MCP, which provides live Amazon Seller/Vendor data.
2
3Current time: ${new Date().toISOString()}
4
5## Data access pattern
6
7Use \`mcp__datadoe__exports_raw_download\` to fetch sales data directly. Analyse the returned data inline — no file download or SQL engine is needed.
8
9## Output rule
10
11After completing your analysis you MUST call \`mcp__local-tools__output_top_asins\` exactly once with all results. Never write the final JSON directly in your response textalways route it through that tool.
12`;

This is the part that turns a generic agent into a focused workflow:

  • DataDoe MCP is the source of truth for the Amazon data
  • Claude reasons over the returned data in the conversation
  • the output tool writes one final JSON artifact to disk

Step 5: Keep the output step explicit

The app uses one local tool for the final handoff: output_top_asins in src/tools/output.tools.ts.

ts
1tool(
2    'output_top_asins',
3    'Log the top-ASINs sales report to console and save it to ./response/<timestamp>.json. Call this exactly once with all results.',
4    { asins: z.array(asinSalesSchema) },
5    async ({ asins }) => {
6        const json = JSON.stringify(asins, null, 2);
7        mkdirSync('./response', { recursive: true });
8        const filePath = `./response/top-asins-${Date.now()}.json`;
9        writeFileSync(filePath, json);
10        return { content: [{ type: 'text', text: json }] };
11    }
12);

The prompt instructs Claude to call this tool once, which keeps the final output structured and predictable.

Step 6: Run the app

Start the sample with:

bash
1yarn start

The app will:

  1. ask DataDoe MCP for the required sales export
  2. let Claude identify the top 3 ASINs by units sold
  3. call output_top_asins once
  4. write the result to ./response/top-asins-<timestamp>.json

A simple mental model

If you want to reuse this pattern in another app, keep the split the same:

  • DataDoe MCP for Amazon data access
  • Claude Agent SDK for the agent loop and tool orchestration
  • local tools for file output and any small app-specific helpers

That separation is what keeps the tutorial simple while still showing a real integration.

DataDoe MCP resources

Check the following resources for more information: