使用说明
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/ 详细文档: