core/apps/webapp/app/routes/api.v1.mcp.$slug.tsx
Harshith Mullapudi 038acea669
Feat: added integration connect and mcp oAuth (#20)
* Feat: added integration connect and mcp oAuth

* Feat: add mcp support to chat

* Fix: UI for integrations and logs

* Fix: ui

* Fix: proxy server

* Feat: enhance MCP tool integration and loading functionality

* Fix: added header

* Fix: Linear integration sync

---------

Co-authored-by: Manoj K <saimanoj58@gmail.com>
2025-07-17 12:41:32 +05:30

103 lines
2.8 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";
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.mcpAuth) {
return new Response(
JSON.stringify({
error: "MCP auth configuration not found for this integration",
}),
{
status: 400,
headers: { "Content-Type": "application/json" },
},
);
}
const { serverUrl } = spec.mcpAuth;
// Find the integration account for this user and integration
const integrationAccount = await getIntegrationAccount(
integrationDefinition.id,
authentication.userId,
);
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,
serverUrl,
integrationConfig.mcp.tokens.access_token,
);
} catch (error: any) {
console.error("MCP Proxy Error:", error);
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
},
);
export { action, loader };