内容
# gobject-introspection-mcp
一个MCP服务器,负责向编码代理公开GObject Introspection元数据。
它会解析系统中安装的`.gir` XML文件,并使每个库、类、函数、信号、属性、枚举成员和结构体字段都可以通过一组标准的MCP工具进行查询。
所有数据都以C语言为导向:C符号名称、C类型字符串、头文件包含、所有权转移语义(`none` / `container` / `full`)、参数方向(`in` / `out` / `inout`)和GType信息。
自动维护一个SQLite缓存(`~/.cache/gi-mcp/cache.db`)。每个命名空间仅在磁盘上的`.gir`文件更改时重新解析。
## 需求
- Python 3.11+
- `lxml`(通常已在系统范围内安装)
- GIR文件 — 安装您要内省的库的`-dev` / `-devel`包,例如`libgtk-4-dev`、`libglib2.0-dev`
## 运行
### 使用uv(无需安装)
```sh
# 标准输入输出传输 — 由Claude Code和VS Code Copilot使用
uv run --project /path/to/gobject-introspection-mcp gi-mcp
# 流式HTTP传输(用于远程/浏览器客户端)
uv run --project /path/to/gobject-introspection-mcp gi-mcp --transport http --port 8000
```
### 通过pip安装
```sh
pip install --user .
gi-mcp # 标准输入输出(默认)
gi-mcp --transport http --port 8000
```
## 编辑器集成
### VS Code Copilot
在工作区中添加至`.vscode/mcp.json`(已包含一个现成的配置文件):
```json
{
"servers": {
"gi": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "${workspaceFolder}", "gi-mcp"]
}
}
}
```
### Claude Code
在项目中添加至`.claude/settings.json`(已包含一个现成的配置文件):
```json
{
"mcpServers": {
"gi": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/gobject-introspection-mcp", "gi-mcp"]
}
}
}
```
切换到Copilot Chat的**代理模式**,或启动Claude Code会话 — 下面列出的工具将自动可用。
## MCP工具
| 工具 | 描述 |
|------|-------------|
| `list_namespaces` | 所有已安装的GIR命名空间,包含版本、共享库、C前缀、头文件和依赖项 |
| `list_symbols(namespace, [version], [kind])` | 命名空间中的所有顶级符号;按`kind`过滤(`class`、`function`、`enumeration`等) |
| `search_symbols(query, [max_results])` | 跨所有命名空间的不区分大小写的名称子字符串搜索 |
| `search_by_c_identifier(c_identifier, [max_results])` | 按C名称查找符号(例如`gtk_widget_show`、`GTK_ALIGN_FILL`) |
| `get_symbol_details(namespace, name, [version])` | 任意顶级符号的完整详细信息 — C类型、方法、属性、信号、字段、父类、接口、头文件 |
| `list_members(namespace, symbol_name, [version])` | 类、接口、记录或联合体的成员:方法、构造函数、属性、信号和字段 |
| `get_inheritance_chain(namespace, symbol_name, [version])` | 从类到根的完整祖先链,包括每个祖先实现的接口 |
| `find_implementations(namespace, interface_name, [version])` | 跨所有命名空间的实现接口的所有类 |
| `get_signal(namespace, symbol_name, signal_name, [version])` | 信号的完整详细信息:参数类型和所有权转移、发出时机、标志、文档 |
| `get_property(namespace, symbol_name, property_name, [version])` | 属性类型、C类型、读写/构造标志、所有权转移、文档 |
| `get_field(namespace, symbol_name, field_name, [version])` | 结构体/记录/联合体字段:类型、C类型、指针标志、可读/可写、文档 |
| `get_enum_member(namespace, symbol_name, member_name, [version])` | 枚举或标志成员:整数值、C宏名称(例如`GTK_ALIGN_FILL`)、文档 |
| `get_callback(namespace, name, [version])` | 回调typedef:完整的参数列表,包含方向和转移、返回类型、GError标志 |
| `search_signals(query, [namespace], [max_results])` | 按名称子字符串查找信号 — 回答“哪个类发出`clicked`?” |
| `search_properties(query, [namespace], [max_results])` | 按名称子字符串查找属性,跨所有类型 |
| `get_constant(namespace, name, [version])` | 顶级常量:值、C宏名称、类型、头文件 |
| `list_deprecated(namespace, [version], [kind])` | 命名空间中的所有已弃用符号,可选按类型过滤 |
## 示例查询
```
list_namespaces
→ [{namespace: "GLib", version: "2.0", headers: ["glib.h"], ...}, ...]
get_symbol_details("GObject", "Object")
→ {name: "Object", c_type: "GObject", gtype_name: "GObject",
headers: ["glib-object.h"], methods: [...], signals: [...], ...}
get_signal("GObject", "Object", "notify")
→ {name: "notify", when: "first", callable: {parameters: [{name: "pspec", ...}]}}
search_signals("clicked")
→ [{signal_name: "clicked", defined_on: "Button", namespace: "Gtk", ...}, ...]
get_enum_member("Gtk", "Align", "fill")
→ {name: "fill", value: 0, c_identifier: "GTK_ALIGN_FILL", kind: "enumeration"}
search_by_c_identifier("g_object_ref")
→ [{c_identifier: "g_object_ref", name: "ref", kind: "method",
defined_on: "Object", namespace: "GObject"}]
get_inheritance_chain("Gtk", "Button")
→ {name: "Button", parent: "Gtk.Widget", implements: ["Gtk.Actionable", ...],
ancestors: [{name: "Widget", ...}, {name: "Object", namespace: "GObject"}]}
```
## 缓存
解析的数据存储在 `$XDG_CACHE_HOME/gi-mcp/cache.db`(默认`~/.cache/gi-mcp/cache.db`)。每个命名空间是一组SQLite数据库中的行 — 命名空间元数据的一行和每个符号的一行 — 按命名空间名称和`.gir`文件的修改时间索引。过时条目会自动替换;无需手动缓存管理。
可以通过 `XDG_CACHE_HOME` 覆盖缓存位置。通过 `GIR_PATH`(以冒号分隔)覆盖搜索哪些 `.gir` 目录。