内容
# WPF-MCP
**Infragistics NetAdvantage for WPF** 的 MCP 服务器 — 组件注册,XAML 命名空间查找,完整的 API 参考,包含属性类型和枚举值,以及 7,000 多个类型中的关键词搜索。
## 工具
| 工具 | 描述 |
|---|---|
| `list_wpf_components` | 列出所有 192 个 Xam* 控件,包含规范的 XAML 命名空间 URI、NuGet 包和描述。在编写 XAML 之前,请始终调用此工具。 |
| `get_project_scaffold` | 为新 WPF 项目生成可运行的 `dotnet new` + `dotnet add package` + `dotnet restore` 命令和 xmlns 声明。传递通过 `list_wpf_components` 解析的组件名称。 |
| `search_wpf_api` | 通过关键词搜索 7,000 多个类型 — 匹配类型名称、摘要和成员名称。在不知道确切类型名称时使用。 |
| `get_wpf_api_reference` | 任意类型的完整 API 参考:属性及其类型、枚举值、事件、方法和按基类分组的继承成员。 |
## 需求
- **Node.js** ≥ 18
- **.NET 8 SDK** — 首次构建所需
## 设置
```bash
git clone <仓库地址>
cd wpf-mcp
npm install
npm run build:all
```
`build:all` 下载 Infragistics NuGet 包,通过反射提取类型元数据,与 XML 文档合并,并编译服务器。首次运行时需要 2-5 分钟(NuGet 恢复),之后速度较快。
## Claude Desktop 配置
添加到 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"infragistics-wpf": {
"command": "node",
"args": ["C:/path/to/wpf-mcp/dist/index.js"]
}
}
}
```
## 数据管道
```
NuGet 包(26.2.x)
├── *.dll → C# TypeExtractor(反射) → nuget/type-info.json
│ (基类型,属性类型,枚举值)
└── *.xml ─────────────────────────────────┐
↓
build-api.ts
↓
src/data/api/*.json (7,082 个类型文件)
src/data/namespaces.json (192 个 Xam* 控件)
src/data/search-index.json (搜索索引)
```
## npm 脚本
| 脚本 | 执行操作 |
|---|---|
| `npm run build:all` | 完整管道:NuGet 恢复 → 类型提取 → API 构建 → TypeScript 编译 |
| `npm run generate` | 仅 API 数据(无 TypeScript 编译) |
| `npm run generate:types` | 仅 C# 反射提取器 → `nuget/type-info.json` |
| `npm run build` | 仅 TypeScript 编译(需要 `src/data/` 存在) |
| `npm run inspector` | 启动 MCP Inspector 进行交互式测试 |
## 开发笔记
- SDK:`@modelcontextprotocol/sdk` v1(v2 版本将于 2026 年 7 月 28 日左右发布,包含破坏性包重命名)
- Zod v3 模式 — 迁移到 SDK v2 时升级到 v4
- 所有工具均为只读(`readOnlyHint: true`,`openWorldHint: false`)
---
<details>
<summary><strong>架构</strong></summary>
### 为什么采用这种方法
Infragistics WPF NuGet 包为每个程序集提供两个文件:
- `InfragisticsWPF.*.dll` — 实际二进制文件
- `InfragisticsWPF.*.xml` — 编译器生成的 XML 文档注释(`<summary>`、`<param>` 等)
XML 文件提供描述,但不包含其他信息 — 无属性类型,无枚举值,无继承关系。获取这些信息的方法是使用反射。Infragistics 自己的文档工具(Innovasys Document! X)也是在生成实时帮助网站之前内部使用反射。
### 构建管道
```
NuGet 包
├─ *.dll ──► scripts/type-extractor/Program.cs (C#,反射)
│ 加载所有 Infragistics DLL 到一个 AssemblyLoadContext
│ 遍历每个公共类型:基类型,属性及其类型,
│ 枚举成员,可空性
│ 输出:nuget/type-info.json (36k 条目,紧凑 JSON)
│
└─ *.xml ──► scripts/build-api.ts (TypeScript)
使用基于分片的块处理解析每个程序集的 XML 文档
(避免对多 MB 文件的灾难性正则表达式回溯)
为每个文件构建一个 Map<typeFQN, members> (O(n),而非 O(n²))
与 type-info.json 合并以附加类型名称/枚举值
使用循环保护遍历 __baseType 链以获取继承的属性
异步并行写入:src/data/api/{TypeName}.json (7k 文件)
还写入:src/data/namespaces.json,src/data/search-index.json
```
### 运行时数据布局
| 文件 | 大小 | 加载时机 | 用途 |
|---|---|---|---|
| `src/data/namespaces.json` | ~50KB | 启动时 | 192 个 Xam* 控件注册表 |
| `src/data/search-index.json` | ~5MB | 启动时 | 紧凑索引:名称 + 摘要 + 成员名称 |
| `src/data/api/{Type}.json` | ~5–15KB 每个 | 按需 | 每个类型的完整成员详细信息 |
搜索索引加载一次并保存在内存中 — 搜索永远不会触及个别类型文件。`get_wpf_api_reference` 每次调用仅加载一个文件。
### 关键设计决策
- **查询时无反射** — 所有反射操作均在构建时发生。MCP 响应是纯 JSON 文件读取。
- **`type-info.json` 被 gitignore** — 由 `build:all` 重新生成。用户需要 .NET 8 SDK 进行首次构建。
- **`src/data/` 被 gitignore** — 由 `build-api.ts` 从 `type-info.json` + NuGet XML 文件重新生成。
- **继承增强** — `enrichWithInheritance()` 遍历 `__baseType` 链,并将父属性复制到具有 `declaredOn` 标签的子条目。这就是为什么 `XamDataGrid` 显示 74 个属性,尽管它直接声明的属性很少。
- **`internal` 过滤器** — 具有 `summary === "internal"` 的成员被剥离。这些是公共 DLL 成员,开发人员为其编写了占位文档,但不属于公共 API 表面。