Follow the setup wizard to set up your server files.
Edit the generated server.ts or server.js file:
Copy
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"import { z } from "zod"// ============================================================================// SERVER CONFIGURATION// ============================================================================export default function createStatelessServer({ config,}: { config: any;}) { const server = new McpServer({ name: "generated-mcp-server", version: "1.0.0", }); // ============================================================================ // TEMPLATE TOOL // ============================================================================ server.tool( "reverseString", "Reverse a string value", { value: z.string().describe("String to reverse"), }, async ({ value }) => { return { content: [ { type: "text", text: value.split("").reverse().join("") } ] }; } ); return server.server;}
Configure Secrets (Optional)
Some MCP servers require API keys or allow users to customize their settings.We support this by allowing devs to modify the sigyl.yaml file to set secrets. You can do this with the optional startCommand field:
Sigyl currently only supports Express.js endpoints. We are working to add more support soon!
Building from Endpoints
Run the setup wizard
Copy
npm create sigyl@latest
Select Generate from express app.
Follow the setup wizard to set up your server files.
View the generated server.ts or server.js file. Your tools will already be set based on your express endpoints.
Copy
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"import { z } from "zod"// ============================================================================// SERVER CONFIGURATION// ============================================================================export default function createStatelessServer({ config,}: { config: any;}) { const server = new McpServer({ name: "generated-mcp-server", version: "1.0.0", }); // ============================================================================ // AUTO-GENERATED TOOLS FROM EXPRESS ENDPOINTS // ============================================================================ // These tools were automatically generated from your Express application. // Each tool corresponds to an endpoint in your Express app. // ===== GET /api/users ===== server.tool( "getApiUsers", "GET /api/users", { limit: z.number().optional(), offset: z.number().optional(), search: z.string().optional(), status: z.string().optional() }, async (args) => { // ===== REQUEST CONFIGURATION ===== const url = `http://localhost:${config.appPort || 3000}/api/users`; const method = "GET"; // Build request options const requestOptions: any = { method, headers: { "Content-Type": "application/json", }, }; // ===== PARAMETER HANDLING ===== const queryParams = new URLSearchParams(); const bodyParams: any = {}; // Add query parameter limit if (args.limit !== undefined) queryParams.append("limit", String(args.limit)); // Add query parameter offset if (args.offset !== undefined) queryParams.append("offset", String(args.offset)); // Add query parameter search if (args.search !== undefined) queryParams.append("search", String(args.search)); // Add query parameter status if (args.status !== undefined) queryParams.append("status", String(args.status)); // ===== URL CONSTRUCTION ===== if (queryParams.toString()) { requestOptions.url = url + (url.includes('?') ? '&' : '?') + queryParams.toString(); } else { requestOptions.url = url; } // Add body for POST/PUT/PATCH requests if (["POST", "PUT", "PATCH"].includes(method) && Object.keys(bodyParams).length > 0) { requestOptions.body = JSON.stringify(bodyParams); } // ===== HTTP REQUEST & RESPONSE ===== try { const response = await fetch(requestOptions.url, requestOptions); const data = await response.json(); return data; } catch (error) { return { content: [ { type: "text", text: `Error calling GET /api/users: ${error instanceof Error ? error.message : String(error)}` } ] }; } } ); return server.server;}
Configure Secrets (Optional)
Some MCP servers require API keys or allow users to customize their settings.We support this by allowing devs to modify the sigyl.yaml file to set secrets. You can do this with the optional startCommand field: