使用 MCP-Go 实现 PostgreSQL MCP Server

上周有朋友看了我分享的如何用golang实现一个MCP Server,问我能分享个数据库的mcp server吗?我想着也没多难,那就实现一个吧。接下来我将详细的介绍如何使用github.com/mark3labs/mcp-go 实现一个PostgreSQL MCP Server。

1. 功能说明

首先,在开发前我们得明确下需求,我们的 MCP Server 需要支持以下功能:

  • 创建表
  • 展示表
  • 执行读数据操作
  • 执行写数据操作

2. 实现 MCP Server Tools

上面明确了需要实现的功能,下面我们来实现对应的Tools。

go 复制代码
func createCreateTableTool() mcp.Tool {
	return mcp.NewTool("create_table",
		mcp.WithDescription("Create a new table in the postgres database"),
		mcp.WithString("schema",
			mcp.Required(),
			mcp.Description("CREATE TABLE SQL statement"),
		),
	)
}

func createListTablesTool() mcp.Tool {
	return mcp.NewTool("list_tables",
		mcp.WithDescription("List all user tables in the database"),
		mcp.WithString("schema",
			mcp.Description("Optional schema name to filter tables"),
		),
	)
}
func createReadQueryTool() mcp.Tool {
	return mcp.NewTool("read_query",
		mcp.WithDescription("Execute a SELECT query on the postgres database"),
		mcp.WithString("query",
			mcp.Required(),
			mcp.Description("SELECT SQL query to execute"),
		),
	)
}

func createWriteQueryTool() mcp.Tool {
	return mcp.NewTool("write_query",
		mcp.WithDescription("Execute an INSERT, UPDATE, or DELETE query on the postgres database"),
		mcp.WithString("query",
			mcp.Required(),
			mcp.Description("SQL query to execute"),
		),
	)
}

3. 连接 PostgreSQL

在数据库操作的Tools定义完后,还需要实现对应的handle方法,但是在这之前得先建立和数据库的连接, 下面代码给出数据库的连接:

go 复制代码
func initConnectionPool() error {
    // 获取数据库连接信息
	port, err := strconv.Atoi(os.Getenv("DB_PORT"))
	if err != nil {
		return fmt.Errorf("invalid DB_PORT: %w", err)
	}

	connStr := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
		os.Getenv("DB_HOST"),
		port,
		os.Getenv("DB_USER"),
		os.Getenv("DB_PASSWORD"),
		os.Getenv("DB_NAME"),
		os.Getenv("DB_SSLMODE"),
	)

	// 连接数据库
	db, err = sql.Open("postgres", connStr)
	if err != nil {
		return fmt.Errorf("database connection failed: %w", err)
	}
	if err = db.Ping(); err != nil {
		return fmt.Errorf("database ping failed: %w", err)
	}

	log.Println("Successfully connected to database")
	return nil
}

4. 添加handle函数

上面操作完成后,已经可以操作数据库了,接下来需要添加handle函数,用于处理来自mcp client的请求。

下面给出读取数据库表的handle函数的示例代码:

go 复制代码
func readQueryToolHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	query, ok := request.Params.Arguments["query"].(string)
	if !ok {
		return nil, errors.New("invalid query parameter")
	}

    // 验证查询语句是否为SELECT语句
	if !selectStmt.MatchString(query) {
		return nil, errors.New("only SELECT queries are allowed")
	}

	rows, err := db.QueryContext(ctx, query)
	if err != nil {
		log.Printf("Query error: %v\n", err)
		return nil, fmt.Errorf("query execution failed")
	}
	defer rows.Close()

	results, err := parseSQLRows(rows)
	if err != nil {
		return nil, fmt.Errorf("result parsing failed")
	}

	return mcp.NewToolResultText(fmt.Sprintf("Query results: %v", results)), nil
}

5. 测试

因为框架这边已经做了listTools的能力,所以我们的开发工作基本完成,接下来就是测试功能是否正常了 之前有分享过Mcp Inspector来验证mcp server的功能,这里我们还是使用这个工具来测试我们的pgsql-mcp-server是否可以正常工作 测试步骤如下:

  1. 启动mcp inspector和待测代码建立连接
bash 复制代码
npx @modelcontextprotocol/inspector go run main.go
  1. 跳转到http://localhost:5173 地址,在ui界面上测试功能
  2. 点击对应的tools进行测试

6. 配置到集成了mcp client的llm程序或插件

上面的测试验证基本没啥问题,这里我们可以用cline插件进行调式功能了。 首先是配置:

json 复制代码
{
  "mcpServers": {
    "pgsql-mcp-server": {
      "command": "C:\\Users\\Administrator\\go\\bin\\sql-mcp-server.exe",
      "args": [],
      "env": {
        "GOPATH": "C:\\Users\\Administrator\\go",
        "GOMODCACHE": "C:\\Users\\Administrator\\go\\pkg\\mod",
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "postgres",
        "DB_USER": "admin",
        "DB_PASSWORD": "postgres",
        "DB_SSLMODE": "disable"
      },
      "disabled": false,
      "autoApprove": []
    }
  }
}

保存配置后cline会自动尝试连接,当连接没问题会显示如下内容:

点击done即可在对话框中使用pgsql-mcp-server了,可以看到它对我输入的数据库的操作会调用tool去执行

查询表操作

总结

以上就是完整的使用 MCP-Go 开发一个 PostgreSQL MCP Server的流程。通过这个实现,你可以轻松地将 PostgreSQL 数据库功能暴露为 MCP 服务,供其他应用程序使用。 完整的代码我已经发布到github/pgsql-mcp-server上了,欢迎大家参考。

相关推荐
孔汤姆7 小时前
ESP32 掌机改造全记录:WiFi 遥测、一键启动 AI 终端
人工智能
HyperAI超神经7 小时前
【vLLM 学习】Disaggregated Prefill
人工智能·深度学习·学习·vllm
我星期八休息8 小时前
网络编程—网络层
开发语言·前端·网络·人工智能·智能路由器
逻辑君9 小时前
ANNA 7.2 方块机器人实验技术报告
人工智能·深度学习·机器学习·机器人
菜鸟‍9 小时前
【论文学习】Medical Image Analysis 2024 || 医学图像分割中失败检测方法的比较基准研究:揭示置信度聚合的作用
人工智能·学习
AI导出鸭9 小时前
怎么让千问做表格?AI导出鸭苹果版将千问输出的管道表格智能解析为二维结构,一键导出为Excel或Word标准表格。
人工智能·chatgpt·word·excel·ai导出鸭
陈嘿萌9 小时前
ECCV 2026 | 南开&OPPO开源 ExpoMotion:首个大规模动态多曝光融合数据集
人工智能·计算机视觉·图像融合·南开大学·新数据集·expomotion·多曝光融合
zyplayer-doc9 小时前
zyplayer-doc企业知识库能做什么:从文档创建、权限管理到AI问答的完整能力
大数据·javascript·数据库·人工智能·pdf·word
IT_陈寒9 小时前
为什么我的Java Stream流操作会吃掉内存?
前端·人工智能·后端
babe小鑫9 小时前
人工智能专业方向梳理的实用清单
人工智能