# OpenAI SDK Integration

> Use Aerostack workspace tools as OpenAI function-calling tools. Full control over the tool call loop — inspect, modify, and batch tool calls.

Use Aerostack workspace tools as [OpenAI](https://platform.openai.com/docs) function-calling tools.
Full control over the tool call loop — inspect, modify, or batch tool calls as needed.

## Install

```bash npm2yarn
npm install @aerostack/sdk-openai openai
```

## Quick Start

```typescript

const openai = new OpenAI();
const config = { workspace: 'my-workspace', token: 'mwt_...' };

const { tools } = await getTools(config);

const response = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Create a GitHub issue for the login bug' }],
  tools,
});

const toolCalls = response.choices[0]?.message.tool_calls;
if (toolCalls) {
  const results = await handleToolCalls(toolCalls, config);
  // results are ChatCompletionToolMessageParam[] — append to messages and continue
}
```

The SDK:
1. Fetches all MCP tools from your workspace
2. Converts them to `ChatCompletionTool[]` format (sanitizing names to fit OpenAI's 64-char limit)
3. `handleToolCalls` executes tool calls in parallel against the workspace gateway
4. Results come back as `ChatCompletionToolMessageParam[]` — append to messages for the next turn

## Multi-Turn Conversation

Build a full agentic loop:

```typescript

const openai = new OpenAI();
const config = { workspace: 'my-workspace', token: 'mwt_...' };
const { tools } = await getTools(config);

const messages: OpenAI.ChatCompletionMessageParam[] = [
  { role: 'user', content: 'Check Stripe for failed payments this week, then post a summary to Slack' },
];

// Agentic loop — run until the model stops calling tools
while (true) {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages,
    tools,
  });

  const choice = response.choices[0];
  messages.push(choice.message);

  if (!choice.message.tool_calls?.length) {
    // Model is done — print final response
    console.log(choice.message.content);
    break;
  }

  // Execute tool calls and append results
  const results = await handleToolCalls(choice.message.tool_calls, config);
  messages.push(...results);
}
```

## Single Tool Call

For finer control, handle one tool call at a time:

```typescript

// Execute a single tool call
const result = await handleToolCall(
  response.choices[0].message.tool_calls[0],
  config,
);
```

## Factory Pattern (Recommended for Production)

```typescript

const aerostack = createAerostackOpenAI({
  workspace: 'my-workspace',
  token: process.env.AEROSTACK_WORKSPACE_TOKEN!,
});

// Reuse across requests — caches the name map after first tools() call
const { tools } = await aerostack.tools();
const results = await aerostack.handleToolCalls(toolCalls);
```

## What `getTools` Returns

```typescript
const result = await getTools(config);

result.tools    // ChatCompletionTool[] — pass to chat.completions.create({ tools })
result.nameMap  // Map<string, string> — sanitized name → original MCP tool name
result.raw      // McpTool[] — raw MCP tool definitions for inspection
```

The `nameMap` is used internally by `handleToolCalls` to resolve sanitized tool names back to their original MCP names. You only need it if you're handling tool execution manually.

## Next Steps

- [Create a workspace](/workspaces/create-workspace) and connect MCP servers
- [Browse 250+ MCP servers](/mcp) in the registry
- See the [full API reference](https://github.com/aerostackdev/sdk-openai) on GitHub
