How to Integrate Composio with OpenAI Using the @composio/openai Package

The @composio/openai package provides provider classes that automatically convert Composio tools into OpenAI-compatible function schemas and handle execution, enabling direct integration with both the Chat Completions and Responses APIs.

The @composio/openai package serves as the official bridge between the Composio SDK and OpenAI's function-calling capabilities. It extends the BaseNonAgenticProvider from @composio/core to deliver schema translation, MCP server adaptation, and asynchronous tool execution. This guide demonstrates how to integrate Composio with OpenAI using production-ready implementations from the ComposioHQ/composio repository.

Architecture Overview

The package exports two specialized providers that extend BaseNonAgenticProvider to handle different OpenAI endpoints. The OpenAIProvider class in ts/packages/providers/openai/src/OpenAIProvider.ts manages the traditional Chat Completions API, while OpenAIResponsesProvider in ts/packages/providers/openai/src/OpenAIResponsesProvider.ts targets the newer Responses API.

Both providers implement four critical functions:

  • wrapTool – Converts Composio tool definitions into OpenAI function schemas
  • wrapMcpServerResponse – Rewrites MCP (Micro-Connector Platform) URLs into OpenAI's expected format
  • executeToolCall – Parses incoming function-call payloads and invokes the underlying Composio tool
  • handleToolCalls / handleResponse – Batch processes multiple tool calls and formats results for OpenAI consumption

When instantiating the Composio client, you inject the provider via the provider parameter. As shown in OpenAIProvider.ts【/ts/packages/providers/openai/src/OpenAIProvider.ts#L30-L48】, the constructor accepts standard configuration and inherits authentication and modifier logic from the base class.

Integrating with OpenAI Chat Completions

For applications using the Chat Completions API, the OpenAIProvider class handles the full lifecycle of tool execution. The wrapTool method【/ts/packages/providers/openai/src/OpenAIProvider.ts#L94-L104】 automatically transforms Composio tool schemas into OpenAI function definitions, while executeToolCall【/ts/packages/providers/openai/src/OpenAIProvider.ts#L80-L95】 decodes JSON arguments and forwards them to the core SDK's execution engine.

The following example demonstrates streaming integration with automatic tool handling:

import { Composio } from '@composio/core';
import { OpenAIProvider } from '@composio/openai';
import OpenAI from 'openai';

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  provider: new OpenAIProvider(),
});

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

export async function POST(req: Request) {
  const { messages } = await req.json();

  // Fetch tools from Composio
  const tools = await composio.tools.get('user123', {
    toolkits: ['gmail', 'googlecalendar'],
    limit: 5,
  });

  // Create streamed completion with function calling
  const stream = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages,
    tools,
    tool_choice: 'auto',
    stream: true,
  });

  // Process stream and execute tools via the provider
  const chunks: string[] = [];
  for await (const chunk of stream) {
    const toolCalls = chunk.choices[0]?.delta?.tool_calls;
    if (toolCalls?.length) {
      const call = toolCalls[0];
      const result = await composio.provider.executeToolCall(call);
      chunks.push(result);
    } else {
      chunks.push(chunk.choices[0]?.delta?.content ?? '');
    }
  }

  return new Response(chunks.join(''), {
    headers: { 'content-type': 'text/plain' },
  });
}

For batch processing multiple function calls simultaneously, the provider exposes handleToolCalls【/ts/packages/providers/openai/src/OpenAIProvider.ts#L39-L62】, which iterates over the entire tool_calls array and aggregates results into the format OpenAI expects for subsequent completion requests.

Using the OpenAI Responses API

The Responses API provider follows a similar pattern but introduces a two-step execution flow via handleResponse【/ts/packages/providers/openai/src/OpenAIResponsesProvider.ts#L39-L48】. This method orchestrates the initial tool call, executes the underlying Composio actions, and returns structured outputs ready for the follow-up request.

import { Composio } from '@composio/core';
import { OpenAIResponsesProvider } from '@composio/openai';
import OpenAI from 'openai';

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  provider: new OpenAIResponsesProvider({ strict: true }),
});

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function run() {
  // Retrieve tools
  const tools = await composio.tools.get('default', {
    toolkits: ['github'],
  });

  // Initial request to Responses endpoint
  const firstResp = await openai.responses.create({
    model: 'gpt-4o-mini',
    input: 'List my latest GitHub repositories.',
    tools,
  });

  // Execute tool calls through the provider
  const toolOutputs = await composio.provider.handleResponse(
    'default',
    firstResp,
  );

  // Submit tool outputs for final synthesis
  const finalResp = await openai.responses.create({
    model: 'gpt-4o-mini',
    input: toolOutputs,
    tools,
  });

  console.log(finalResp.output[0].content[0].text);
}

run();

Both providers support MCP server adaptation through wrapMcpServerResponse, located in OpenAIProvider.ts【/ts/packages/providers/openai/src/OpenAIProvider.ts#L60-L65】 and OpenAIResponsesProvider.ts【/ts/packages/providers/openai/src/OpenAIResponsesProvider.ts#L83-L90】, ensuring that tools returning MCP URLs are correctly formatted for OpenAI consumption.

Enabling Strict Mode for Parameter Validation

The OpenAIResponsesProvider accepts a strict option that automatically prunes non-required properties from tool input schemas before transmission. When strict: true is passed to the constructor, the wrapTool implementation【/ts/packages/providers/openai/src/OpenAIResponsesProvider.ts#L24-L33】 strips optional JSON properties, ensuring OpenAI receives only the required parameters for each function.

import { Composio } from '@composio/core';
import { OpenAIResponsesProvider } from '@composio/openai';

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  provider: new OpenAIResponsesProvider({ strict: true }),
});

This mode reduces token consumption and prevents model hallucination of optional parameters during function calls.

Summary

  • Install @composio/openai alongside @composio/core and the openai package to enable provider functionality
  • Use OpenAIProvider for Chat Completions API integrations, leveraging executeToolCall for individual invocations or handleToolCalls for batch processing
  • Use OpenAIResponsesProvider for the Responses API, utilizing handleResponse to manage the two-step tool execution flow
  • Enable strict mode in OpenAIResponsesProvider to automatically filter non-required parameters from tool schemas before sending them to OpenAI

Frequently Asked Questions

What is the difference between OpenAIProvider and OpenAIResponsesProvider?

OpenAIProvider targets the traditional Chat Completions API and provides executeToolCall and handleToolCalls methods for streaming and batch processing. OpenAIResponsesProvider targets the newer Responses API and exposes handleResponse to manage the asynchronous tool execution loop required by that endpoint, as implemented in ts/packages/providers/openai/src/OpenAIResponsesProvider.ts【/ts/packages/providers/openai/src/OpenAIResponsesProvider.ts#L39-L48】.

How does the provider handle MCP server responses?

Both providers implement wrapMcpServerResponse to rewrite MCP URLs into OpenAI-compatible schemas. The chat completion provider handles this in OpenAIProvider.ts【/ts/packages/providers/openai/src/OpenAIProvider.ts#L60-L65】, while the responses provider manages it in OpenAIResponsesProvider.ts【/ts/packages/providers/openai/src/OpenAIResponsesProvider.ts#L83-L90】, ensuring seamless integration with Composio's Micro-Connector Platform.

Can I stream responses while executing Composio tools?

Yes. The OpenAIProvider supports streaming through the standard OpenAI SDK streaming interface. Within the stream loop, you detect tool_calls in the delta chunks and invoke composio.provider.executeToolCall() to execute tools asynchronously while continuing to stream text content, as shown in the Chat Completions integration example【/ts/packages/providers/openai/src/OpenAIProvider.ts#L80-L95】.

Where are the core provider methods defined?

The chat completion logic resides in ts/packages/providers/openai/src/OpenAIProvider.ts, containing wrapTool, executeToolCall, and handleToolCalls. The responses logic is defined in ts/packages/providers/openai/src/OpenAIResponsesProvider.ts, containing the strict-mode wrapTool implementation and handleResponse. Both extend BaseNonAgenticProvider from @composio/core for shared authentication and execution infrastructure.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →