For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://modelgates.ai/docs/_mcp/server.

Message Formats

OpenAI Chat Format

fromChatMessages()

Convert OpenAI chat-style messages to OpenResponses input:

typescript
import { ModelGates, fromChatMessages } from '@modelgates/agent'; const modelgates = new ModelGates({  apiKey: process.env.MODELGATES_API_KEY,}); // OpenAI chat formatconst chatMessages = [  { role: 'system', content: 'You are a helpful assistant.' },  { role: 'user', content: 'Hello!' },  { role: 'assistant', content: 'Hi there! How can I help you?' },  { role: 'user', content: 'What is the weather like?' },]; const result = modelgates.callModel({  model: 'openai/gpt-5-nano',  input: fromChatMessages(chatMessages),}); const text = await result.getText();

toChatMessage()

Convert an OpenResponses response to chat message format:

typescript
import { toChatMessage } from '@modelgates/agent'; const result = modelgates.callModel({  model: 'openai/gpt-5-nano',  input: 'Hello!',}); const response = await result.getResponse();const chatMessage = toChatMessage(response); // chatMessage is now: { role: 'assistant', content: '...' }console.log(chatMessage.role);    // 'assistant'console.log(chatMessage.content); // Response text

Supported Message Types

Chat RoleDescription
systemSystem instructions
userUser messages
assistantAssistant responses
developerDeveloper instructions
toolTool response messages

Tool Messages

Tool responses are converted to function call outputs:

typescript
const chatMessages = [  { role: 'user', content: 'What is the weather?' },  {    role: 'assistant',    content: null,    tool_calls: [{      id: 'call_123',      type: 'function',      function: { name: 'get_weather', arguments: '{"location":"Paris"}' },    }],  },  {    role: 'tool',    tool_call_id: 'call_123',    content: '{"temperature": 20}',  },]; const input = fromChatMessages(chatMessages);

Anthropic Claude Format

fromClaudeMessages()

Convert Anthropic Claude-style messages to OpenResponses input:

typescript
import { ModelGates, fromClaudeMessages } from '@modelgates/agent'; // Claude formatconst claudeMessages = [  { role: 'user', content: 'Hello!' },  { role: 'assistant', content: 'Hi there!' },  { role: 'user', content: 'Tell me about TypeScript.' },]; const result = modelgates.callModel({  model: 'anthropic/claude-sonnet-4.5',  input: fromClaudeMessages(claudeMessages),});

toClaudeMessage()

Convert an OpenResponses response to Claude message format:

typescript
import { toClaudeMessage } from '@modelgates/agent'; const result = modelgates.callModel({  model: 'anthropic/claude-sonnet-4.5',  input: 'Hello!',}); const response = await result.getResponse();const claudeMessage = toClaudeMessage(response); // Compatible with Anthropic SDK types

Content Blocks

Claude's content block format is supported:

typescript
const claudeMessages = [  {    role: 'user',    content: [      { type: 'text', text: 'What is in this image?' },      {        type: 'image',        source: {          type: 'url',          url: 'https://example.com/image.jpg',        },      },    ],  },]; const input = fromClaudeMessages(claudeMessages);

Tool Use Blocks

Claude's tool use format is converted:

typescript
const claudeMessages = [  { role: 'user', content: 'What is the weather?' },  {    role: 'assistant',    content: [      {        type: 'tool_use',        id: 'tool_123',        name: 'get_weather',        input: { location: 'Paris' },      },    ],  },  {    role: 'user',    content: [      {        type: 'tool_result',        tool_use_id: 'tool_123',        content: '{"temperature": 20}',      },    ],  },]; const input = fromClaudeMessages(claudeMessages);

Base64 Images

Both URL and base64 images are supported:

typescript
const claudeMessages = [  {    role: 'user',    content: [      { type: 'text', text: 'Describe this image.' },      {        type: 'image',        source: {          type: 'base64',          media_type: 'image/png',          data: 'iVBORw0KGgo...',        },      },    ],  },];

Limitations

Some Claude features are not preserved in conversion. e.g. is_error flag on tool_result blocks

These features are Claude-specific and not supported by ModelGates.

Migration Examples

From OpenAI SDK

typescript
// Before: OpenAI SDKimport OpenAI from 'openai'; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });const completion = await openai.chat.completions.create({  model: 'gpt-4',  messages: [    { role: 'system', content: 'You are helpful.' },    { role: 'user', content: 'Hello!' },  ],}); // After: ModelGates SDKimport { ModelGates, fromChatMessages } from '@modelgates/agent'; const modelgates = new ModelGates({ apiKey: process.env.MODELGATES_API_KEY });const result = modelgates.callModel({  model: 'openai/gpt-5.2',  input: fromChatMessages([    { role: 'system', content: 'You are helpful.' },    { role: 'user', content: 'Hello!' },  ]),}); const text = await result.getText();

From Anthropic SDK

typescript
// Before: Anthropic SDKimport Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic();const message = await anthropic.messages.create({  model: 'claude-sonnet-4-20250514',  max_tokens: 1024,  messages: [    { role: 'user', content: 'Hello!' },  ],}); // After: ModelGates SDKimport { ModelGates, fromClaudeMessages } from '@modelgates/agent'; const modelgates = new ModelGates({ apiKey: process.env.MODELGATES_API_KEY });const result = modelgates.callModel({  model: 'anthropic/claude-sonnet-4.5',  input: fromClaudeMessages([    { role: 'user', content: 'Hello!' },  ]),  maxOutputTokens: 1024,}); const text = await result.getText();

Building Conversations

Accumulate messages across multiple calls:

typescript
import { fromChatMessages, toChatMessage } from '@modelgates/agent'; // Start with initial messagelet messages = [  { role: 'system', content: 'You are a helpful assistant.' },  { role: 'user', content: 'Hello!' },]; // First calllet result = modelgates.callModel({  model: 'openai/gpt-5-nano',  input: fromChatMessages(messages),}); let response = await result.getResponse();let assistantMessage = toChatMessage(response); // Add to historymessages.push(assistantMessage);messages.push({ role: 'user', content: 'What can you help me with?' }); // Continue conversationresult = modelgates.callModel({  model: 'openai/gpt-5-nano',  input: fromChatMessages(messages),});

Next Steps