MCP (Model Context Protocol)
Connect LLMs to remote MCP servers for dynamic tool discovery and execution.
MCP (Model Context Protocol) is an open protocol that lets LLMs connect to external tool servers dynamically. Instead of hardcoding tool definitions, you point to remote MCP servers and Aivene automatically discovers and executes the available tools.
Why MCP matters
- Dynamic tool discovery — Tools are fetched from remote servers at runtime, no code changes needed
- Decoupled architecture — Tool implementations live on separate servers, making them reusable across applications
- Ecosystem compatibility — MCP is an open standard with growing community support and pre-built servers
- Simplified integration — Connect to databases, APIs, and services without writing custom tool code
How it works
Instead of defining tools inline with JSON schemas, you specify MCP server URLs. Aivene connects to each server, discovers available tools, and presents them to the model. When the model calls a tool, Aivene routes the call to the appropriate MCP server and returns the result.
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.aivene.com/v1',
apiKey: process.env.AIVENE_API_KEY
});
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'user', content: 'What files are in the current directory?' }
],
tools: [
{
type: 'mcp',
server_label: 'filesystem',
server_url: 'https://mcp-filesystem.example.com/mcp',
server_description: 'File system operations'
}
]
});MCP tool definition
An MCP tool definition tells Aivene which remote server to connect to:
| Field | Type | Required | Description |
|---|---|---|---|
type | 'mcp' | Yes | Must be 'mcp' |
server_label | string | Yes | Unique identifier for the server (used in tool names) |
server_url | string | Yes | URL of the MCP server endpoint |
server_description | string | No | Description prepended to tool descriptions |
headers | object | No | Custom headers for authentication |
allowed_tools | string[] | No | Whitelist of tool names to expose (null = all) |
const tools = [
{
type: 'mcp',
server_label: 'github',
server_url: 'https://mcp-github.example.com/mcp',
server_description: 'GitHub repository operations',
headers: {
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
allowed_tools: ['search_repositories', 'get_file_contents']
}
];Tool naming
When tools are discovered from MCP servers, Aivene qualifies them with the server label to avoid naming conflicts:
{server_label}__{tool_name}For example, a list_files tool from a server labeled filesystem becomes
filesystem__list_files. This lets you connect multiple MCP servers that
may have tools with the same name.
Tool name format
The double underscore (__) separates the server label from the tool name.
When the model calls filesystem__list_files, Aivene routes it to the
filesystem server and calls the list_files tool.
Transports
Aivene supports two MCP transport protocols, automatically detected by URL:
| URL Pattern | Transport | Protocol Version |
|---|---|---|
*/sse | Legacy HTTP+SSE | 2024-11-05 |
*/mcp or bare domain | Streamable HTTP | 2025-03-26 |
Streamable HTTP (recommended)
The modern transport uses standard HTTP POST with optional SSE responses:
https://mcp-server.example.com/mcpLegacy SSE
The older transport establishes a persistent SSE connection for server-sent events:
https://mcp-server.example.com/sseMixing MCP with regular tools
You can combine MCP tools with regular function tools in the same request:
const tools = [
// Regular function tool
{
type: 'function',
function: {
name: 'get_current_time',
description: 'Get the current time',
parameters: { type: 'object', properties: {} }
}
},
// MCP server
{
type: 'mcp',
server_label: 'weather',
server_url: 'https://mcp-weather.example.com/mcp'
}
];Aivene resolves MCP tools at request time and combines them with your inline tools. The model sees a unified list of available functions.
Authentication
Pass authentication headers to MCP servers using the headers field:
const tools = [
{
type: 'mcp',
server_label: 'database',
server_url: 'https://mcp-database.example.com/mcp',
headers: {
'Authorization': `Bearer ${process.env.DB_TOKEN}`,
'X-Tenant-Id': 'acme-corp'
}
}
];Security
MCP server credentials are sent with every tool discovery and execution request. Only connect to trusted MCP servers and use short-lived tokens when possible.
Filtering tools
Use allowed_tools to expose only specific tools from an MCP server:
const tools = [
{
type: 'mcp',
server_label: 'github',
server_url: 'https://mcp-github.example.com/mcp',
// Only expose read operations
allowed_tools: [
'search_repositories',
'get_file_contents',
'list_commits'
]
}
];When allowed_tools is null or omitted, all tools from the server are
exposed.
Error handling
If an MCP server fails to respond or returns an error, Aivene returns an error message in the response:
try {
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'List files' }],
tools: [{
type: 'mcp',
server_label: 'filesystem',
server_url: 'https://unreachable-server.example.com/mcp'
}]
});
} catch (error) {
// "Error retrieving tool list from MCP server: 'filesystem'. Reason: ..."
console.error(error.message);
}Streaming
MCP tools work seamlessly with streaming responses. Tool calls are accumulated and executed just like regular function tools:
const stream = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Search for TypeScript repos' }],
tools: [{
type: 'mcp',
server_label: 'github',
server_url: 'https://mcp-github.example.com/mcp'
}],
stream: true
});
for await (const chunk of stream) {
// Handle streaming chunks...
}Example: Multi-server setup
Connect to multiple MCP servers for a comprehensive agent:
const tools = [
{
type: 'mcp',
server_label: 'filesystem',
server_url: 'https://mcp-fs.internal/mcp',
server_description: 'Local file operations'
},
{
type: 'mcp',
server_label: 'database',
server_url: 'https://mcp-db.internal/mcp',
server_description: 'Database queries',
headers: { 'Authorization': `Bearer ${process.env.DB_TOKEN}` }
},
{
type: 'mcp',
server_label: 'slack',
server_url: 'https://mcp-slack.internal/mcp',
server_description: 'Slack messaging',
allowed_tools: ['send_message', 'list_channels']
}
];
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: 'You are a helpful assistant with access to files, database, and Slack.'
},
{
role: 'user',
content: 'Find all users who signed up this week and post a summary to #growth'
}
],
tools
});Building MCP servers
MCP is an open protocol. You can build your own MCP servers using the official SDKs:
- TypeScript:
@modelcontextprotocol/sdk - Python:
mcp
A minimal MCP server exposes tools via the tools/list and tools/call
JSON-RPC methods:
// Example MCP server structure (TypeScript SDK)
import { Server } from '@modelcontextprotocol/sdk/server';
const server = new Server({
name: 'my-mcp-server',
version: '1.0.0'
});
server.setRequestHandler('tools/list', async () => ({
tools: [
{
name: 'greet',
description: 'Say hello to someone',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string', description: 'Name to greet' }
},
required: ['name']
}
}
]
}));
server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
if (name === 'greet') {
return { content: [{ type: 'text', text: `Hello, ${args.name}!` }] };
}
throw new Error(`Unknown tool: ${name}`);
});Community MCP servers
The MCP ecosystem includes pre-built servers for common integrations:
| Server | Description |
|---|---|
| Filesystem | Read/write local files |
| GitHub | Repository operations, issues, PRs |
| Slack | Send messages, manage channels |
| PostgreSQL | Database queries |
| Brave Search | Web search |
| Puppeteer | Browser automation |
Check the MCP server registry for more options.
Best practices
-
Use descriptive labels — Server labels appear in tool names. Use short, clear labels like
github,database, orslack. -
Filter sensitive tools — Use
allowed_toolsto restrict access to read-only or safe operations when appropriate. -
Handle server failures — MCP servers may be unavailable. Implement retries and graceful degradation.
-
Monitor tool usage — Log which MCP tools are called to debug issues and optimize performance.
-
Keep servers fast — MCP tool discovery adds latency to requests. Ensure your servers respond quickly to
tools/list.
Limitations
- Discovery latency — Each MCP server is queried at request time, adding network latency. Consider caching for high-traffic applications.
- No tool caching — Tools are discovered fresh on each request. If your tool list is static, regular function tools may be more efficient.
- Session management — Aivene manages MCP sessions internally. Long-running conversations may see session timeouts on some servers.
- Error propagation — MCP server errors surface as tool execution failures. The model may need guidance on how to handle unavailable tools.