AI工具集成服务器

一个基于Spring Boot的MCP服务器,提供与Claude、Perplexity、ChatGPT等AI客户端的集成工具,适合企业级部署。

  • by ShanmugaSivapragasam
  • Shell
  • 本地部署
  • 更新于
在 GitHub 查看 ShanmugaSivapragasam/hello-mcp

使用说明

你好MCP服务器

一个生产就绪的Spring Boot MCP(模型上下文协议)服务器,提供与Claude、Perplexity、ChatGPT和其他AI客户端集成的AI工具。采用Spring AI MCP框架构建,用于企业级部署。

概述

此MCP服务器通过模型上下文协议公开AI工具,实现与各种AI平台的无缝集成。服务器提供 hello-tool 它演示了MCP架构,可以用自定义业务逻辑进行扩展。

主要特点

  • ✅ 生产就绪:使用Spring Boot 3.5.7和Java 21构建
  • ✅ 符合MCP协议:使用Spring AI MCP服务器WebVC
  • ✅ 企业级:全面的日志记录、监控和安全
  • ✅ 可扩展架构:支持水平扩展和负载平衡
  • ✅ 多AI平台支持:兼容克劳德、ChatGPT、困惑
  • ✅ 云原生:Docker和Kubernetes就绪

技术规格

  • 框架:弹簧靴3.5.7
  • Java版本: 21
  • 生成工具:Gradle 8.x
  • 协议:MCP(模型上下文协议)
  • 建筑:微服务/独立
  • 部署:JAR、Docker、Kubernetes

🚀 快速启动(30秒)

# Clone and start the server
git clone https://github.com/your-org/hello-mcp.git
cd hello-mcp
./start.sh

服务器将在以下时间运行 http://localhost:8080 MCP工具已准备好进行AI集成!

可用工具

hello工具

  • 描述:从MCP服务器返回问候消息
  • 用法:演示MCP工具功能
  • 响应: "Hello from MCP server!"
  • Spring Boot: 3.5.7
  • 春季AI:1.1.0-M4(支持MCP服务器)
  • Gradle: 8.14.3
  • 生成工具:Gradle包装

特性

  • 用Spring AI实现MCP服务器
  • 简单的问候工具(hello-tool)
  • 可配置的MCP服务器设置
  • RESTful web端点
  • 综合录井

项目结构

src/main/java/com/shan/hello_mcp/
├── HelloMcpApplication.java    # Main Spring Boot application
└── HelloTools.java             # MCP tools implementation

入门指南

先决条件

  • Java 25或更高版本
  • Git

安装和设置

  1. 克隆存储库:

    git clone <repository-url>
    cd hello-mcp
    
  2. 构建项目:

    ./gradlew build
    
  3. 运行应用程序:

    ./gradlew bootRun
    

应用程序将在默认端口(8080)上启动,MCP服务器将可用于客户端连接。

配置

MCP服务器配置在 application.properties:

spring.application.name=hello-mcp
spring.ai.mcp.server.name=HelloMCPServer
spring.ai.mcp.server.description=A simple MCP server application
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.author=Shan
spring.ai.mcp.server.protocol=streamable
spring.ai.mcp.server.stdio=false
spring.ai.mcp.server.type=sync

可用工具

hello工具

  • 名字: hello-tool
  • 描述:一个从MCP服务器返回问候消息的工具
  • 响应:返回“来自MCP服务器的Hello!”消息

用法示例

当连接到MCP客户端时,您可以调用 hello-tool 以接收问候消息。该工具将记录通话并返回问候响应。

发展

运行测试

./gradlew test

生产大楼

./gradlew bootJar

可执行JAR将在 build/libs/.

依赖项

关键依赖关系包括:

  • spring-boot-starter-web:Web框架支持
  • spring-ai-starter-mcp-server-webmvc:MCP服务器实现
  • spring-boot-starter-test:测试框架

作者

山

版本

0.0.1快照

快速开始

先决条件

  • Java 21或更高版本
  • Gradle 8.x
  • Git
  • Docker(可选)
  • Kubernetes(用于生产部署)

开发设置

  1. 克隆存储库

    git clone https://github.com/your-org/hello-mcp.git
    cd hello-mcp
    
  2. 构建应用程序

    ./gradlew build
    
  3. 在本地运行

    ./gradlew bootRun
    
  4. 验证服务器

    curl http://localhost:8080/actuator/health
    

生产部署指南

选项1:传统JAR部署

1.构建生产JAR

./gradlew clean build -Pprofile=prod

2.服务器设置(Ubuntu/RHEL)

# Create application user
sudo useradd -r -s /bin/false mcp-server

# Create directories
sudo mkdir -p /opt/mcp-server/{bin,config,logs}
sudo chown -R mcp-server:mcp-server /opt/mcp-server

# Copy JAR
sudo cp build/libs/hello-mcp-0.0.1-SNAPSHOT.jar /opt/mcp-server/bin/

3.生产配置

创建 /opt/mcp-server/config/application-prod.properties:

# Server Configuration
server.port=8080
server.servlet.context-path=/mcp
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s

# MCP Server Configuration
spring.application.name=hello-mcp
spring.ai.mcp.server.name=HelloMCPServer-Prod
spring.ai.mcp.server.description=Production MCP server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.author=Enterprise Team

# Protocol Configuration
spring.ai.mcp.server.protocol=streamable
spring.ai.mcp.server.stdio=false
spring.ai.mcp.server.type=sync

# Logging Configuration
logging.level.com.shan.hello_mcp=INFO
logging.level.org.springframework.ai.mcp=DEBUG
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
logging.file.name=/opt/mcp-server/logs/application.log
logging.logback.rollingpolicy.max-file-size=100MB
logging.logback.rollingpolicy.total-size-cap=1GB

# Actuator (Monitoring)
management.endpoints.web.exposure.include=health,info,metrics,prometheus
management.endpoint.health.show-details=when-authorized
management.metrics.export.prometheus.enabled=true

# Security (if enabled)
management.endpoints.web.base-path=/actuator
management.server.port=9090

4.SystemD服务

创建 /etc/systemd/system/mcp-server.service:

[Unit]
Description=Hello MCP Server
After=network.target

[Service]
Type=simple
User=mcp-server
Group=mcp-server
WorkingDirectory=/opt/mcp-server
ExecStart=/usr/bin/java \
    -Xms512m -Xmx2g \
    -XX:+UseG1GC \
    -XX:MaxGCPauseMillis=200 \
    -Dspring.profiles.active=prod \
    -Dspring.config.location=/opt/mcp-server/config/ \
    -jar /opt/mcp-server/bin/hello-mcp-0.0.1-SNAPSHOT.jar
ExecStop=/bin/kill -TERM $MAINPID
Restart=always
RestartSec=30
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

5.启动服务

sudo systemctl daemon-reload
sudo systemctl enable mcp-server
sudo systemctl start mcp-server
sudo systemctl status mcp-server

选项2:Docker部署

1.创建Dockerfile

FROM openjdk:25-jdk-slim

# Create app user
RUN groupadd -r mcpuser && useradd -r -g mcpuser mcpuser

# Set working directory
WORKDIR /app

# Copy JAR
COPY build/libs/hello-mcp-*.jar app.jar

# Create logs directory
RUN mkdir -p /app/logs && chown -R mcpuser:mcpuser /app

# Switch to non-root user
USER mcpuser

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

# Expose ports
EXPOSE 8080 9090

# JVM options for containers
ENV JAVA_OPTS="-Xms512m -Xmx1g -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"

# Run application
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

2.构建和运行

# Build image
docker build -t hello-mcp:latest .

# Run container
docker run -d \
  --name mcp-server \
  -p 8080:8080 \
  -p 9090:9090 \
  -e SPRING_PROFILES_ACTIVE=prod \
  -v /opt/mcp-server/logs:/app/logs \
  --restart unless-stopped \
  hello-mcp:latest

选项3:Kubernetes部署

1.创建Kubernetes清单

namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: mcp-server
  labels:
    name: mcp-server

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mcp-server-config
  namespace: mcp-server
data:
  application-prod.properties: |
    server.port=8080
    spring.profiles.active=prod
    spring.ai.mcp.server.name=HelloMCPServer-K8s
    logging.level.com.shan.hello_mcp=INFO
    management.endpoints.web.exposure.include=health,info,metrics,prometheus

部署.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mcp-server
  namespace: mcp-server
  labels:
    app: mcp-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mcp-server
  template:
    metadata:
      labels:
        app: mcp-server
    spec:
      containers:
      - name: mcp-server
        image: hello-mcp:latest
        ports:
        - containerPort: 8080
        - containerPort: 9090
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        - name: JAVA_OPTS
          value: "-Xms512m -Xmx1g -XX:+UseContainerSupport"
        volumeMounts:
        - name: config-volume
          mountPath: /app/config
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 9090
          initialDelaySeconds: 60
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 9090
          initialDelaySeconds: 30
          periodSeconds: 10
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
      volumes:
      - name: config-volume
        configMap:
          name: mcp-server-config

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: mcp-server-service
  namespace: mcp-server
  labels:
    app: mcp-server
spec:
  selector:
    app: mcp-server
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  - name: management
    port: 9090
    targetPort: 9090
  type: ClusterIP

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mcp-server-ingress
  namespace: mcp-server
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - mcp.yourdomain.com
    secretName: mcp-server-tls
  rules:
  - host: mcp.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: mcp-server-service
            port:
              number: 8080

2.部署到Kubernetes

# Apply manifests
kubectl apply -f k8s/

# Verify deployment
kubectl get pods -n mcp-server
kubectl get services -n mcp-server
kubectl logs -f deployment/mcp-server -n mcp-server

负载均衡器和反向代理设置

Nginx配置

upstream mcp_backend {
    server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8080 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    listen 443 ssl http2;
    server_name mcp.yourdomain.com;

    # SSL Configuration
    ssl_certificate /etc/ssl/certs/mcp.yourdomain.com.crt;
    ssl_certificate_key /etc/ssl/private/mcp.yourdomain.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;

    # Security Headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Rate Limiting
    limit_req_zone $binary_remote_addr zone=mcp_limit:10m rate=10r/s;
    limit_req zone=mcp_limit burst=20 nodelay;

    location / {
        proxy_pass http://mcp_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
        
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
        proxy_busy_buffers_size 8k;
    }

    location /actuator {
        deny all;
        return 403;
    }
}

AI平台集成

克劳德集成

import anthropic
import requests

# MCP Server connection
MCP_SERVER_URL = "https://mcp.yourdomain.com"

def call_mcp_tool(tool_name, **kwargs):
    response = requests.post(
        f"{MCP_SERVER_URL}/mcp/tools/{tool_name}",
        json=kwargs,
        headers={"Content-Type": "application/json"}
    )
    return response.json()

# Use with Claude
client = anthropic.Anthropic(api_key="your-api-key")

# Call MCP tool
greeting = call_mcp_tool("hello-tool")
print(f"MCP Response: {greeting}")

ChatGPT集成

const axios = require('axios');

const MCP_SERVER_URL = 'https://mcp.yourdomain.com';

async function callMcpTool(toolName, params = {}) {
    try {
        const response = await axios.post(
            `${MCP_SERVER_URL}/mcp/tools/${toolName}`,
            params,
            {
                headers: { 'Content-Type': 'application/json' }
            }
        );
        return response.data;
    } catch (error) {
        console.error('MCP Tool Error:', error);
        throw error;
    }
}

// Example usage
async function main() {
    const greeting = await callMcpTool('hello-tool');
    console.log('MCP Response:', greeting);
}

困惑整合

import requests
from typing import Dict, Any

class McpClient:
    def __init__(self, base_url: str):
        self.base_url = base_url.rstrip('/')
    
    def call_tool(self, tool_name: str, **kwargs) -> Dict[str, Any]:
        response = requests.post(
            f"{self.base_url}/mcp/tools/{tool_name}",
            json=kwargs,
            timeout=30
        )
        response.raise_for_status()
        return response.json()

# Initialize MCP client
mcp = McpClient("https://mcp.yourdomain.com")

# Use with Perplexity workflows
def enhanced_search_with_mcp():
    # Call MCP tool first
    greeting = mcp.call_tool("hello-tool")
    
    # Then proceed with Perplexity search
    return greeting

监测和可观察性

普罗米修斯指标

访问指标: http://your-server:9090/actuator/prometheus

需监控的关键指标:

  • jvm_memory_used_bytes
  • http_server_requests_seconds
  • mcp_tool_calls_total
  • application_ready_time_seconds

Grafana仪表板

导入提供的Grafana仪表板JSON以进行全面监控。

日志分析

# View real-time logs
sudo journalctl -u mcp-server -f

# Search for specific patterns
sudo journalctl -u mcp-server | grep "ERROR\|WARN"

# Export logs for analysis
sudo journalctl -u mcp-server --since="1 hour ago" > /tmp/mcp-logs.txt

安全考虑

生产安全检查表

  • [ ] 网络安全

    • 防火墙已配置(仅端口80、443、22打开)
    • 用于内部通信的VPN/VPC
    • 带SSL终止的负载平衡器
  • [ ] 应用安全

    • 已启用Spring安全
    • 已实施利率限制
    • 在所有端点上进行输入验证
    • CORS配置正确
  • [ ] 基础设施安全

    • 定期安全更新
    • 非root用户执行
    • 秘密管理(HashiCorp保险库/K8s秘密)
    • 容器漏洞扫描
  • [ ] 监控和警报

    • 实时错误警报
    • 性能监控
    • 安全事件日志记录
    • 审计跟踪维护

环境变量

# Required for production
export SPRING_PROFILES_ACTIVE=prod
export MCP_SERVER_SECRET_KEY=your-secret-key
export DATABASE_URL=your-database-url
export MONITORING_API_KEY=your-monitoring-key

故障排除

常见问题

  1. 端口已在使用中

    sudo lsof -i :8080
    sudo kill -9 <PID>
    
  2. 内存问题

    # Increase JVM heap size
    export JAVA_OPTS="-Xms1g -Xmx4g"
    
  3. MCP连接问题

    # Check MCP endpoint
    curl -v http://localhost:8080/mcp/tools
    
  4. SSL证书问题

    # Verify certificate
    openssl x509 -in /path/to/cert.pem -text -noout
    

性能调整

JVM生产调优

JAVA_OPTS="
  -Xms2g -Xmx4g
  -XX:+UseG1GC
  -XX:MaxGCPauseMillis=200
  -XX:+UseStringDeduplication
  -XX:+OptimizeStringConcat
  -XX:+UseCompressedOops
  -Djava.security.egd=file:/dev/./urandom
"

数据库连接池

# HikariCP Configuration
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=600000
spring.datasource.hikari.connection-timeout=20000

可扩展性和高可用性

水平缩放

  • 在负载均衡器后面部署多个实例
  • 使用无会话设计(无状态)
  • 实施断路器以提高弹性

垂直缩放

  • 监控CPU/内存使用情况
  • 相应地调整JVM堆大小
  • 使用分析工具进行优化

数据库扩展

  • 读取副本以应对读取繁重的工作负载
  • 连接池优化
  • 查询性能调优

支持与维护

定期维护任务

  1. 周刊

    • 查看应用程序日志
    • 检查系统指标
    • 更新依赖关系(安全补丁)
  2. 每月

    • 绩效评估
    • 容量规划
    • 安全审计
  3. 季度

    • 测试
    • 建筑评论
    • 技术栈更新

获取帮助

许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。


企业支持可用 -联系我们获取生产支持、定制功能和SLA保证。