core/apps/webapp/app/routes/api.v1.mcp.$slug.tsx
Harshith Mullapudi 8d9ddcf375
Fix: core cli to work with core repo (#26)
* Fix: core cli to work with core repo

* Fix: cli working and mcp proxy
2025-07-22 10:17:40 +05:30

143 lines
3.9 KiB
TypeScript

import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { getIntegrationDefinitionWithSlug } from "~/services/integrationDefinition.server";
import { proxyRequest } from "~/utils/proxy.server";
import { z } from "zod";
import { getIntegrationAccount } from "~/services/integrationAccount.server";
import { createMCPStdioProxy } from "@core/mcp-proxy";
import { randomUUID } from "node:crypto";
import { configureStdioMCPEnvironment } from "~/trigger/utils/mcp";
export const integrationSlugSchema = z.object({
slug: z.string(),
});
const { action, loader } = createActionApiRoute(
{
params: integrationSlugSchema,
allowJWT: true,
authorization: {
action: "mcp",
},
corsStrategy: "all",
},
async ({ authentication, request, params }) => {
try {
const slug = params.slug;
if (!slug) {
return new Response(
JSON.stringify({ error: "Integration slug is required" }),
{
status: 400,
headers: { "Content-Type": "application/json" },
},
);
}
// Fetch integration definition by slug
const integrationDefinition =
await getIntegrationDefinitionWithSlug(slug);
if (!integrationDefinition) {
return new Response(
JSON.stringify({ error: "Integration not found" }),
{
status: 404,
headers: { "Content-Type": "application/json" },
},
);
}
const spec = integrationDefinition.spec as any;
if (!spec.mcp) {
return new Response(
JSON.stringify({
error: "MCP auth configuration not found for this integration",
}),
{
status: 400,
headers: { "Content-Type": "application/json" },
},
);
}
const { url, type } = spec.mcp;
// Find the integration account for this user and integration
const integrationAccount = await getIntegrationAccount(
integrationDefinition.id,
authentication.userId,
);
if (type === "http") {
const integrationConfig =
integrationAccount?.integrationConfiguration as any;
if (
!integrationAccount ||
!integrationConfig ||
!integrationConfig.mcp
) {
return new Response(
JSON.stringify({
error: "No integration account with mcp config",
}),
{
status: 400,
headers: { "Content-Type": "application/json" },
},
);
}
// Proxy the request to the serverUrl
return await proxyRequest(
request,
url,
integrationConfig.mcp.tokens.access_token,
);
} else {
if (!integrationAccount) {
return new Response(
JSON.stringify({
error: "No integration account found",
}),
{
status: 400,
headers: { "Content-Type": "application/json" },
},
);
}
// Configure environment variables using the utility function
const { env, args } = configureStdioMCPEnvironment(
spec,
integrationAccount,
);
// Get session_id from headers (case-insensitive), or generate a new uuid if not present
const sessionId =
request.headers.get("mcp-session-id") ||
request.headers.get("Mcp-Session-Id") ||
randomUUID();
// Use the saved local file instead of command
const executablePath = `./integrations/${slug}/main`;
return createMCPStdioProxy(request, executablePath, args, {
env,
sessionId,
});
}
} catch (error: any) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
},
);
export { action, loader };