// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText, tool } from 'ai';
import { z } from 'zod';
class AlloyMCPClient {
private baseUrl: string;
constructor(serverId: string, accessToken: string) {
this.baseUrl = `https://mcp.runalloy.com/mcp/${serverId}/${accessToken}`;
}
async callTool(name: string, args: Record<string, any> = {}): Promise<any> {
const response = await fetch(this.baseUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'tools/call',
params: { name, arguments: args },
id: Date.now()
})
});
const text = await response.text();
// Parse event-stream response
for (const line of text.split('\n')) {
if (line.startsWith('data: ')) {
return JSON.parse(line.slice(6)).result;
}
}
}
}
// Initialize once
const mcp = new AlloyMCPClient(
process.env.MCP_SERVER_ID!,
process.env.MCP_ACCESS_TOKEN!
);
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: openai('gpt-4'),
messages,
tools: {
listConnectors: tool({
description: 'Get available platform integrations',
parameters: z.object({
category: z.string().optional().describe('Filter by category')
}),
execute: async ({ category }) => {
const result = await mcp.callTool('list_connectors_alloy', { category });
return `Available connectors: ${JSON.stringify(result)}`;
}
}),
executeAction: tool({
description: 'Execute an action on a platform',
parameters: z.object({
connectorId: z.string().describe('Platform identifier'),
actionId: z.string().describe('Action to execute'),
parameters: z.record(z.any()).describe('Action parameters')
}),
execute: async ({ connectorId, actionId, parameters }) => {
const result = await mcp.callTool('execute_action_alloy', {
connectorId,
actionId,
parameters
});
return `Action completed: ${JSON.stringify(result)}`;
}
})
},
system: `You are a helpful assistant that can interact with various platforms.
You can list available integrations and execute actions on them.
Always explain what you're doing before taking actions.`
});
return result.toDataStreamResponse();
}