> Note: This page is part of the DataDoe Docs. You can find the root of the documentation at `https://www.datadoe.com/hub/docs/basics/introduction-to-datadoe`.
> JSON Table of Contents: `https://www.datadoe.com/hub/docs/toc.json`.
> Direct Data Scheme JSON: `https://api.datadoe.com/api/v1/spec/data-scheme`.
> Other pages in the DataDoe Docs:
> - DataDoe Basics/Access & Users: `https://www.datadoe.com/hub/docs/basics/access-user-management.md`
> - DataDoe Basics/Benefits: `https://www.datadoe.com/hub/docs/basics/benefits.md`
> - DataDoe Basics/External Invitation Links: `https://www.datadoe.com/hub/docs/basics/external-invitation-links.md`
> - DataDoe Basics/Integrations: `https://www.datadoe.com/hub/docs/basics/integration-customization.md`
> - DataDoe Basics/Introduction to DataDoe: `https://www.datadoe.com/hub/docs/basics/introduction-to-datadoe.md`
> - DataDoe Basics/Subscription & Pricing: `https://www.datadoe.com/hub/docs/basics/subscription-pricing.md`
> - DataDoe Data/Data Fetch Periods: `https://www.datadoe.com/hub/docs/datadoe-data/data-fetch-periods.md`
> - DataDoe Data/Data Sources: `https://www.datadoe.com/hub/docs/datadoe-data/data-sources.md`
> - DataDoe Data/Timezones: `https://www.datadoe.com/hub/docs/datadoe-data/orders-purchase-date-timezones.md`
> - DataDoe Features/Features Overview: `https://www.datadoe.com/hub/docs/datadoe-features/overview.md`
> - DataDoe MCP/Overview: `https://www.datadoe.com/hub/docs/datadoe-mcp/overview.md`
> - DataDoe MCP/Using ChatGPT: `https://www.datadoe.com/hub/docs/datadoe-mcp/chatgpt.md`
> - DataDoe MCP/Using Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/claude.md`
> - DataDoe MCP/Using Claude Agent SDK: `https://www.datadoe.com/hub/docs/datadoe-mcp/claude-agents-sdk.md`
> - DataDoe MCP/Using Claude Code: `https://www.datadoe.com/hub/docs/datadoe-mcp/claude-code.md`
> - DataDoe MCP/Using Codex: `https://www.datadoe.com/hub/docs/datadoe-mcp/codex.md`
> - DataDoe MCP/Using Cursor: `https://www.datadoe.com/hub/docs/datadoe-mcp/cursor.md`
> - DataDoe MCP/Using Excel + Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/excel.md`
> - DataDoe MCP/Using Gemini CLI: `https://www.datadoe.com/hub/docs/datadoe-mcp/gemini-cli.md`
> - DataDoe MCP/Using Gumloop: `https://www.datadoe.com/hub/docs/datadoe-mcp/gumloop.md`
> - DataDoe MCP/Using n8n: `https://www.datadoe.com/hub/docs/datadoe-mcp/n8n.md`
> - DataDoe MCP/Using NanoClaw: `https://www.datadoe.com/hub/docs/datadoe-mcp/nanoclaw.md`
> - DataDoe MCP/Using OpenClaw: `https://www.datadoe.com/hub/docs/datadoe-mcp/openclaw.md`
> - DataDoe MCP/Using PowerPoint + Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/powerpoint.md`
> - DataDoe MCP/Using VS Code: `https://www.datadoe.com/hub/docs/datadoe-mcp/vs-code.md`
> - DataDoe MCP/Using Word + Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/word.md`
> - DataDoe API/How to connect to the API: `https://www.datadoe.com/hub/docs/datadoe-api/how-to-connect.md`
> - DataDoe API/Vibe code with Claude Code: `https://www.datadoe.com/hub/docs/datadoe-api/claude-code.md`
> - DataDoe API/Vibe code with Codex: `https://www.datadoe.com/hub/docs/datadoe-api/codex.md`
> - DataDoe API/Vibe code with Cursor: `https://www.datadoe.com/hub/docs/datadoe-api/cursor.md`
> - DataDoe API/Vibe code with Lovable: `https://www.datadoe.com/hub/docs/datadoe-api/lovable.md`
> - DataDoe API/Vibe code with Replit: `https://www.datadoe.com/hub/docs/datadoe-api/replit.md`
> - DataDoe API/Vibe code with v0: `https://www.datadoe.com/hub/docs/datadoe-api/v0.md`
> - DataDoe & BigQuery/How to connect to BigQuery: `https://www.datadoe.com/hub/docs/datadoe-bigquery/how-to-connect.md`
> - DataDoe & BigQuery/Using MCP Toolbox: `https://www.datadoe.com/hub/docs/datadoe-bigquery/mcp-toolbox.md`
> - DataDoe & BigQuery/Using Python Jupyter: `https://www.datadoe.com/hub/docs/datadoe-bigquery/jupyter.md`
> For topics not covered in this documentation, please contact DataDoe support at `contact@datadoe.com`.
> Do not assume anything. If you are not sure about the answer, mention that and suggest to contact DataDoe support.

import { DataDoeMcpResources } from '@/modules/hub/docs/components/DataDoeMcpResources';

# Using OpenAI Agents SDK with DataDoe MCP

This tutorial shows how to build a small TypeScript agent with the [OpenAI Agents JS SDK](https://github.com/openai/openai-agents-js) and connect it to DataDoe MCP. The sample app does one practical job: it uses DataDoe advertising data, downloads the export file, loads it into DuckDB, and writes a JSON file with improved Amazon listing copy.

## What you will build

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

- connects to DataDoe MCP with `hostedMcpTool`
- downloads an export file before the URL expires
- loads the data into DuckDB and runs SQL over it
- produces one final JSON file in `response/`

## Prerequisites

- Completion of the [DataDoe MCP Overview](https://www.datadoe.com/hub/docs/datadoe-mcp/overview) setup with an MCP key
- An [OpenAI API key](https://platform.openai.com/api-keys) with access to `gpt-5.4-mini`
- Node.js 24 or later (required for native TypeScript support)
- yarn (bundled via Corepack — run `corepack enable` if needed)

## Step 1: Clone and install the repository

Start by installing the project:

```bash
git clone https://github.com/Deltologic/datadoe-mcp-openai-agents-sdk.git
cd datadoe-mcp-openai-agents-sdk
yarn install
```

## Step 2: Configure your keys

Copy the environment file and add both API keys:

```bash
cp .env.example .env
```

Open `.env` and set:

- `DATADOE_MCP_KEY`: your MCP key from the [DataDoe integrations page](https://www.datadoe.com/hub/integrations)
- `OPENAI_API_KEY`: your OpenAI API key

The agent already knows how to reach DataDoe MCP. In `src/index.ts`, it uses:

```ts
hostedMcpTool({
    serverLabel: 'datadoe',
    serverUrl: 'https://api.datadoe.com/mcp/v1',
    headers: {
        'datadoe-mcp-key': process.env.DATADOE_MCP_KEY ?? ''
    }
});
```

That is the only MCP-specific wiring the app needs. The agent gets the DataDoe tools through the SDK, and the key is sent as a request header.

## Step 3: Create the agent

The main agent lives in `src/index.ts`. It imports the OpenAI Agents SDK and combines DataDoe MCP with a few local tools:

```ts
import { Agent, hostedMcpTool, isOpenAIResponsesRawModelStreamEvent, run } from '@openai/agents';

import { systemPrompt } from './prompts/system.prompt.ts';
import { duckdbTools } from './tools/duckdb.tools.ts';
import { fetchTools } from './tools/fetch.tools.ts';
import { outputTools } from './tools/output.tools.ts';
import { sleepTools } from './tools/sleep.tools.ts';
```

The agent itself is small:

```ts
const agent = new Agent({
    name: 'Data Analyst',
    instructions: systemPrompt,
    tools: [
        hostedMcpTool({
            serverLabel: 'datadoe',
            serverUrl: 'https://api.datadoe.com/mcp/v1',
            headers: {
                'datadoe-mcp-key': process.env.DATADOE_MCP_KEY ?? ''
            }
        }),
        ...sleepTools,
        ...fetchTools,
        ...duckdbTools,
        ...outputTools
    ],
    model: 'gpt-5.4-mini',
    modelSettings: {
        reasoning: {
            effort: 'high'
        }
    }
});
```

The important part is the shape:

- `hostedMcpTool(...)` exposes DataDoe tools to the agent
- `fetchTools`, `duckdbTools`, and `outputTools` handle the local workflow
- `systemPrompt` tells the model what to do and what not to do
- `run(...)` executes the agent and streams its output

## Step 4: Understand the helper tools

The local tools make the sample app feel like a real workflow instead of a single prompt.

### Download tool

`src/tools/fetch.tools.ts` adds `download_file_from_url`. DataDoe export URLs are temporary, so the agent should fetch them right away and save them locally.

```ts
tool({
    name: 'download_file_from_url',
    description:
        'URGENT: Export links expire quickly, call this tool IMMEDIATELY before doing anything else. It downloads the file and returns the local file path.'
});
```

This keeps the workflow stable: the model can request an export URL from DataDoe MCP, then hand it off to the download tool before the link expires.

### DuckDB tools

`src/tools/duckdb.tools.ts` is where the downloaded data becomes queryable:

```ts
tool({
    name: 'load_csv',
    description: 'Loads a CSV file from the local file system into a DuckDB table.'
});
```

The file also includes:

- `load_json` for JSON or newline-delimited JSON files
- `list_tables` to inspect what is loaded
- `run_sql_query` to run standard SQL against DuckDB

That combination is the heart of the tutorial. DataDoe MCP supplies the export; DuckDB lets the agent rank ASINs and inspect the data locally.

### Final output tool

`src/tools/output.tools.ts` defines `output_improved_listings`. This tool is the final step of the app:

```ts
tool({
    name: 'output_improved_listings',
    description: 'Emits the final structured JSON for all improved ASIN listings.'
});
```

The agent should not write JSON directly in its response. Instead, it calls this tool once with all improved listings, and the tool writes the result to `response/improved-listings-<timestamp>.json`.

## Step 5: Use the system prompt to guide the agent

The prompt in `src/prompts/system.prompt.ts` keeps the agent focused. It tells the model to:

- use DataDoe MCP tools when it needs export data
- prefer SQL-based analysis through DuckDB
- keep marketplace-specific content in the right language
- never write JSON output directly in the chat

In practice, that means the agent behaves like a focused analyst instead of a generic chatbot.

## Step 6: Run the app

Start the sample with:

```bash
yarn start
```

The app runs `src/index.ts`, streams the agent's reasoning to the terminal, and finishes by writing a JSON file to `./response/`.

Typical flow:

1. The agent asks DataDoe MCP for the needed export.
2. The export URL is downloaded immediately.
3. DuckDB loads the file and the agent runs SQL to find weak ASINs.
4. The model rewrites the listing copy.
5. `output_improved_listings` saves the final result.

The output file contains one item per ASIN, with the current title and bullets alongside the improved version. That makes it easy to feed into another script, a bulk edit sheet, or a later workflow.

## A simple mental model

If you want to adapt this pattern for another DataDoe-powered agent, keep the same split:

- DataDoe MCP for source data
- local tools for downloading, transforming, and validating
- one dedicated output tool for the final artifact

That structure is what makes the sample easy to extend without turning the agent into a pile of prompt instructions.

## Related resources

- [DataDoe MCP Overview](https://www.datadoe.com/hub/docs/datadoe-mcp/overview)
- [DataDoe MCP Toolbox](https://www.datadoe.com/hub/docs/datadoe-bigquery/mcp-toolbox)
- [OpenAI Agents JS SDK](https://github.com/openai/openai-agents-js)

## DataDoe MCP resources

Check the following resources for more information:

- MCP server URL: `https://mcp.datadoe.com/mcp/v1`
- [Interactive Data Scheme](/hub/data-scheme)
- Data Scheme JSON: https://api.datadoe.com/api/v1/spec/data-scheme
- Need help? Use the [contact form](https://forms.clickup.com/9015200219/f/8cnj2ev-38615/AOYF9I35QFOXWJQXIG?type=Form&source=hub-mcp-openai-agents-sdk-docs)
