SQL数据库连接服务

Paprika MCP Server是一个用于将Claude连接到自定义SQL数据库的模型上下文协议(MCP)桌面扩展,支持实时查询和交互数据库。

  • by jonaheaton
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 jonaheaton/paprika_mcp_server

使用说明

Paprika MCP服务器

用于将Claude连接到自定义SQL数据库的模型上下文协议(MCP)桌面扩展。此服务器允许Claude在对话期间实时查询您的数据库并与之交互。

概述

MCP桌面扩展允许您创建自定义工具,Claude可以直接通过桌面应用程序使用这些工具。此实现提供了一个SQL数据库接口,允许Claude执行查询、探索模式和分析数据。

项目设置

1.初始化项目

cd /Users/jonaheaton/Documents/paprika_mcp_server
npm init -y

2.安装依赖项

npm install @modelcontextprotocol/sdk
npm install better-sqlite3  # For SQLite
# OR for other databases:
# npm install mysql2        # For MySQL
# npm install pg            # For PostgreSQL

3.创建MCP服务器

创建一个名为的文件 server.js:

#!/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 Database from 'better-sqlite3'; // or your preferred SQL driver

class SQLMCPServer {
  constructor() {
    this.server = new Server(
      {
        name: 'paprika-sql-server',
        version: '0.1.0',
      },
      {
        capabilities: {
          tools: {},
        },
      }
    );

    // Initialize your database connection
    this.db = new Database('path/to/your/database.db'); // Update with your database path
    
    this.setupToolHandlers();
  }

  setupToolHandlers() {
    // List available tools
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: 'query_sql',
            description: 'Execute a SQL query on the database',
            inputSchema: {
              type: 'object',
              properties: {
                query: {
                  type: 'string',
                  description: 'SQL query to execute',
                },
              },
              required: ['query'],
            },
          },
          {
            name: 'describe_tables',
            description: 'Get schema information for all tables',
            inputSchema: {
              type: 'object',
              properties: {},
            },
          },
          {
            name: 'get_table_schema',
            description: 'Get detailed schema for a specific table',
            inputSchema: {
              type: 'object',
              properties: {
                table_name: {
                  type: 'string',
                  description: 'Name of the table to describe',
                },
              },
              required: ['table_name'],
            },
          },
        ],
      };
    });

    // Handle tool calls
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;

      try {
        switch (name) {
          case 'query_sql':
            return await this.executeQuery(args.query);
          
          case 'describe_tables':
            return await this.describeTables();
          
          case 'get_table_schema':
            return await this.getTableSchema(args.table_name);
          
          default:
            throw new Error(`Unknown tool: ${name}`);
        }
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error.message}`,
            },
          ],
        };
      }
    });
  }

  async executeQuery(query) {
    try {
      // Prevent destructive operations if needed
      const lowerQuery = query.toLowerCase().trim();
      if (lowerQuery.startsWith('drop') || lowerQuery.startsWith('delete') || lowerQuery.startsWith('truncate')) {
        throw new Error('Destructive operations are not allowed');
      }

      const result = this.db.prepare(query).all();
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
    } catch (error) {
      throw new Error(`SQL execution failed: ${error.message}`);
    }
  }

  async describeTables() {
    try {
      const tables = this.db.prepare(`
        SELECT name FROM sqlite_master 
        WHERE type='table' AND name NOT LIKE 'sqlite_%'
      `).all();
      
      return {
        content: [
          {
            type: 'text',
            text: `Available tables: ${tables.map(t => t.name).join(', ')}`,
          },
        ],
      };
    } catch (error) {
      throw new Error(`Failed to describe tables: ${error.message}`);
    }
  }

  async getTableSchema(tableName) {
    try {
      const schema = this.db.prepare(`PRAGMA table_info(${tableName})`).all();
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(schema, null, 2),
          },
        ],
      };
    } catch (error) {
      throw new Error(`Failed to get schema for ${tableName}: ${error.message}`);
    }
  }

  async run() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
  }
}

const server = new SQLMCPServer();
server.run().catch(console.error);

4.配置Package.json

更新您的 package.json:

{
  "name": "paprika-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "main": "server.js",
  "bin": {
    "paprika-mcp-server": "./server.js"
  },
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.1.0",
    "better-sqlite3": "^8.7.0"
  }
}

安装

1.全局安装软件包

npm install -g .

2.配置克劳德桌面

创建或编辑Claude桌面配置文件:

地点: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "paprika-database": {
      "command": "paprika-mcp-server",
      "args": []
    }
  }
}

3.重新启动克劳德桌面

更改配置后,重新启动Claude Desktop应用程序。

数据库特定配置

SQLite(默认)

import Database from 'better-sqlite3';
this.db = new Database('/path/to/your/database.db');

PostgreSQL

import pg from 'pg';
const { Pool } = pg;

this.db = new Pool({
  user: 'your_user',
  host: 'localhost',
  database: 'your_database',
  password: 'your_password',
  port: 5432,
});

// Update query execution method for async/await
async executeQuery(query) {
  const result = await this.db.query(query);
  return {
    content: [
      {
        type: 'text',
        text: JSON.stringify(result.rows, null, 2),
      },
    ],
  };
}

MySQL

import mysql from 'mysql2/promise';

this.db = await mysql.createConnection({
  host: 'localhost',
  user: 'your_user',
  password: 'your_password',
  database: 'your_database'
});

// Update query execution method
async executeQuery(query) {
  const [rows] = await this.db.execute(query);
  return {
    content: [
      {
        type: 'text',
        text: JSON.stringify(rows, null, 2),
      },
    ],
  };
}

使用示例

配置后,您可以要求Claude与您的数据库进行交互:

  • “显示数据库中的所有表”
  • “查询用户表中的最新条目”
  • “产品表的模式是什么?”
  • “查找状态为“活动”的所有记录”
  • “按类别获取记录数”

安全考虑

查询限制

服务器包括针对破坏性操作的基本保护:

  • DROP 语句被阻止
  • DELETE 语句被阻止
  • TRUNCATE 语句被阻止

附加安全措施

  • 考虑实现只读数据库访问
  • 添加输入验证和净化
  • 实施查询结果大小限制
  • 如果需要,添加身份验证
  • 使用环境变量进行敏感配置

环境配置示例

// Use environment variables for database connection
this.db = new Database(process.env.DATABASE_PATH || './default.db');

高级功能

1.查询结果格式

添加将结果格式化为表格或图表的方法:

formatAsTable(data) {
  // Convert JSON to formatted table
}

formatAsChart(data) {
  // Generate chart data
}

2.查询历史和缓存

实现查询缓存以提高性能:

this.queryCache = new Map();

async executeQuery(query) {
  if (this.queryCache.has(query)) {
    return this.queryCache.get(query);
  }
  // Execute and cache result
}

3.多数据库支持

扩展以支持多个数据库连接:

this.databases = {
  primary: new Database('./primary.db'),
  analytics: new Database('./analytics.db')
};

4.自定义业务逻辑

添加特定于域的功能:

{
  name: 'get_recipe_by_ingredient',
  description: 'Find recipes containing specific ingredients',
  // ... implementation
}

故障排除

常见问题

  1. 服务器未出现在Claude中

    • 检查配置文件路径是否正确
    • 验证服务器是否已全局安装
    • 重新启动克劳德桌面
  2. 数据库连接错误

    • 验证数据库文件路径是否正确
    • 检查数据库权限
    • 确保已安装数据库驱动程序
  3. 查询执行错误

    • 验证SQL语法
    • 检查表和列名
    • 查看Claude中的错误消息

调试

通过添加调试语句启用详细日志记录:

console.error('Debug:', JSON.stringify(request, null, 2));

发展

测试服务器

# Test the server directly
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' | node server.js

进行更改

  1. 编辑 server.js
  2. 全局重新安装: npm install -g .
  3. 重新启动克劳德桌面

贡献

  1. 分叉存储库
  2. 创建要素分支
  3. 进行更改
  4. 彻底测试
  5. 提交拉取请求

许可证

MIT许可证-有关详细信息,请参阅许可证文件。