内容
<p align="center">
<img src="assets/twine-mcp-logo.png" alt="Twine MCP logo: a stylized blue-to-green gradient branching tree ending in a sparkle icon" width="160" />
</p>
<h1 align="center">Twine MCP</h1>
<p align="center">
<a href="https://www.npmjs.com/package/@unveil-gg/twine-mcp"><img src="https://img.shields.io/npm/v/@unveil-gg/twine-mcp.svg?style=flat-square" alt="npm version" hspace="3"/></a><a href="https://github.com/Unveil-gg/twine-mcp/actions/workflows/ci.yml"><img src="https://github.com/Unveil-gg/twine-mcp/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI" hspace="3"/></a><a href="https://www.npmjs.com/package/@unveil-gg/twine-mcp"><img src="https://img.shields.io/npm/l/@unveil-gg/twine-mcp.svg?style=flat-square" alt="license" hspace="3"/></a><a href="https://www.npmjs.com/package/@unveil-gg/twine-mcp"><img src="https://img.shields.io/npm/dm/@unveil-gg/twine-mcp.svg?style=flat-square" alt="npm downloads" hspace="3"/></a><a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-compatible-8B5CF6?style=flat-square" alt="MCP compatible" hspace="3"/></a>
</p>
Twine 交互式故事创作的MCP服务器。连接您的Twine故事库,并提供用于段落编辑、链接图分析、情节一致性检查和叙事智能的AI工具。
与 **Cursor**、**Claude Code**、**Claude Desktop** 和 **Codex CLI** 兼容。
---
## 安装
```bash
npm install -g @unveil-gg/twine-mcp
twine-mcp setup
```
安装向导会自动检测您的Twine库,询问您使用的编辑器,并写入(或复制)MCP配置文件 - 无需手动编辑JSON。
完成后重启您的编辑器。要求您的AI运行 `ping` 以确认连接。
<details>
<summary>手动配置(如果您更喜欢这样做)</summary>
将以下内容添加到您的编辑器的MCP配置文件(`~/.cursor/mcp.json`、`~/.claude.json`等):
```json
{
"mcpServers": {
"twine": {
"command": "twine-mcp",
"env": {
"TWINE_LIBRARY": "/Users/yourname/Documents/Twine/Stories"
}
}
}
}
```
库路径将从Twine的设置中自动检测,或默认为 `~/Documents/Twine/Stories`。
</details>
---
## 功能
| 类别 | 示例 |
|----------|----------|
| **故事管理** | 列出、创建、删除、导出Twee、编译HTML |
| **段落CRUD** | 创建、编辑、重命名段落(重写 `[[链接]]`) |
| **图分析** | 损坏的链接、死端、孤立节点、循环、路径查找 |
| **情节检查** | 完整分析报告、变量使用、标签一致性 |
| **叙事智能** | 故事摘要、分支图、结尾审计 - 对AI来说节省标记 |
| **格式感知** | Harlowe、SugarCube、Chapbook语法指南 |
### 推荐的AI工作流程
```
ping → summarize_story → get_story_context → get_story_branches
→ get_narrative_flow → get_passage_context → get_all_endings
```
从廉价的开始(`summarize_story` ≈ 200 tokens),仅在需要时深入。
---
## 工具参考
<details>
<summary><strong>故事管理</strong></summary>
| 工具 | 描述 |
|------|-------------|
| `list_stories` | 列出所有故事的元数据。支持 `fields` 过滤。 |
| `get_story` | 完整的故事数据。可切换 `include_passages` 和 `compact`。 |
| `create_story` | 创建新的故事文件,包含起始段落。 |
| `delete_story` | 永久删除故事文件。 |
| `export_twee` | 导出为Twee 3源文本。 |
| `compile_story` | 在给定输出路径处生成校对HTML文件。 |
</details>
<details>
<summary><strong>段落CRUD</strong></summary>
| 工具 | 描述 |
|------|-------------|
| `list_passages` | 所有段落的名称、标签、字数。 |
| `get_passage` | 完整的段落内容 + 标签 + 外出链接。 |
| `create_passage` | 添加新的段落,可选内容、标签、位置。 |
| `update_passage` | 编辑文本、标签或编辑器位置。 |
| `delete_passage` | 删除段落。 |
| `rename_passage` | 重命名 + 重写所有指向旧名称的 `[[链接]]`。 |
| `set_start_passage` | 更改故事的起始段落。 |
</details>
<details>
<summary><strong>图与导航</strong></summary>
| 工具 | 描述 |
|------|-------------|
| `get_link_graph` | 完整的邻接列表或紧凑的计数。 |
| `find_broken_links` | 指向不存在的段落的链接。 |
| `find_dead_ends` | 没有外出链接的段落(未标记 `ending`)。 |
| `find_orphans` | 没有其他段落链接到的段落。 |
| `find_cycles` | 循环的链接路径。 |
| `get_passage_path` | 两个段落之间的最短路径(BFS)。 |
| `get_reachable_passages` | 从起点可达的所有段落 + 不可达列表。 |
</details>
<details>
<summary><strong>故事分析</strong></summary>
| 工具 | 描述 |
|------|-------------|
| `analyze_story` | 综合报告:损坏的链接、死端、孤立节点、循环、统计数据。 |
| `get_story_stats` | 字数、阅读时间、标签使用、分支统计。 |
| `search_passages` | 跨所有段落的全文 + 标签搜索。 |
| `find_variable_usage` | 格式感知的变量设置/读取跟踪。 |
| `check_tag_consistency` | 罕见标签、高标签段落、无标签段落计数。 |
</details>
<details>
<summary><strong>叙事智能</strong></summary>
| 工具 | 描述 |
|------|-------------|
| `summarize_story` | 最便宜的定位调用。~500 tokens 最大。 |
| `get_story_context` | 可配置的包。支持 `fields` + `compact`。 |
| `get_narrative_flow` | 按DFS顺序排列的散文。支持 `max_depth` + `max_passages`。 |
| `get_all_endings` | 所有终端段落 + 上游路径。 |
| `get_passage_context` | 上游路径 + 内容 + 单个段落的外出链接。 |
| `get_story_branches` | 具有子树可达性计数的分支点。 |
</details>
<details>
<summary><strong>格式感知与实用工具</strong></summary>
| 工具 | 描述 |
|------|-------------|
| `list_story_formats` | 内置 + 用户安装的格式。 |
| `get_format_info` | 描述、文档网址和使用情况。 |
| `get_format_syntax_guide` | Harlowe、SugarCube、Chapbook、Snowman的语法参考。 |
| `ping` | 健康检查 + 库路径 + 故事计数。 |
| `get_config` | 服务器配置。 |
| `batch_update` | 单次保存中的原子多段编辑。 |
**MCP 资源:** `twine://stories`、`twine://story/{name}`、`twine://story/{name}/graph`、`twine://story/{name}/summary`
</details>
---
## 标记效率
每个工具都支持惯例以最小化标记成本:
- **`fields`** — 选择要返回的属性
- **`compact: true`** — 仅名称 + 80字符预览
- **`max_depth` / `max_passages`** — 限定遍历输出
- 默认情况下,段落文本不会包含在列表/图表工具中
---
## 工作原理
通过 [chokidar](https://github.com/paulmillr/chokidar) 监视 `~/Documents/Twine/Stories/*.html`,使用 [extwee](https://github.com/videlais/extwee) 解析,并将写入内容缝合回原始HTML。TwineJS在聚焦时重新加载。
Twine 没有插件API - 此服务器完全通过文件系统操作。
---
## 贡献与开发
- **[CONTRIBUTORS.md](CONTRIBUTORS.md)** — 本地设置、如何帮助、AI使用政策
- **[DEVELOPMENT.md](DEVELOPMENT.md)** — 发布工作流、npm身份验证、CI
---
## 限制
- 仅支持桌面版/Electron Twine(不支持网页/PWA)
- 段落文本是不透明的源代码(不执行宏)
- 格式转换仅供参考,不自动执行