MCP协议服务器

一个基于Spring Boot和Spring AI构建的MCP协议服务器,为AI助手提供游戏视频目录访问功能,适用于企业级部署和Claude Desktop集成。

  • by AnkitPaunikar
  • Java
  • 本地部署
  • 更新于
在 GitHub 查看 ankitpaunikar/mcp-server

使用说明

MCP服务器

使用Spring Boot和Spring AI构建的简单模型上下文协议(MCP)服务器实现,旨在与Claude Desktop和其他兼容MCP的AI客户端无缝协作。

概述

此MCP服务器为AI助手提供了访问“Bee gaming”频道精心策划的游戏视频集的权限。它演示了如何通过模型上下文协议提供实时数据访问来创建扩展人工智能功能的自定义工具。

为什么Java适用于此MCP服务器?

企业级性能和可靠性

选择Java进行此实现,以提供超出典型MCP原型的生产就绪性能:

特性 Java+Spring AI Python/Node.js 影响
工具定义 @Tool 注释 手动协议处理 样板代码减少80%
类型安全 编译时验证 运行时错误 防止违反MCP协议
并发客户 1000+个连接 200-500个连接 3-5倍更好的可扩展性
记忆稳定性 可预测的GC 可变内存使用率 一致的性能

主要技术优势

🚀 Spring AI原生集成
与需要自定义MCP实现的Python/Node.js不同,Spring AI提供了零配置MCP协议处理,并具有自动工具注册和传输管理功能。

⚡ 生产性能
JVM优化以可预测的内存使用率提供每秒5000多个请求的吞吐量,使其成为可靠性重要的企业部署的理想选择。

🔒 企业安全
强类型可防止运行时MCP协议错误,而Spring Boot的安全模型提供生产级身份验证和授权功能。

🛠️ 开发者体验
与动态语言替代品相比,IntelliJ/Eclipse专门为MCP工具开发提供了卓越的调试、重构和测试支持。

当Java在MCP上表现出色时

Java是您需要时的最佳选择:

  • 高吞吐量MCP服务器 处理多个Claude Desktop实例
  • 长时间运行的生产服务器 需要99.9%的正常运行时间
  • 企业集成 现有的Java/Spring生态系统
  • 类型安全MCP工具开发 防止违反协议

对于快速原型或数据科学集成,Python仍然是更快的开发选择。

✨ 特性

  • 视频目录访问:检索可用游戏视频的完整列表
  • 按标题搜索:按确切标题查找特定视频
  • Spring Boot集成:使用Spring AI的MCP服务器框架构建
  • 轻便快速:针对CLI交互进行了优化的非web应用程序
  • 克劳德桌面兼容:已准备好与Claude Desktop应用程序集成
  • 企业就绪:生产级记录、配置和错误处理

🛠️ 使用的技术

  • Java 21 -具有现代语言功能的最新LTS版本
  • 弹簧靴3.5.0 -企业应用框架
  • 春季AI 1.0.0 -支持本机协议的MCP服务器启动器
  • 梅文 -依赖关系管理和构建自动化

📋 先决条件

在运行此MCP服务器之前,请确保:

  • 已安装Java 21或更高版本
  • 已安装Maven 3.6+
  • Claude桌面应用程序(用于集成)

🚀 快速开始

1.克隆存储库

git clone https://github.com/AnkitPaunikar/MCP-Server.git
cd MCP-Server

2.建设项目

mvn clean package -DskipTests

3.运行服务器

java -jar target/BasicMCPServer-0.0.1-SNAPSHOT.jar

🔧 配置

服务器通过以下方式配置 application.properties:

# MCP Server Configuration
spring.ai.mcp.server.name=ankit-mcp
spring.ai.mcp.server.version=0.0.1

# Application Settings
spring.application.name=BasicMCPServer
spring.main.web-application-type=none
spring.main.banner-mode=off

📱 Claude桌面集成

要将此MCP服务器与Claude Desktop一起使用:

  1. 找到您的Claude Desktop配置文件:

    • 窗户: %APPDATA%\Claude\claude_desktop_config.json
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  2. 添加服务器配置:

{
  "mcpServers": {
    "ankit-mcp": {
      "command": "java",
      "args": [
        "-jar",
        "/path/to/your/BasicMCPServer-0.0.1-SNAPSHOT.jar"
      ]
    }
  }
}
  1. 重新启动克劳德桌面 加载新服务器

🎮 可用工具

一旦连接,以下工具将在Claude中可用:

get_videos

检索可用游戏视频的完整列表。

用途: “显示所有可用视频”

get_video

按确切标题查找特定视频。

参数:

  • title (String):要搜索的视频的确切标题

用途: “找到标题为“隐士的最后一战!(无评论)”的视频。”

🔍 运作原理

  1. Spring AI集成:用途 @Tool 将方法作为MCP工具公开的注释
  2. 视频数据:维护内存中的游戏视频集合
  3. MCP协议:使用stdio传输与AI客户端通信
  4. 工具回调:自动向MCP框架注册工具

🌐 其他语言的实现

Python实现

使用FastMCP框架:

# server.py
from fastmcp import FastMCP
from typing import List

# Video data
videos = [
    {"title": "Final Fight of the hermit! (no commentary)", "url": "https://youtu.be/HnHtP4Mjyxk"},
    {"title": "Worlds most dangerous hermit", "url": "https://youtu.be/UaS0KBQ8Esc"}
]

mcp = FastMCP("Bee Gaming MCP")

@mcp.tool()
def get_videos() -> List[dict]:
    """Get a list of videos from Bee Gaming"""
    return videos

@mcp.tool()
def get_video(title: str) -> dict:
    """Get a video from Bee Gaming by title"""
    return next((video for video in videos if video["title"] == title), None)

if __name__ == "__main__":
    mcp.run()

安装与运行:

pip install fastmcp
python server.py

Claude桌面配置:

{
  "mcpServers": {
    "bee-gaming-python": {
      "command": "python",
      "args": ["server.py"]
    }
  }
}

Node.js实现

使用MCP SDK:

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

// Video data
const videos = [
    { title: "Final Fight of the hermit! (no commentary)", url: "https://youtu.be/HnHtP4Mjyxk" },
    { title: "Worlds most dangerous hermit", url: "https://youtu.be/UaS0KBQ8Esc" }
];

const server = new Server({
    name: "bee-gaming-mcp",
    version: "0.1.0"
}, {
    capabilities: {
        tools: {}
    }
});

// Tool handlers
server.setRequestHandler('tools/list', async () => ({
    tools: [
        { name: "get_videos", description: "Get a list of videos from Bee Gaming" },
        { name: "get_video", description: "Get a video from Bee Gaming by title" }
    ]
}));

server.setRequestHandler('tools/call', async (request) => {
    const { name, arguments: args } = request.params;
    
    switch (name) {
        case 'get_videos':
            return { content: [{ type: "text", text: JSON.stringify(videos) }] };
        case 'get_video':
            const video = videos.find(v => v.title === args.title);
            return { content: [{ type: "text", text: JSON.stringify(video) }] };
        default:
            throw new Error(`Unknown tool: ${name}`);
    }
});

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

安装与运行:

npm install @modelcontextprotocol/sdk
node server.js

Claude桌面配置:

{
  "mcpServers": {
    "bee-gaming-node": {
      "command": "node",
      "args": ["server.js"]
    }
  }
}

Rust实现

使用tokio mcp机箱:

// src/main.rs
use serde_json::json;
use std::collections::HashMap;
use tokio_mcp::{McpServer, Tool, ToolResult};

#[derive(Clone)]
struct Video {
    title: String,
    url: String,
}

struct BeeGamingServer {
    videos: Vec<Video>,
}

impl BeeGamingServer {
    fn new() -> Self {
        Self {
            videos: vec![
                Video {
                    title: "Final Fight of the hermit! (no commentary)".to_string(),
                    url: "https://youtu.be/HnHtP4Mjyxk".to_string(),
                },
                Video {
                    title: "Worlds most dangerous hermit".to_string(),
                    url: "https://youtu.be/UaS0KBQ8Esc".to_string(),
                },
            ],
        }
    }
}

#[async_trait::async_trait]
impl McpServer for BeeGamingServer {
    async fn handle_tool(&self, name: &str, args: HashMap<String, serde_json::Value>) -> ToolResult {
        match name {
            "get_videos" => {
                let videos_json = serde_json::to_string(&self.videos)?;
                Ok(json!({ "content": [{ "type": "text", "text": videos_json }] }))
            }
            "get_video" => {
                let title = args.get("title").and_then(|v| v.as_str()).unwrap_or("");
                let video = self.videos.iter().find(|v| v.title == title);
                let result = serde_json::to_string(&video)?;
                Ok(json!({ "content": [{ "type": "text", "text": result }] }))
            }
            _ => Err(format!("Unknown tool: {}", name).into()),
        }
    }

    fn get_tools(&self) -> Vec<Tool> {
        vec![
            Tool {
                name: "get_videos".to_string(),
                description: "Get a list of videos from Bee Gaming".to_string(),
                input_schema: json!({}),
            },
            Tool {
                name: "get_video".to_string(),
                description: "Get a video from Bee Gaming by title".to_string(),
                input_schema: json!({
                    "type": "object",
                    "properties": {
                        "title": { "type": "string" }
                    }
                }),
            },
        ]
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let server = BeeGamingServer::new();
    server.run().await?;
    Ok(())
}

安装与运行:

# Cargo.toml
[dependencies]
tokio-mcp = "0.1"
serde_json = "1.0"
async-trait = "0.1"

cargo run

Claude桌面配置:

{
  "mcpServers": {
    "bee-gaming-rust": {
      "command": "./target/release/bee-gaming-mcp"
    }
  }
}

Go实现

使用自定义MCP实现:

// main.go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "os"
)

type Video struct {
    Title string `json:"title"`
    URL   string `json:"url"`
}

type MCPServer struct {
    videos []Video
}

func NewMCPServer() *MCPServer {
    return &MCPServer{
        videos: []Video{
            {Title: "Final Fight of the hermit! (no commentary)", URL: "https://youtu.be/HnHtP4Mjyxk"},
            {Title: "Worlds most dangerous hermit", URL: "https://youtu.be/UaS0KBQ8Esc"},
        },
    }
}

func (s *MCPServer) HandleTool(toolName string, args map[string]interface{}) (interface{}, error) {
    switch toolName {
    case "get_videos":
        return s.videos, nil
    case "get_video":
        title, ok := args["title"].(string)
        if !ok {
            return nil, fmt.Errorf("title parameter required")
        }
        for _, video := range s.videos {
            if video.Title == title {
                return video, nil
            }
        }
        return nil, nil
    default:
        return nil, fmt.Errorf("unknown tool: %s", toolName)
    }
}

func main() {
    server := NewMCPServer()
    
    // MCP protocol handling (simplified)
    decoder := json.NewDecoder(os.Stdin)
    encoder := json.NewEncoder(os.Stdout)
    
    for {
        var request map[string]interface{}
        if err := decoder.Decode(&request); err != nil {
            log.Fatal(err)
        }
        
        // Handle MCP request (simplified)
        if method, ok := request["method"].(string); ok && method == "tools/call" {
            params := request["params"].(map[string]interface{})
            toolName := params["name"].(string)
            args := params["arguments"].(map[string]interface{})
            
            result, err := server.HandleTool(toolName, args)
            if err != nil {
                encoder.Encode(map[string]interface{}{
                    "id": request["id"],
                    "error": map[string]string{"message": err.Error()},
                })
            } else {
                encoder.Encode(map[string]interface{}{
                    "id": request["id"],
                    "result": map[string]interface{}{
                        "content": []map[string]string{{
                            "type": "text",
                            "text": fmt.Sprintf("%v", result),
                        }},
                    },
                })
            }
        }
    }
}

安装与运行:

go mod init bee-gaming-mcp
go run main.go

Claude桌面配置:

{
  "mcpServers": {
    "bee-gaming-go": {
      "command": "./bee-gaming-mcp"
    }
  }
}

📊 语言比较摘要

语言 代码行 设置复杂性 性能 生态系统
Java 约50行 中等(Maven) 优秀 成熟
python 约25行 简单(点) 良好 优秀
Node.js ~ 45行 简单(npm) 很好 很好
锈 约80行 中等(货物) 优秀 有限
去 约70行 简单(go mod) 非常好 成长中

关键要点:

  • python:原型制作速度最快,最大的MCP社区
  • Java:最适合企业生产部署
  • Node.js:非常适合基于web的MCP集成
  • 锈:最高性能,陡峭的学习曲线
  • 去:简单性和性能的良好平衡

📄 许可证: 该项目是开源的,可在 MIT许可证.