import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath } from 'url';
import { createBasicTemplate } from './templates/basic.js';
import { createWebSearchTemplate } from './templates/web-search.js';
import { createDatabaseTemplate } from './templates/database.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Create a new MCP server
const server = new Server(
{ name: "mcp-forge", version: "1.0.0" },
{
capabilities: {
tools: {
// Tool 1: Generate a new MCP server
generate_mcp_server: {
description: "Generates a new MCP server with the specified configuration",
parameters: {
type: "object",
properties: {
name: {
type: "string",
description: "Name of the MCP server"
},
template: {
type: "string",
enum: ["basic", "web-search", "database"],
description: "Template to use for the MCP server"
},
outputDir: {
type: "string",
description: "Directory to output the generated MCP server"
}
},
required: ["name", "template", "outputDir"]
},
handler: async (params) => {
const { name, template, outputDir } = params;
try {
// Create output directory if it doesn't exist
await fs.ensureDir(outputDir);
let templateFn;
switch (template) {
case "basic":
templateFn = createBasicTemplate;
break;
case "web-search":
templateFn = createWebSearchTemplate;
break;
case "database":
templateFn = createDatabaseTemplate;
break;
default:
templateFn = createBasicTemplate;
}
const files = templateFn(name);
// Write files
for (const [filePath, content] of Object.entries(files)) {
await fs.writeFile(path.join(outputDir, filePath), content);
}
return {
success: true,
message: `MCP server "${name}" has been generated in ${outputDir}`,
files: Object.keys(files)
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
},
// Tool 2: Get Cursor integration config
get_cursor_integration: {
description: "Generates the integration code for Cursor IDE",
parameters: {
type: "object",
properties: {
packageName: {
type: "string",
description: "NPM package name of the MCP server"
},
config: {
type: "object",
description: "Configuration object for the MCP server"
}
},
required: ["packageName"]
},
handler: async (params) => {
const { packageName, config = {} } = params;
const configString = JSON.stringify(config).replace(/"/g, '\\"');
const cursorConfig = {
command: "npx",
args: [
"-y",
"@smithery/cli@latest",
"run",
packageName,
"--config",
`"${configString}"`
]
};
const mcpJson = {
mcpServers: {
[packageName.split('/').pop()]: cursorConfig
}
};
return {
mcpJson: JSON.stringify(mcpJson, null, 2),
commandLine: `npx -y @smithery/cli@latest run ${packageName} --config "${configString}"`,
instructions: "Add this to your ~/.cursor/mcp.json file to integrate with Cursor IDE"
};
}
},
// Tool 3: Deploy to Smithery
deploy_to_smithery: {
description: "Provides instructions for deploying the MCP server to Smithery",
parameters: {
type: "object",
properties: {
repoUrl: {
type: "string",
description: "GitHub repository URL of the MCP server"
}
},
required: ["repoUrl"]
},
handler: async (params) => {
const { repoUrl } = params;
return {
steps: [
"1. Push your code to GitHub repository: " + repoUrl,
"2. Visit https://smithery.ai/dashboard",
"3. Click 'Deploy New Server'",
"4. Enter your repository URL",
"5. Follow the deployment instructions"
],
note: "Ensure your repository has a valid Dockerfile and smithery.yaml at the root"
};
}
}
}
}
}
);
// Start the server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);