内容
# 代币史密斯
**让编码代理了解设计系统。** 一个MCP服务器,为任何代理(Claude Code,Claude Desktop,Cursor)提供一流的访问设计系统代币的功能 - 这样它编写的UI可以*在系统内*,而不是一堆猜测的十六进制值。
今天编写UI的代理不知道您的设计系统存在。它使用`#2563eb`,因为这是它记住的蓝色。代币史密斯是桥梁:通过MCP公开设计系统(W3C [设计代币 / DTCG](https://tr.designtokens.org/) `tokens.json`),以便代理*查询*系统 - 解析`color.action.primary`为实际值,遵循别名链 - 而不是发明一个。
> **范围,诚实地说。** 代币史密斯通过MCP使设计系统*可用*给代理;它尚未*强制*代理调用工具或遵循其输出。今天,它消除了猜测的借口 - 它还没有防止猜测。关闭该漏洞(验证生成的UI是否实际使用了代币)是[路线图](#状态--路线图)。
---
## 30秒演示

*左侧:在没有设计系统的情况下,代理会选择的值(手动编写以显示常见的Tailwind默认猜测)。右侧:使用代币史密斯生成的相同组件,每个值通过代币史密斯解析。差异很微妙,这是为了演示目的而故意设计的。打开 [`demo/preview.html`](./demo/preview.html) 以查看实时演示。*
`demo/` 目录包含一个组件,`SettingsCard`,有两种实现方式:
- [`without.tsx`](./demo/without.tsx) - 手动编写的示例,展示了代理(或开发人员凭记忆)选择的值,当设计系统不在上下文中时:通用Tailwind默认值。
- [`with.tsx`](./demo/with.tsx) - 相同的组件,每个字面值通过代币史密斯工具实时解析,每个值都引用其代币路径。这些值是实际工具输出。
猜测 vs. 解析,每行代表卡片使用的不同代币:
| 角色 | 代币路径 | 猜测值 | 代币正确值 |
|---|---|---|---|
| 主要操作背景 | `color.action.primary` | `#2563eb` | `#2557c7` |
| 卡片表面 | `color.surface.raised` | `#ffffff` | `#f7f8fa` |
| 卡片半径 | `radius.lg` | `12px` | `16px` |
| 柔和文本 | `color.text.muted` | `#6b7280` | `#5b6472` |
| 字体家族 | `type.family.sans` | `-apple-system` | `Inter` |
| … | | **所有13个代币都不同** | |
没有一个Tailwind默认值匹配Meridian代币。 `#2563eb` vs `#2557c7` 呈现为“蓝色”,通过视觉审查并发布 - 这正是代币系统旨在防止的偏差,而这正是LLM在无法读取代币时重新引入的偏差。完整的分解、诚实的注意事项和别名链在 [`demo/README.md`](./demo/README.md) 中。
---
## 快速入门
需要 Node 20+。
```bash
git clone https://github.com/jtmchorse/tokensmith
cd tokensmith
npm install
npm run build
```
将其指向您自己的DTCG代币文件,或使用捆绑的`Meridian`示例:
```bash
# Claude Code — 项目范围,捆绑示例代币
claude mcp add tokensmith -s project -- node "$(pwd)/dist/index.js"
# …或使用您自己的 tokens.json
claude mcp add tokensmith -s project -- node "$(pwd)/dist/index.js" /abs/path/tokens.json
```
克劳德桌面版(`claude_desktop_config.json`,然后完全退出并重新打开):
```json
{ "mcpServers": { "tokensmith": { "command": "node", "args": ["/abs/path/dist/index.js"] } } }
```
代币文件从 `argv[2]`、然后 `TOKENS_PATH`、最后是捆绑的 [`examples/tokens.json`](./examples/tokens.json) 解析。
---
## 工具
| 工具 | 功能 |
|---|---|
| **`list_tokens(group?)`** | 解析后的代币列表 `{path, type, value, aliasOf?, description?}`,可选地按组前缀(如 `"color.action"`)过滤。 |
| **`resolve_token(name)`** | 解析一个代币到 `{path, value, type, chain, isAlias, description}`。`chain` 是关键 - 它显示了整个别名链。 |
| **`ping`** | 健康检查 → `pong`。 |
`resolve_token` 跟随别名链到其终端值,并返回其路径:
```
resolve_token color.action.primary
→ { value: "#2557c7",
chain: ["color.action.primary", "color.brand.primary", "color.base.blue-600"] }
```
这种间接性是有价值的:设计师重新定位 `brand.primary` 一次,每个询问 `action.primary` 的消费者都会随之移动。猜测的十六进制值则会冻结在模型记住的任何值上。
---
## 工作原理
- **DTCG 加载器** (`src/dtcg/`) - 遍历 W3C `tokens.json`,继承 `$type` 到组,展平为 `Map<dot.path, token>`,并检测别名。失败时会大声报错,报错信息包含违规路径。
- **别名解析器** (`src/dtcg/resolver.ts`) - 通过任意深度的别名链解析整个 `$value` 别名,带有访问过的集合 **循环保护**(自引用、2 节点和中链循环均被捕获)。未知路径会收到最近的错误 *"你是否想到了"* 提示。
- **MCP 服务器** (`src/index.ts`) - 在标准输入/输出上注册三个工具;解析器和解析失败作为 MCP 工具错误出现,带有完整的消息(和提示)。
- **经过测试的核心** - `npm test`(vitest),在加载器 + 解析器上运行 34 个测试用例,包括每个错误路径。
`Meridian` 示例是一个虚构的、干净的设计系统:62 个代币,21 个别名,链最多 3 级,构建用于演示解析。
---
## 状态和路线图
**`v0.0`** - 工作中的基础,端到端工作:
- ✅ **M0** 标准输入/输出 MCP 管道 · ✅ **M1** DTCG 加载器 · ✅ **M2** 别名解析器 + 循环保护
- ✅ **M3** `list_tokens` + `resolve_token` · ✅ **M4** 在克劳德客户端和演示中实时运行
**下一步(`v0.1`+):** 设计系统感知的*生成*(而不仅仅是查找),现有代码的代币**审计**,浅色/深色模式,复合值引用和往返 Figma。
---
## 贡献者注意事项
在标准输入/输出 MCP 服务器上,**标准输出是 JSON-RPC 通道**。单个不小心输出到标准输出的 `console.log` 会损坏流,客户端会默默地无法连接。所有日志记录都会发送到标准错误流。如果它“无故”无法连接,那是嫌疑人 #1。
## 许可证
MIT