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 textSupported Message Types
| Chat Role | Description |
|---|---|
system | System instructions |
user | User messages |
assistant | Assistant responses |
developer | Developer instructions |
tool | Tool 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 typesContent 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
- Text Generation - Input formats and parameters
- Tools - Add tool capabilities
- Streaming - Stream format-converted responses