内容
# Apple Numbers MCP 服务器
[MCP(Model Context Protocol)](https://modelcontextprotocol.io/) 服务器,可使 Claude 等 AI 助手能够读取、写入、搜索和修改 Apple Numbers(`.numbers`)电子表格文件。由 [numbers-parser](https://pypi.org/project/numbers-parser/) Python 库支持。
[](https://www.npmjs.com/package/apple-numbers-mcp)
[](https://github.com/sweetrb/apple-numbers-mcp/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
## 什么是本项目?
本服务器作为 AI 助手和 Apple Numbers 电子表格之间的桥梁。配置完成后,您可以要求 Claude(或任何支持 MCP 的 AI)执行以下操作:
- “这个电子表格里有什么?” - 检查工作表、表格、尺寸
- “查找客户是 Acme Corp 的所有行”
- “将 Q3 Results 表格导出为 CSV”
- “将单元格 B5 设置为 =SUM(B2:B4)”
- “将这三行追加到 Inventory 表格”
- “加粗并居中表头行”
- “导入此 CSV 到新电子表格”
AI 助手与本服务器通信,服务器使用 [numbers-parser](https://pypi.org/project/numbers-parser/) 读取和写入 `.numbers` 文件(大多数操作无需 Numbers.app)。所有数据都保留在您的机器上。
## 快速入门
### 使用 Claude Code(最简单)
如果您正在使用 [Claude Code](https://claude.com/product/claude-code)(在终端或 VS Code 中),只需要求 Claude 安装它:
```
安装 sweetrb/apple-numbers-mcp MCP 服务器,以便我可以处理我的 Numbers 电子表格
```
Claude 将自动处理安装和配置。安装后,您需要安装 `numbers-parser`(Python)- 请参见下面的[要求](#要求)。
### 使用插件市场
作为 Claude Code 插件安装,以实现自动配置和增强的 AI 行为:
```bash
/plugin marketplace add sweetrb/apple-numbers-mcp
/plugin install apple-numbers
```
此方法还安装了一个**技能**,教 Claude 如何有效地使用 Apple Numbers。
### 手动安装
**1. 安装服务器:**
```bash
npm install -g github:sweetrb/apple-numbers-mcp
```
**2. 安装 numbers-parser**(服务器依赖的 Python 库):
```bash
pip3 install numbers-parser
```
或者,如果您克隆了仓库,请运行 `npm run setup` 以创建项目本地的 Python venv,并预安装 `numbers-parser`。
**3. 添加到 Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"apple-numbers": {
"command": "npx",
"args": ["apple-numbers-mcp"]
}
}
}
```
**4. 重启 Claude Desktop** 并开始使用自然语言:
```
"What sheets are in ~/Documents/budget.numbers?"
```
#### 从克隆仓库运行(Claude Code 项目范围 `.mcp.json`)
该仓库自带一个 `.mcp.json`,因此当您在克隆仓库内运行 `claude` 时,服务器会自动注册为**项目范围**服务器 - 无需手动配置。在启动之前,请运行**两者**:
```bash
npm run build # 编译 TypeScript 到 build/
npm run setup # 创建 ./venv Python 侧所需的内容
```
`npm run setup` 是必需的,因为这是 Python 侧车服务器:它会调用 `./venv/bin/python3` 运行 `numbers-parser`。如果没有 venv,服务器会启动但所有工具调用都会失败。然后,从仓库目录启动 Claude Code 并在提示时批准服务器。
入口点写法如下:
```json
"args": ["${CLAUDE_PROJECT_DIR:-.}/build/index.js"]
```
`CLAUDE_PROJECT_DIR` 是 Claude Code 注入到项目/用户范围服务器环境中的变量,它解析为仓库根目录。**您必须从仓库内启动 `claude`** 才能生效 - 裸 `.` 备用方案仅作为最后的手段,并且*不*可靠,因为它相对于启动进程的工作目录,而不是仓库。
> **为什么不使用 `${CLAUDE_PLUGIN_ROOT}`?** `CLAUDE_PLUGIN_ROOT` **仅**在市场插件安装时设置,从不用于项目范围克隆,因此它无法驱动克隆工作流程。相反,市场安装无法使用 `CLAUDE_PROJECT_DIR`(在插件中,它指向*用户的*项目,而不是插件自己的目录)。Claude Code **不支持**嵌套默认值,如 `${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PROJECT_DIR:-.}}`,因此单个入口点字符串无法适用于两种上下文。因此,两个分发路径是解耦的:**插件**携带其自己的 MCP 配置在 `.claude-plugin/plugin.json` 中(使用 `${CLAUDE_PLUGIN_ROOT}`),而根 `.mcp.json` 专门用于**克隆**工作流程(使用 `${CLAUDE_PROJECT_DIR:-.}`)。由于 `plugin.json` 声明了自己的 `mcpServers`,因此插件也不会自动加载根 `.mcp.json`,因此不会发生双重注册。
> **关于作用域优先级的注意事项:** 项目范围(`.mcp.json`)优先于用户范围。如果您在用户范围(例如 `~/.claude.json` 中的绝对路径)中也注册了一个 `apple-numbers` 条目(例如绝对路径),则项目范围条目获胜,用户范围条目完全被忽略。请选择一个 - 对于此仓库的本地开发,项目范围 `.mcp.json` 是预期来源。要固定特定本地构建,请在**本地**范围注册它(`claude mcp add apple-numbers -s local -- node /abs/path/build/index.js`),它优先于项目范围。
## 要求
- **macOS 或 Linux** - `numbers-parser` 直接读取文件格式,因此大多数工具在任何地方都适用。**格式化和公式工具需要 Numbers.app 所在的 macOS。**
- **Node.js 20+** - MCP 服务器所需
- **Python 3.9+ with numbers-parser** - 通过 `pip3 install numbers-parser` 或通过 `npm run setup` 从源代码安装
## 功能
### 读取
| 功能 | 描述 |
|---------|-------------|
| **文件检查** | 列出工作表、表格、尺寸和表头行 |
| **表格读取** | 读取数据,带有可选的行范围和列过滤 |
| **单元格读取** | 通过 0-based 索引读取单个单元格,带有可选的公式/格式/合并元数据 |
| **搜索** | 在每个单元格中进行不区分大小写的文本搜索,可选地限定在一张工作表中 |
| **导出** | 将表格导出为 CSV、TSV 或 JSON |
### 写入
| 功能 | 描述 |
|---------|-------------|
| **创建电子表格** | 带有表头和可选初始行的新 `.numbers` 文件 |
| **设置单元格** | 将值写入单个单元格,可选类型强制转换 |
| **批量设置单元格** | 一次写入多个单元格(比多个 set-cell 调用更高效) |
| **添加/更新/删除行** | 按索引追加、替换或删除行 |
| **工作表和表格** | 将新工作表或表格添加到现有文件;重命名任一 |
### 公式(需要 Numbers.app)
| 功能 | 描述 |
|---------|-------------|
| **设置公式** | 将公式写入单元格,例如 `=SUM(B2:B10)` |
| **批量设置公式** | 一次写入多个公式 |
### 格式化(需要 Numbers.app)
| 功能 | 描述 |
|---------|-------------|
| **单元格样式** | 字体、大小、颜色、数字格式、对齐方式 |
| **批量单元格样式** | 同时设置多个单元格的样式 |
| **列宽/行高** | 以像素为单位设置尺寸 |
| **合并/取消合并** | 合并单元格范围或取消合并 |
### 导入/诊断
| 功能 | 描述 |
|---------|-------------|
| **导入 CSV/TSV/JSON** | 将表格文件转换为新的 `.numbers` 电子表格 |
| **健康检查** | 验证 Python 3 和 numbers-parser 是否已安装 |
---
## 工具参考
本节记录所有可用的工具。AI 代理应使用这些工具名称和参数。
### 读取
#### `health-check`
验证 Python 3 和 `numbers-parser` 是否已安装并可从服务器访问。
**参数:** 无
**返回:** `numbers-parser` 版本,或解释如何安装的错误。
---
#### `get-file-info`
获取 `.numbers` 文件的结构:工作表、表格、尺寸、表头行。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的绝对或 `~` 相对路径 |
**返回:** 默认工作表名称,以及每个工作表及其表格(名称、尺寸、表头行)。
---
#### `read-table`
从表格中读取数据。返回表头和行。如果未指定,默认为第一个工作表和第一个表格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 否 | 工作表名称(默认为第一个工作表) |
| `table` | 字符串 | 否 | 表格名称(默认为第一个表格) |
| `startRow` | 数字 | 否 | 0-based 开始行,包含(默认为 1,表头后) |
| `endRow` | 数字 | 否 | 0-based 结束行,包含(默认为最后一行) |
| `columns` | (字符串\|数字)[] | 否 | 列过滤器:表头名称或 0-based 索引 |
---
#### `get-cell`
通过行和列索引(0-based)读取单个单元格值。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 是 | 工作表名称 |
| `table` | 字符串 | 是 | 表格名称 |
| `row` | 数字 | 是 | 行索引(0-based) |
| `col` | 数字 | 是 | 列索引(0-based) |
| `verbose` | 布尔值 | 否 | 包括公式、格式化值和合并信息 |
---
#### `search`
`.numbers` 文件中每个单元格之间的不区分大小写的部分匹配。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `query` | 字符串 | 是 | 要搜索的文本 |
| `sheet` | 字符串 | 否 | 限制搜索到一个工作表 |
**返回:** 每个匹配项及其工作表、表格、行、列标题和值。
---
#### `export-table`
将表格导出为 CSV、TSV 或 JSON。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `format` | `"csv" \| "tsv" \| "json"` | 是 | 输出格式 |
| `outputPath` | 字符串 | 是 | 输出文件的路径 |
| `sheet` | 字符串 | 否 | 工作表名称(默认为第一个工作表) |
| `table` | 字符串 | 否 | 表格名称(默认为第一个表格) |
---
### 写入
#### `create-spreadsheet`
创建带有单个工作表和表格的新 `.numbers` 文件。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | 新文件的路径 |
| `headers` | 字符串[] | 是 | 列标题名称 |
| `rows` | (字符串\|数字\|布尔值\|空)[][] | 否 | 初始数据行 |
| `sheetName` | 字符串 | 否 | 默认:`"Sheet 1"` |
| `tableName` | 字符串 | 否 | 默认:`"Table 1"` |
---
#### `set-cell`
将值写入单个单元格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `row` | 数字 | 是 | 行索引(0-based) |
| `col` | 数字 | 是 | 列索引(0-based) |
| `value` | 字符串\|数字\|布尔值\|空 | 是 | 要写入的值 |
| `sheet` | 字符串 | 否 | 工作表名称(默认为第一个工作表) |
| `table` | 字符串 | 否 | 表格名称(默认为第一个表格) |
| `type` | `"string" \| "number" \| "boolean" \| "date"` | 否 | 强制值类型(默认为自动检测) |
---
#### `set-cells-batch`
一次写入多个单元格。比多个 `set-cell` 调用更高效。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `updates` | 数组 | 是 | `{row, col, value, type?}` 对象数组 |
| `sheet` | 字符串 | 否 | 工作表名称 |
| `table` | 字符串 | 否 | 表格名称 |
---
#### `add-rows`
在最后一行后追加数据行。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `rows` | 数组[] | 是 | 要追加的行(每行一个数组) |
| `sheet` | 字符串 | 否 | 工作表名称 |
| `table` | 字符串 | 否 | 表格名称 |
---
#### `update-rows`
按索引写入完整行。每个更新都是完整的行替换。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `updates` | 数组 | 是 | `{row, values}` 对象数组 |
| `sheet` | 字符串 | 否 | 工作表名称 |
| `table` | 字符串 | 否 | 表格名称 |
#### `delete-rows`
删除由 0-based 索引指定的一行范围。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `startRow` | 数字 | 是 | 要删除的第一行(0-based,包含) |
| `endRow` | 数字 | 是 | 要删除的最后一行(0-based,包含) |
| `sheet` | 字符串 | 否 | 工作表名称 |
| `table` | 字符串 | 否 | 表格名称 |
---
### 工作表和表格
#### `add-sheet`
添加新的工作表,可选地为默认表格添加表头。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheetName` | 字符串 | 是 | 新工作表的名称 |
| `tableName` | 字符串 | 否 | 默认表格的名称 |
| `headers` | 字符串[] | 否 | 默认表格的表头 |
---
#### `add-table`
向现有工作表添加新表格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 否 | 工作表名称(默认为第一个工作表) |
| `tableName` | 字符串 | 否 | 新表格的名称 |
| `headers` | 字符串[] | 否 | 列标题 |
---
#### `rename-sheet` / `rename-table`
重命名工作表或表格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| (rename-sheet)`oldName` / `newName` | 字符串 | 是 | 当前和新的工作表名称 |
| (rename-table)`sheet` | 字符串 | 否 | 包含表格的工作表 |
| (rename-table)`oldName` / `newName` | 字符串 | 是 | 当前和新的表格名称 |
---
### 公式(需要 Numbers.app)
#### `set-formula`
将公式写入单元格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 是 | 工作表名称 |
| `table` | 字符串 | 是 | 表格名称 |
| `row` | 数字 | 是 | 0-based 行 |
| `col` | 数字 | 是 | 0-based 列 |
| `formula` | 字符串 | 是 | 公式文本(包括前导 `=` |
---
#### `set-formulas-batch`
写入多个公式。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | 表格名称 |
| `entries` | 数组 | 是 | `{row, col, formula}` 对象数组 |
---
### 格式化(需要 Numbers.app)
#### `set-cell-style`
将样式应用于单元格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 是 | 工作表名称 |
| `table` | 字符串 | 是 | 表格名称 |
| `row` | 数字 | 是 | 0-based 行 |
| `col` | 数字 | 是 | 0-based 列 |
| `style` | 对象 | 是 | `{font?, fontSize?, color?, fillColor?, bold?, italic?, alignment?, numberFormat?, ...}` |
---
#### `set-cells-style-batch`
将样式应用于多个单元格。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 是 | 工作表名称 |
| `table` | 字符串 | 是 | 表格名称 |
| `entries` | 数组 | 是 | `{row, col, style}` 对象数组 |
---
#### `set-column-width` / `set-row-height`
以像素为单位设置列宽或行高。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 是 | 工作表名称 |
| `table` | 字符串 | 是 | 表格名称 |
| `col` (列) / `row` (行) | 数字 | 是 | 0-based 索引 |
| `width` (列) / `height` (行) | 数字 | 是 | 像素大小 |
---
#### `merge-cells` / `unmerge-cells`
合并单元格范围或取消合并。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `path` | 字符串 | 是 | `.numbers` 文件的路径 |
| `sheet` | 字符串 | 是 | 工作表名称 |
| `table` | 字符串 | 是 | 表格名称 |
| `startRow`, `startCol`, `endRow`, `endCol` | 数字 | 是 | 0-based 坐标(包含) |
---
### 导入
#### `import-csv`
将 CSV、TSV 或 JSON 文件导入新的 `.numbers` 电子表格。自动检测文件扩展名或显式传递 `format`。
| 参数 | 类型 | 必需 | 描述 |
|-----------|------|----------|-------------|
| `inputPath` | 字符串 | 是 | CSV/TSV/JSON 输入文件的路径 |
| `outputPath` | 字符串 | 是 | 输出 `.numbers` 文件的路径 |
| `format` | `"auto" \| "csv" \| "tsv" \| "json"` | 否 | 默认:自动检测文件扩展名 |
| `sheetName` | 字符串 | 否 | 默认:`"Sheet 1"` |
| `tableName` | 字符串 | 否 | 默认:`"Table 1"` |
---
## 使用模式
本节介绍一些使用工具的模式。
<!--
## 工具限制
本节介绍一些工具限制。
-->
### 基本工作流程
```
用户: "What's in ~/Documents/budget.numbers?"
AI: [调用 get-file-info]
"它有 3 张表: Q1, Q2, Q3. Q1 包含一个 'Budget' 表格,有 12 行 × 5 列..."
用户: "显示 Q3"
AI: [调用 read-table,参数 sheet='Q3']
"Q3 / Budget (12 行 × 5 列): ..."
用户: "查找所有关于 Acme Corp 的记录"
AI: [调用 search,参数 query='Acme Corp']
"在 Q1/Budget 和 Q3/Vendors 中找到 4 个匹配项..."
```
### 迭代编辑
```
用户: "将 B5 设置为 =SUM(B2:B4) 并加粗表头行"
AI: [调用 set-formula] [调用 set-cells-style-batch,参数 bold=true,作用于第 0 行]
"已完成 — B5 已设置为 =SUM(B2:B4),表头行已加粗。"
```
### 导入 CSV
```
用户: "将 ~/Downloads/customers.csv 导入到新的电子表格中"
AI: [调用 import-csv,参数 inputPath 和 outputPath]
"已导入 240 行(6 列)到 ~/Documents/customers.numbers"
```
---
## 安装选项
### npm(推荐)
```bash
npm install -g github:sweetrb/apple-numbers-mcp
pip3 install numbers-parser
```
### 从源码安装(使用项目本地虚拟环境)
```bash
git clone https://github.com/sweetrb/apple-numbers-mcp.git
cd apple-numbers-mcp
npm install
npm run setup # 创建 ./venv 并安装 numbers-parser
npm run build
```
如果从源码安装,请使用此配置:
```json
{
"mcpServers": {
"apple-numbers": {
"command": "node",
"args": ["/绝对路径/to/apple-numbers-mcp/build/index.js"]
}
}
}
```
服务器优先使用项目本地虚拟环境 `./venv/bin/python3`(如果存在),否则回落到系统 `python3`。全局 npm 安装只要系统 Python 上有 `numbers-parser` 即可正常工作。
---
## 架构
该软件包是一个 **TypeScript MCP 服务器,带有 Python 侧车**:
- MCP 服务器(Node)通过 stdio 通信,使用模型上下文协议。
- 捆绑的 Python 脚本(`src/utils/numbers_reader.py`)使用 `numbers-parser` 读取和写入 `.numbers` 文件,并返回 JSON。
- 对于格式化、公式和单元格尺寸更改,使用 AppleScript 层(`src/utils/applescript.ts`)直接驱动 Numbers.app — `numbers-parser` 不写入样式。
- TypeScript 通过 `child_process.execFileSync` 启动 Python。
这是 [apple-photos-mcp](https://github.com/sweetrb/apple-photos-mcp) 在 `osxphotos` 库中使用的相同 Python 侧车模式。
---
## 安全性和隐私
- **仅限本地** — 所有操作都在本地机器上进行。不会将数据发送到外部服务器。
- **无凭证存储** — 服务器不会存储任何密码或身份验证令牌。
- **文件系统访问** — 工具需要明确的路径;服务器只读取或写入您命名的文件。
- **Numbers.app 自动化** — 格式化和公式工具通过 AppleScript 驱动 Numbers.app。macOS 将在首次使用时提示自动权限。
---
## 已知限制
| 限制 | 原因 |
|------------|--------|
| 格式化 / 公式 / 尺寸需要 Numbers.app | `numbers-parser` 不写入样式或公式;AppleScript 层填补了这一空白(仅限 macOS) |
| 无条件格式化 | `numbers-parser` 未公开 |
| 无图表或图像 | `numbers-parser` 未公开 |
| 不支持删除表格 | `numbers-parser` 未公开 |
| 仅计算值写入 | `set-cell` / `add-rows` 等写入计算值;使用 `set-formula` 写入公式 |
| 日期筛选格式 | ISO 8601(`YYYY-MM-DD` 或完整 ISO 日期时间) |
这些是为未来版本跟踪的。底层 `numbers-parser` 库通过其 `Style` API 部分支持样式,这为其中一些提供了一条前进的道路。
---
## 故障排除
### "numbers-parser 未安装。运行:npm run setup"
- 运行 `pip3 install numbers-parser`(全局)或 `npm run setup`(项目本地虚拟环境)。
- 如果您使用了虚拟环境,请确保它是项目目录中的 `./venv/`。
### `apple-numbers` 服务器无法连接,运行时报错
- 在存储库目录内启动 `claude`,以便 `CLAUDE_PROJECT_DIR` 解析为存储库根目录(裸 `.` fallback 不可靠)。
- 运行 **both** `npm run build` 和 `npm run setup` — `build` 编译入口点,`setup` 创建 Python 侧车所需的 `./venv`。
- 运行 `claude mcp list` 检查冲突范围;项目范围 `.mcp.json` 优先于用户范围 `apple-numbers` 条目,本地范围条目优先于两者。
- 如果服务器被列为待处理,请在 Claude Code 提示时批准项目范围服务器。
### "文件未找到"
- 检查路径;如果您的 shell 没有展开 `~`,请手动展开。
- 确保文件扩展名为 `.numbers`。
### 格式化 / 公式工具因 "Numbers.app 未运行" 而失败
- 至少打开 Numbers.app 一次。macOS 将提示自动权限 — 请接受。
- 在 **系统设置 → 隐私和安全 → 自动化** 中进行验证。
### 输出看起来不正确(日期为 ISO 格式,浮点数带有小数)
- 服务器将日期归一化为 ISO 8601,并将接近整数的浮点数四舍五入。如果您想要原始值,请提交问题。
---
## 开发
```bash
npm install # 安装依赖
npm run setup # 创建 ./venv 并安装 numbers-parser
npm run build # 编译 TypeScript
npm test # 单元测试(模拟)
npm run test:integration # 集成测试,针对真实 .numbers 固定件
npm run test:all # 两者
npm run typecheck # 类型检查,不生成输出
npm run lint # 检查代码风格
npm run format # 格式化代码
```
### 集成测试
集成测试在真实的 `.numbers` 固定件文件上测试整个管道。首先生成固定件,然后运行:
```bash
npm run setup
./venv/bin/python3 test/fixtures/generate-fixtures.py
npm run test:all
```
单元测试在任何地方运行;集成测试在固定件或 `numbers-parser` 不可用时自动跳过。
---
## 作者
**Rob Sweet** - 总裁, [Superior Technologies Research](https://www.superiortech.io)
一家软件咨询、承包和开发公司。
- 邮箱: rob@superiortech.io
- GitHub: [@sweetrb](https://github.com/sweetrb)
## 许可证
MIT 许可证 - 参见 [LICENSE](LICENSE) 了解详情。该项目与 Apple Inc. 或 [numbers-parser](https://pypi.org/project/numbers-parser/) 项目无关。
## 贡献
欢迎贡献!请在 [github.com/sweetrb/apple-numbers-mcp](https://github.com/sweetrb/apple-numbers-mcp) 上提出问题或提交 PR。
## 相关项目
- [apple-mail-mcp](https://github.com/sweetrb/apple-mail-mcp) — Apple Mail 的 MCP 服务器
- [apple-notes-mcp](https://github.com/sweetrb/apple-notes-mcp) — Apple Notes 的 MCP 服务器
- [apple-photos-mcp](https://github.com/sweetrb/apple-photos-mcp) — Apple Photos 的 MCP 服务器
- [numbers-parser](https://pypi.org/project/numbers-parser/) — 为该服务器提供支持的 Python 库
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器