← 返回
未分类 Key

mcp-server-plus

Enhanced MCP server creation with templates, security best practices, deployment guides, and monitoring. Supports multiple transport types (stdio, SSE, WebSocket) and deployment platforms.
Enhanced MCP server creation with templates, security best practices, deployment guides, and monitoring. Supports multiple transport types (stdio, SSE, WebSocket) and deployment platforms.
yjkj999999
未分类 community v1.0.0 1 版本 100000 Key: 需要
★ 0
Stars
📥 13
下载
💾 0
安装
1
版本
#latest

概述

MCP Server Plus

Enhanced MCP server creation with templates, security, deployment, and monitoring.

Features

  • Server Templates: Ready-to-use templates for common use cases
  • Security Best Practices: Authentication, rate limiting, input validation
  • Deployment Guides: Multiple platforms (Docker, Vercel, AWS)
  • Monitoring: Health checks, logging, metrics
  • Transport Options: stdio, SSE, WebSocket

Quick Reference

Use CaseTemplateTransport
-------------------------------
API wrapperapi-wrapperSSE
Database accessdatabasestdio
File systemfilesystemstdio
Real-timewebsocketWebSocket

Server Templates

API Wrapper Server

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server(
  {
    name: "api-wrapper",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Define tools
server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "fetch_data",
      description: "Fetch data from external API",
      inputSchema: {
        type: "object",
        properties: {
          endpoint: { type: "string" },
          params: { type: "object" },
        },
        required: ["endpoint"],
      },
    },
  ],
}));

// Handle tool calls
server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  
  if (name === "fetch_data") {
    const response = await fetch(args.endpoint, {
      method: "GET",
      headers: {
        "Authorization": `Bearer ${process.env.API_KEY}`,
      },
    });
    const data = await response.json();
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(data, null, 2),
        },
      ],
    };
  }
});

// Start server
const transport = new StdioServerTransport();
await server.connect(transport);

Database Server

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { Pool } from "pg";

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

const server = new Server(
  {
    name: "database",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "query",
      description: "Execute SQL query",
      inputSchema: {
        type: "object",
        properties: {
          sql: { type: "string" },
          params: { type: "array" },
        },
        required: ["sql"],
      },
    },
  ],
}));

server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  
  if (name === "query") {
    const result = await pool.query(args.sql, args.params);
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({
            rows: result.rows,
            rowCount: result.rowCount,
          }, null, 2),
        },
      ],
    };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);

File System Server

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import * as fs from "fs/promises";
import * as path from "path";

const server = new Server(
  {
    name: "filesystem",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "read_file",
      description: "Read file contents",
      inputSchema: {
        type: "object",
        properties: {
          path: { type: "string" },
        },
        required: ["path"],
      },
    },
    {
      name: "write_file",
      description: "Write to file",
      inputSchema: {
        type: "object",
        properties: {
          path: { type: "string" },
          content: { type: "string" },
        },
        required: ["path", "content"],
      },
    },
  ],
}));

server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  
  if (name === "read_file") {
    const content = await fs.readFile(args.path, "utf-8");
    return {
      content: [
        {
          type: "text",
          text: content,
        },
      ],
    };
  }
  
  if (name === "write_file") {
    await fs.writeFile(args.path, args.content);
    return {
      content: [
        {
          type: "text",
          text: `File written successfully: ${args.path}`,
        },
      ],
    };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);

Security Best Practices

Authentication

// API key validation
const validateApiKey = (req) => {
  const apiKey = req.headers["x-api-key"];
  if (apiKey !== process.env.API_KEY) {
    throw new Error("Invalid API key");
  }
};

// OAuth2 validation
const validateOAuth = async (req) => {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) {
    throw new Error("Missing authorization token");
  }
  
  const user = await verifyToken(token);
  return user;
};

Rate Limiting

import rateLimit from "express-rate-limit";

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: "Too many requests",
});

app.use(limiter);

Input Validation

import { z } from "zod";

const ToolInputSchema = z.object({
  endpoint: z.string().url(),
  params: z.object({}).optional(),
});

const validateInput = (input) => {
  return ToolInputSchema.parse(input);
};

Environment Variables

# Required
API_KEY=your-api-key
DATABASE_URL=postgresql://user:pass@host/db

# Optional
PORT=3000
LOG_LEVEL=info
RATE_LIMIT=100

Deployment Guides

Docker

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000

CMD ["node", "server.js"]
# docker-compose.yml
version: "3.8"
services:
  mcp-server:
    build: .
    ports:
      - "3000:3000"
    environment:
      - API_KEY=${API_KEY}
      - DATABASE_URL=${DATABASE_URL}
    restart: unless-stopped

Vercel

{
  "version": 2,
  "builds": [
    {
      "src": "server.js",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "server.js"
    }
  ]
}

AWS Lambda

// handler.js
const { Server } = require("@modelcontextprotocol/sdk/server/index.js");
const { SSEServerTransport } = require("@modelcontextprotocol/sdk/server/sse.js");

exports.handler = async (event, context) => {
  const server = new Server(/* ... */);
  const transport = new SSEServerTransport("/messages", res);
  
  await server.connect(transport);
  
  return {
    statusCode: 200,
    body: JSON.stringify({ status: "connected" }),
  };
};

Monitoring

Health Checks

app.get("/health", (req, res) => {
  res.json({
    status: "healthy",
    uptime: process.uptime(),
    timestamp: new Date().toISOString(),
  });
});

Logging

import winston from "winston";

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || "info",
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: "error.log", level: "error" }),
    new winston.transports.File({ filename: "combined.log" }),
  ],
});

Metrics

import { Counter, Histogram } from "prom-client";

const requestCounter = new Counter({
  name: "mcp_requests_total",
  help: "Total number of MCP requests",
  labelNames: ["method", "status"],
});

const requestDuration = new Histogram({
  name: "mcp_request_duration_seconds",
  help: "Duration of MCP requests in seconds",
  labelNames: ["method"],
});

Transport Options

stdio

  • Best for local communication
  • Simple setup
  • Low latency

SSE (Server-Sent Events)

  • Best for web applications
  • HTTP-based
  • Easy to proxy

WebSocket

  • Best for real-time communication
  • Bidirectional
  • Persistent connection

Best Practices

  1. Use TypeScript - Type safety and better tooling
  2. Validate inputs - Always validate tool inputs
  3. Handle errors - Return meaningful error messages
  4. Log operations - Track tool usage and errors
  5. Rate limit - Prevent abuse
  6. Use environment variables - Never hardcode secrets
  7. Health checks - Monitor server status
  8. Documentation - Document tools and usage

Common Issues

IssueSolution
-----------------
Connection refusedCheck server is running
Authentication failedVerify API key
TimeoutIncrease timeout or check network
Rate limitedImplement rate limiting
Memory leakMonitor and restart periodically

版本历史

共 1 个版本

  • v1.0.0 从ClawHub迁移发布 当前
    2026-06-07 12:35 安全 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

安全,无风险
查看报告

🔗 相关推荐

dev-programming

Github

steipete
使用 `gh` CLI 与 GitHub 交互,通过 `gh issue`、`gh pr`、`gh run` 和 `gh api` 管理议题、PR、CI 运行及高级查询。
★ 681 📥 330,060
dev-programming

Mcporter

steipete
使用 mcporter CLI 直接列出、配置、认证及调用 MCP 服务器/工具(支持 HTTP 或 stdio),涵盖临时服务器、配置编辑及 CLI/类型生成功能。
★ 197 📥 68,058
design-media

agnes-image-gen

user_15292d5a
使用 Agnes AI 的图片生成模型生成图片,支持文生图(agnes-image-2.1-flash)和图生图(agnes-image-2.0-flash)。支持自定义 API Key,用户可使用自己的 Agnes Key。优化重点:降低
★ 1 📥 212