Initial commit
This commit is contained in:
25
skills/mcp-server-creator/templates/package.json.template
Normal file
25
skills/mcp-server-creator/templates/package.json.template
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "{{SERVER_NAME}}",
|
||||
"version": "1.0.0",
|
||||
"description": "{{SERVER_DESCRIPTION}}",
|
||||
"type": "module",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
|
||||
"watch": "tsc --watch",
|
||||
"start": "node build/index.js",
|
||||
"inspect": "npx @modelcontextprotocol/inspector node build/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||
"zod": "^3.23.0"{{#EXTRA_DEPS}},
|
||||
{{EXTRA_DEPS}}{{/EXTRA_DEPS}}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.0.0",
|
||||
"typescript": "^5.6.0"
|
||||
},
|
||||
"keywords": ["mcp", "model-context-protocol", "{{SERVER_NAME}}"],
|
||||
"author": "{{AUTHOR}}",
|
||||
"license": "MIT"
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
{{SERVER_NAME}} MCP Server
|
||||
|
||||
{{SERVER_DESCRIPTION}}
|
||||
"""
|
||||
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
import os
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
# Configure logging to stderr (CRITICAL: never log to stdout in STDIO mode)
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=[logging.StreamHandler()] # Writes to stderr by default
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Initialize MCP server
|
||||
mcp = FastMCP("{{SERVER_NAME}}")
|
||||
|
||||
{{#TOOLS}}
|
||||
@mcp.tool()
|
||||
async def {{TOOL_FUNCTION}}({{TOOL_PARAMS_TYPED}}) -> {{TOOL_RETURN_TYPE}}:
|
||||
"""
|
||||
{{TOOL_DESCRIPTION}}
|
||||
|
||||
Args:
|
||||
{{#TOOL_PARAMS}}
|
||||
{{PARAM_NAME}}: {{PARAM_DESCRIPTION}}
|
||||
{{/TOOL_PARAMS}}
|
||||
|
||||
Returns:
|
||||
{{TOOL_RETURN_DESCRIPTION}}
|
||||
"""
|
||||
try:
|
||||
logger.info(f"{{TOOL_FUNCTION}} called with: {{TOOL_PARAMS_LOG}}")
|
||||
|
||||
# TODO: Implement your tool logic here
|
||||
result = None # Replace with actual implementation
|
||||
|
||||
return str(result)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in {{TOOL_FUNCTION}}: {str(e)}")
|
||||
raise
|
||||
|
||||
{{/TOOLS}}
|
||||
|
||||
{{#HAS_RESOURCES}}
|
||||
@mcp.resource("{{RESOURCE_URI_PATTERN}}")
|
||||
async def get_resource({{RESOURCE_PARAMS}}) -> str:
|
||||
"""
|
||||
{{RESOURCE_DESCRIPTION}}
|
||||
|
||||
Args:
|
||||
{{#RESOURCE_PARAMS_LIST}}
|
||||
{{PARAM_NAME}}: {{PARAM_DESCRIPTION}}
|
||||
{{/RESOURCE_PARAMS_LIST}}
|
||||
|
||||
Returns:
|
||||
Resource content as string
|
||||
"""
|
||||
try:
|
||||
logger.info(f"Resource requested: {{RESOURCE_PARAMS_LOG}}")
|
||||
|
||||
# TODO: Implement resource fetching logic
|
||||
content = "" # Replace with actual implementation
|
||||
|
||||
return content
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching resource: {str(e)}")
|
||||
raise
|
||||
{{/HAS_RESOURCES}}
|
||||
|
||||
{{#HAS_PROMPTS}}
|
||||
@mcp.prompt()
|
||||
async def {{PROMPT_NAME}}({{PROMPT_PARAMS}}) -> str:
|
||||
"""
|
||||
{{PROMPT_DESCRIPTION}}
|
||||
|
||||
Args:
|
||||
{{#PROMPT_PARAMS_LIST}}
|
||||
{{PARAM_NAME}}: {{PARAM_DESCRIPTION}}
|
||||
{{/PROMPT_PARAMS_LIST}}
|
||||
|
||||
Returns:
|
||||
Formatted prompt template
|
||||
"""
|
||||
return f"""
|
||||
{{PROMPT_TEMPLATE}}
|
||||
"""
|
||||
{{/HAS_PROMPTS}}
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("Starting {{SERVER_NAME}} MCP server...")
|
||||
mcp.run()
|
||||
19
skills/mcp-server-creator/templates/tsconfig.json.template
Normal file
19
skills/mcp-server-creator/templates/tsconfig.json.template
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "build"]
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
CallToolRequestSchema,
|
||||
ListToolsRequestSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import { z } from "zod";
|
||||
|
||||
// Server metadata
|
||||
const SERVER_NAME = "{{SERVER_NAME}}";
|
||||
const SERVER_VERSION = "1.0.0";
|
||||
|
||||
// Initialize MCP server
|
||||
const server = new Server(
|
||||
{
|
||||
name: SERVER_NAME,
|
||||
version: SERVER_VERSION,
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
tools: {},
|
||||
{{#HAS_RESOURCES}}resources: {},{{/HAS_RESOURCES}}
|
||||
{{#HAS_PROMPTS}}prompts: {},{{/HAS_PROMPTS}}
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// List available tools
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
||||
tools: [
|
||||
{{#TOOLS}}
|
||||
{
|
||||
name: "{{TOOL_NAME}}",
|
||||
description: "{{TOOL_DESCRIPTION}}",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
{{#TOOL_PARAMS}}
|
||||
{{PARAM_NAME}}: {
|
||||
type: "{{PARAM_TYPE}}",
|
||||
description: "{{PARAM_DESCRIPTION}}",
|
||||
},
|
||||
{{/TOOL_PARAMS}}
|
||||
},
|
||||
required: [{{REQUIRED_PARAMS}}],
|
||||
},
|
||||
},
|
||||
{{/TOOLS}}
|
||||
],
|
||||
}));
|
||||
|
||||
// Handle tool calls
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
const { name, arguments: args } = request.params;
|
||||
|
||||
{{#TOOLS}}
|
||||
if (name === "{{TOOL_NAME}}") {
|
||||
try {
|
||||
// TODO: Implement {{TOOL_NAME}} logic
|
||||
{{#TOOL_PARAMS}}
|
||||
const {{PARAM_NAME}} = args.{{PARAM_NAME}} as {{PARAM_TS_TYPE}};
|
||||
{{/TOOL_PARAMS}}
|
||||
|
||||
// Your implementation here
|
||||
const result = await {{TOOL_FUNCTION}}({{PARAM_NAMES}});
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Error in {{TOOL_NAME}}:`, error);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
{{/TOOLS}}
|
||||
|
||||
throw new Error(`Unknown tool: ${name}`);
|
||||
});
|
||||
|
||||
{{#HAS_RESOURCES}}
|
||||
// TODO: Implement resource handlers
|
||||
// Example:
|
||||
// server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
||||
// resources: [
|
||||
// {
|
||||
// uri: "resource://template/{id}",
|
||||
// name: "Resource Name",
|
||||
// description: "Resource description",
|
||||
// },
|
||||
// ],
|
||||
// }));
|
||||
{{/HAS_RESOURCES}}
|
||||
|
||||
{{#HAS_PROMPTS}}
|
||||
// TODO: Implement prompt handlers
|
||||
// Example:
|
||||
// server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
||||
// prompts: [
|
||||
// {
|
||||
// name: "prompt_name",
|
||||
// description: "Prompt description",
|
||||
// arguments: [
|
||||
// {
|
||||
// name: "arg_name",
|
||||
// description: "Argument description",
|
||||
// required: true,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// }));
|
||||
{{/HAS_PROMPTS}}
|
||||
|
||||
// Start server
|
||||
async function main() {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
|
||||
// CRITICAL: Never use console.log() in STDIO mode - it corrupts the JSON-RPC stream!
|
||||
console.error(`${SERVER_NAME} MCP server running on stdio`);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("Fatal error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user