---
title: "OpenAI Agents SDK"
description: "Give an agent built with the OpenAI Agents SDK, in Python or TypeScript, the Nextmail tools as an MCP server."
url: "https://nextmail.sh/docs/mcp/frameworks/openai-agents-sdk"
area: "MCP server"
category: "Frameworks and tools"
---

# OpenAI Agents SDK

Give an agent built with the OpenAI Agents SDK, in Python or TypeScript, the Nextmail tools as an MCP server.

## Install

**Packages**

_Python_

```bash
pip install openai-agents
```

_TypeScript_

```bash
npm install @openai/agents zod
```

The Python package needs Python 3.10 or later. Both read your OpenAI key from `OPENAI_API_KEY`, and an agent without a `model` uses the SDK’s default.

## Sign in once

**Terminal**

```
npx @nextmail/cli login
```

Choose the browser sign-in. On the approval page, pick the workspace, the access, the addresses the agent may reach and how long the approval lasts. Read only is the default, and it leaves out tools such as `sendEmail`, `replyToEmail` and `createDraft`, so choose Read and send when the agent should draft or reply. The sign-in is saved on this machine and listed in Account → Command line, where you can narrow it or remove it. A sign-in the bridge has not used for 7 days, or one whose approval has ended, has to sign in again.

On a server or over SSH, add `--no-browser`: open the link on any device, approve, and paste the code it shows back into the terminal. A browser sign-in needs a person once, so a CI job cannot make one.

> The MCP server takes an approved sign-in and never an API key. A key sent to it gets `401`, with a `WWW-Authenticate` header that points at the OAuth metadata. Code that holds a key calls the REST API or an SDK instead.

## Run an agent

**Example**

_Python_

```python
import asyncio

from agents import Agent, Runner
from agents.mcp import MCPServerStdio, create_static_tool_filter

async def main():
    async with MCPServerStdio(
        name="Nextmail",
        params={"command": "npx", "args": ["-y", "@nextmail/cli", "mcp", "serve"]},
        client_session_timeout_seconds=30,
        tool_filter=create_static_tool_filter(
            allowed_tool_names=["whoAmI", "listThreads", "getThread"]
        ),
    ) as server:
        agent = Agent(
            name="Inbox assistant",
            instructions="Read the mailbox with the Nextmail tools. Never send anything.",
            mcp_servers=[server],
        )
        result = await Runner.run(agent, "Summarise my unread mail.")
        print(result.final_output)

asyncio.run(main())
```

_TypeScript_

```typescript
import { Agent, MCPServerStdio, createMCPToolStaticFilter, run } from '@openai/agents'

const server = new MCPServerStdio({
  name: 'Nextmail',
  command: 'npx',
  args: ['-y', '@nextmail/cli', 'mcp', 'serve'],
  clientSessionTimeoutSeconds: 30,
  toolFilter: createMCPToolStaticFilter({ allowed: ['whoAmI', 'listThreads', 'getThread'] }),
})

await server.connect()
try {
  const agent = new Agent({
    name: 'Inbox assistant',
    instructions: 'Read the mailbox with the Nextmail tools. Never send anything.',
    mcpServers: [server],
  })
  const result = await run(agent, 'Summarise my unread mail.')
  console.log(result.finalOutput)
} finally {
  await server.close()
}
```

The framework starts the local bridge, `npx -y @nextmail/cli mcp serve`, as a stdio MCP server. The bridge sends each call to the MCP server with your saved sign-in and renews the access token when it runs out, so the agent never handles a token. To use another profile of the command line, add `--profile <name>` to the arguments. The bridge runs on Node.js 20.12 or later.

- The static tool filter keeps the agent to the tools it names, by the names the server lists.
- In Python the client session timeout is 5 seconds by default, and the first `npx` download can take longer, so the examples allow 30.

## What the agent can do

The server registers up to 600 tools, and the agent sees the ones both your role and the approval allow. A tool the approval leaves out is never listed, so the model never tries it. Every tool loaded is sent to the model on each turn, so give the agent the ones its job needs. The example starts from `whoAmI`, `listThreads` and `getThread`.

| Tool | What it does | Access it needs |
| --- | --- | --- |
| `whoAmI` | The role you hold in the active workspace, and every permission it grants | None |
| `listThreads`, `getThread` | List conversations with filters, and read the latest message of one | Read only |
| `waitForEmail` | Wait up to 60 seconds for a message that matches, such as a sign-in code | Read only |
| `createDraft` | Save a draft without sending it, as a reply when given a thread | Read and send |
| `replyToEmail`, `sendEmail` | Reply inside a thread, or send a new email | Read and send |
| `modifyLabels` | Add or remove labels on conversations | Read and send |

> The MCP server never asks before a tool acts, so a tool that sends or deletes does it at once. A few tools make a change the REST API guards with a verification code, such as creating a rule or removing a domain, and the bridge cannot ask for a code. Run `npx @nextmail/cli verify` in a terminal with the same profile, or choose Allow changes for 60 minutes on this sign-in in Account → Command line, and those tools run for the next 60 minutes.

## Without the command line

`MCPServerStreamableHttp` can connect to the remote server, `https://api.nextmail.sh/mcp`, with an OAuth provider from the MCP SDK: pass it as `auth` in Python (an `httpx.Auth` with MCP SDK 1, an `httpx2.Auth` with 2), or as `authProvider` in TypeScript.

The hosted MCP tool, which OpenAI runs on its side, takes an OAuth access token in `authorization`. Your app runs the sign-in, sends the token with every request, and renews it, since an access token lasts an hour.

## Related

- [OpenAI Agents SDK](https://nextmail.sh/agents/openai-agents-sdk.md): The OpenAI Agents SDK page: what an agent can do with a mailbox on Nextmail, and prompts to try.
- [What it can reach](https://nextmail.sh/docs/mcp/scope.md): How your role and the approval decide the tool list.
- [Tools](https://nextmail.sh/docs/mcp/tools.md): All 600, grouped by what they are for.
- [The local bridge](https://nextmail.sh/docs/cli/ai-and-mcp.md): How `mcp serve` forwards calls, renews tokens and reports refusals.
