Building a Custom MCP Flow Server
Use Prismatic's MCP server when possible
Prismatic offers a built-in MCP flow server that connects to all of your agent flows with no additional code. For most use cases, the built-in server is the right choice.
You may want to build your own MCP server if you need fine-grained control over things like custom authentication, filtering which flows are exposed, or embedding MCP tooling within a larger application.
Building your own MCP flow server using Prismatic flows
If you would like to build your own MCP flow server and instruct it to interact with agent flows in Prismatic, your MCP flow server must be told which flows are available to be queried. This example code instructs an MCP flow server to fetch agent flows from Prismatic's API, and creates a resource for each:
import {
type JSONSchema,
JSONSchemaToZod,
} from "@dmitryrechkin/json-schema-to-zod";
import {
McpServer,
type ToolCallback,
} from "@modelcontextprotocol/sdk/server/mcp.js";
import { gql, request } from "graphql-request";
const STACK_BASE_URL = "https://app.prismatic.io"; // Change this to your own region
const PRISMATIC_API_KEY = ""; // TODO: Set your Prismatic API key here
interface AgentFlowResponse {
ai: {
agentFlows: {
nodes: {
id: string;
name: string;
description: string;
webhookUrl: string;
apiKeys: string[];
invokeSchema: string;
resultSchema: string;
}[];
};
};
}
// Query for agentFlows
const result = await request<AgentFlowResponse>(
new URL("/api", STACK_BASE_URL).toString(),
gql`
query agentFlows {
ai {
agentFlows {
nodes {
id
name
description
webhookUrl
apiKeys
invokeSchema
resultSchema
}
}
}
}
`,
{},
{
Authorization: `Bearer ${PRISMATIC_API_KEY}`,
},
);
// Customize MCP server to allow custom tool registrations, particularly
// for use with JSON Schema (as, by default, only zod schemas are supported).
class DynamicMcpServer extends McpServer {
jsonSchemaTool(
name: string,
description: string,
schema: JSONSchema,
cb: ToolCallback,
): void {
const zodSchema = JSONSchemaToZod.convert(schema) as any;
super.tool(name, description, zodSchema.shape, cb);
}
}
const server = new DynamicMcpServer({
name: "person-getter",
version: "1.0.0",
capabilities: {
resources: {},
tools: {},
},
});
// For each flow, create a tool that can be invoked by the MCP client
for (const flow of result.ai.agentFlows.nodes) {
server.jsonSchemaTool(
flow.name,
flow.description,
JSON.parse(flow.invokeSchema),
async (args) => {
console.log("flow invoke", flow.name, args);
const result = await fetch(flow.webhookUrl, {
method: "POST",
body: JSON.stringify(args),
headers: {
"Content-Type": "application/json",
"prismatic-synchronous": "true",
},
});
return { content: [{ type: "text", text: await result.text() }] };
},
);
}