MCP协议实现库

mcp-glib是一个基于GLib/GObject的Model Context Protocol (MCP)实现,用于在C语言中构建MCP服务器和客户端,支持多种传输协议和异步操作。

  • by copyleft-games
  • C
  • 本地部署
  • 更新于
在 GitHub 查看 copyleft-games/mcp-glib

使用说明

mcp glib

GLib/GObject的实现 模型上下文协议(MCP) 用于在C中构建MCP服务器和客户端。

特性

  • MCP服务器支持 -向人工智能应用程序公开工具、资源和提示
  • MCP客户端支持 -连接到MCP服务器并与之交互
  • 任务API -对长时间运行的工具操作的实验支持
  • 标准运输 -通过stdin/stdout进行基于进程的通信
  • HTTP/WebSocket传输 -libsoup-3上的客户端和服务器变体
  • 多路传输 -用于在另一协议内隧道传输MCP的无I/O多路复用传输
  • G对象反思 -对语言绑定(Python、JavaScript等)的一流支持
  • 异步操作 -基于libdex构建,用于可组合异步期货
  • 交叉平台的 -通过mingw交叉编译的Windows DLL

状态

完成 -完整的MCP 2025-03-26协议实施,包括:

  • 工具、资源、资源模板和提示
  • 具有异步操作的服务器和客户端类
  • 为长时间运行的操作任务API(实验)
  • 带有子进程生成的Stdio传输
  • 用于语言绑定的GIR/typelib生成
  • 综合测试套件(170多项测试)

需求

  • 支持gnu89的GCC
  • GLib 2.0/GObject 2.0/GIO 2.0/GIO Unix 2.0
  • json-glib 1.0
  • libsoup 3.0
  • Libdex 1.0

Fedora 43

sudo dnf install gcc make pkgconfig glib2-devel json-glib-devel \
    libsoup3-devel libdex-devel gobject-introspection-devel

建筑

make              # Build library
make test         # Run tests
make examples     # Build examples
make gir          # Generate GIR and typelib
make install      # Install to /usr/local

交叉编译

make WINDOWS=1      # Windows x64 DLL (via mingw)
make LINUX_ARM64=1  # Linux ARM64

看 docs/building.md 了解详情。

快速示例

简单MCP服务器

#include <mcp/mcp.h>

static GMainLoop *main_loop = NULL;

/* Tool handler - called when client invokes the tool */
static McpToolResult *
echo_handler (McpServer  *server,
              const gchar *name,
              JsonObject  *arguments,
              gpointer     user_data)
{
    McpToolResult *result;
    const gchar *message = NULL;

    if (arguments != NULL && json_object_has_member (arguments, "message"))
    {
        message = json_object_get_string_member (arguments, "message");
    }

    if (message == NULL)
    {
        message = "(no message)";
    }

    result = mcp_tool_result_new (FALSE);
    mcp_tool_result_add_text (result, message);

    return result;
}

static void
on_client_disconnected (McpServer *server, gpointer user_data)
{
    g_main_loop_quit (main_loop);
}

int
main (int argc, char *argv[])
{
    g_autoptr(McpServer) server = NULL;
    g_autoptr(McpStdioTransport) transport = NULL;
    g_autoptr(McpTool) echo_tool = NULL;

    main_loop = g_main_loop_new (NULL, FALSE);

    /* Create server */
    server = mcp_server_new ("my-server", "1.0.0");
    mcp_server_set_instructions (server, "Use the echo tool to echo messages.");

    g_signal_connect (server, "client-disconnected",
                      G_CALLBACK (on_client_disconnected), NULL);

    /* Add a tool */
    echo_tool = mcp_tool_new ("echo", "Echoes back the message");
    mcp_server_add_tool (server, echo_tool, echo_handler, NULL, NULL);

    /* Create stdio transport and start */
    transport = mcp_stdio_transport_new ();
    mcp_server_set_transport (server, MCP_TRANSPORT (transport));
    mcp_server_start_async (server, NULL, NULL, NULL);

    g_main_loop_run (main_loop);
    g_main_loop_unref (main_loop);

    return 0;
}

简单MCP客户端

#include <mcp/mcp.h>

static GMainLoop *main_loop = NULL;
static McpClient *client = NULL;

static void
on_tool_called (GObject      *source,
                GAsyncResult *result,
                gpointer      user_data)
{
    g_autoptr(GError) error = NULL;
    McpToolResult *tool_result;

    tool_result = mcp_client_call_tool_finish (MCP_CLIENT (source), result, &error);

    if (error != NULL)
    {
        g_printerr ("Tool call failed: %s\n", error->message);
    }
    else
    {
        JsonArray *content = mcp_tool_result_get_content (tool_result);
        guint i;

        for (i = 0; i < json_array_get_length (content); i++)
        {
            JsonObject *item = json_array_get_object_element (content, i);
            const gchar *type = json_object_get_string_member (item, "type");

            if (g_strcmp0 (type, "text") == 0)
            {
                g_print ("Result: %s\n", json_object_get_string_member (item, "text"));
            }
        }

        mcp_tool_result_unref (tool_result);
    }

    g_main_loop_quit (main_loop);
}

static void
on_connected (GObject      *source,
              GAsyncResult *result,
              gpointer      user_data)
{
    g_autoptr(GError) error = NULL;
    g_autoptr(JsonObject) args = NULL;

    if (!mcp_client_connect_finish (MCP_CLIENT (source), result, &error))
    {
        g_printerr ("Connection failed: %s\n", error->message);
        g_main_loop_quit (main_loop);
        return;
    }

    g_print ("Connected!\n");

    /* Call the echo tool */
    args = json_object_new ();
    json_object_set_string_member (args, "message", "Hello, MCP!");
    mcp_client_call_tool_async (client, "echo", args, NULL, on_tool_called, NULL);
}

int
main (int argc, char *argv[])
{
    g_autoptr(McpStdioTransport) transport = NULL;
    g_autoptr(GError) error = NULL;

    main_loop = g_main_loop_new (NULL, FALSE);

    /* Create client */
    client = mcp_client_new ("my-client", "1.0.0");

    /* Spawn server as subprocess */
    transport = mcp_stdio_transport_new_subprocess_simple ("./my-server", &error);
    if (transport == NULL)
    {
        g_printerr ("Failed to spawn server: %s\n", error->message);
        return 1;
    }

    mcp_client_set_transport (client, MCP_TRANSPORT (transport));
    mcp_client_connect_async (client, NULL, on_connected, NULL);

    g_main_loop_run (main_loop);

    g_object_unref (client);
    g_main_loop_unref (main_loop);

    return 0;
}

例子

这 examples/ 目录包含工作示例程序:

  • 简单服务器.c -带有echo工具、自述文件资源和问候提示的最小服务器
  • 简单客户端.c -连接到服务器并执行所有功能的客户端
  • 计算器服务器.c -计算器加,减,乘,除,sqrt,电动工具
  • 文件系统服务器.c -使用资源模板从目录中提供文件

构建和运行示例:

make examples
./build/simple-client ./build/simple-server
./build/simple-client ./build/calculator-server
./build/simple-client ./build/filesystem-server /path/to/directory

CLI工具

用于与MCP服务器交互的命令行工具:

工具 说明
mcp-inspect 显示服务器信息、功能、工具、资源、提示
mcp-call 使用JSON参数调用特定工具
mcp-read 按URI读取资源
mcp-prompt 获取带有参数的提示
mcp-shell 用于探索服务器的交互式REPL
mcp-remote-client 将stdio代理到远程HTTP/WebSocket MCP服务器

构建和使用:

# Build tools (requires readline-devel for mcp-shell)
make tools

# Inspect a server
./build/mcp-inspect --stdio ./build/simple-server

# Call a tool
./build/mcp-call --stdio ./build/calculator-server -- add '{"a": 5, "b": 3}'

# Interactive shell
./build/mcp-shell --stdio ./build/simple-server

# Bridge stdio to a remote HTTP server
./build/mcp-remote-client --http https://api.example.com/mcp

看 docs/cli-tools.md 以获取完整的文档。

测试

运行测试套件:

make test

测试包括:

  • 所有核心类型(枚举、内容、工具、资源、提示、任务)的单元测试
  • 消息编码/解码的协议测试
  • 使用模拟传输进行服务器和客户端测试
  • 与链接传输对的集成测试

API概述

核心类型

类型 描述
McpServer MCP服务器-公开工具、资源和提示
McpClient MCP客户端-连接到服务器
McpTool 使用JSON模式的工具定义
McpResource 资源定义(URI、名称、mime类型)
McpResourceTemplate 动态资源的URI模板
McpPrompt 带参数的提示模板
McpTask 长期运行(实验)

运输类型

类型 描述
McpTransport 抽象传输接口
McpStdioTransport 基于标准的运输

结果类型(框内)

类型 描述
McpToolResult 工具调用的结果
McpResourceContents 从资源读取内容
McpPromptResult 提示获取结果
McpPromptMessage 提示结果中的消息

语言绑定

生成GObject自检文件:

make gir

这将创建:

  • build/Mcp-1.0.gir -GIR XML文件
  • build/Mcp-1.0.typelib -编译的typelib

Python示例

import gi
gi.require_version('Mcp', '1.0')
from gi.repository import Mcp, GLib

# Create a server
server = Mcp.Server.new("python-server", "1.0.0")
# ... add tools, resources, prompts

许可证

AGPL-3.0或更高版本

版权所有(C)2025 Copyleft Games

文档

看 docs/ 详细文档:

参考文献