API 参考
在任何地方——iOS/Android 应用、CI 流水线——都可以通过 REST 获取 variable Jar 的变量。 只读,使用与 MCP 服务器相同的令牌。
测试版:API 与 MCP 在正式发布前可能会变化;格式现已带有版本号(见“平台代码输出”),不兼容的变更会提前公告,并保留 12 个月的并行期。
签发令牌
- variablejar.com/app → 项目卡片的 ⋯ 菜单 → 属性 → API 令牌(MCP) 部分
- 输入令牌名称并按 签发——令牌(
vjt_…)只在签发后立即显示一次。请妥善保存。 - 一个令牌只能访问这一个项目。如果泄露,请立即在同一界面撤销。
令牌会过期(默认 180 天,最长 365 天),过期前 14 天会收到铃铛通知。只有工作区所有者可以签发包含文本值(STRING)的令牌——会导出所有语言的值,包括未发布的翻译。也可以把令牌限定在所选的集合。
令牌的安全取决于保存它的地方:持有令牌的人可获取其范围内的所有值。通过 API 或 MCP 导出的数据会离开本服务,由你自行负责处理。
端点
GET https://variablejar.com/api/v1/variables
Authorization: Bearer vjt_...
curl -H "Authorization: Bearer vjt_..." \
"https://variablejar.com/api/v1/variables"
文本值(STRING)只有在令牌签发时包含了文本值、并且请求带上 ?include=strings 时才会返回。
响应
值为最终值,别名({Collection/key})已解析。只有无法解析的单元格会连同原因(broken · cycle · inline)出现在 unresolved 中,并保留原值。
{
"apiVersion": "v1",
"project": { "name": "My Variables" },
"collections": [
{ "name": "Color", "modes": ["light", "dark"] },
{ "name": "Text", "modes": ["en", "ko"] }
],
"tokens": [
{
"key": "color/primary",
"collection": "Color",
"type": "COLOR",
"valuesByMode": { "light": "#3B82F6", "dark": "#60A5FA" }
},
{ "key": "hello", "collection": "Text", "type": "STRING", "valuesByMode": {}, "omitted": "strings" }
]
}
不带 include=strings 时,STRING 令牌仍会列出,但 valuesByMode 为空,并带有 "omitted": "strings"。
平台代码输出
加上 ?format= 即可接收生成的平台代码,而不是 JSON:
| format | 输出 | Content-Type |
|---|---|---|
css@1 (别名 css) | CSS 自定义属性——默认模式在 :root,其他模式在 [data-theme="<mode>"] | text/css |
swift@1 (别名 swift) | SwiftUI——每个集合一个类型,每个模式一个静态实例 | text/plain |
compose@1 (别名 compose) | Jetpack Compose(Kotlin)——结构与 Swift 相同 | text/plain |
格式带有版本号。不带版本的名称(css)是永久固定到 @1 的别名——不会自行切换到更新的版本。同一版本内只允许两类变更:修正语法无效的输出,以及安全转义方面的修正;两者都会提升该格式的 rev(见下文 /formats)并使缓存失效。任何改变值的表示方式或标识符的变更都是新版本(css@2),旧版本会继续提供 12 个月(通过 Deprecation 和 Sunset 头告知)。
curl -H "Authorization: Bearer vjt_..." \
"https://variablejar.com/api/v1/variables?format=css" \
> variables.css
输出是确定性的——相同的令牌总会产生相同的字节,因此 ETag/If-None-Match 缓存与 JSON 响应的效果相同。别名始终解析为最终值;无法解析的引用以注释输出,绝不会编造数值。未知的 format 会返回 400 { "error": "unknown_format" }。
标识符由集合名和变量名生成,与数据的顺序无关:在 Figma 中调整集合、变量或模式的顺序,永远不会让令牌改名。当两个名称归并为同一个标识符时,按原始名称排序在前的保留原本的标识符,其余的依次加上 _2、_3 ……;新增一个冲突的名称可能会让已有的编号后移,因此请避免只在分隔符或大小写上不同的名称。无论使用哪种筛选(collection、include=strings,或仅限部分集合的令牌),同一个变量得到的标识符都相同:名称先在整个项目范围内确定,之后才对响应进行筛选。
?collection=<name> 把输出限定为一个集合(项目中没有该名称时返回 400 unknown_collection)。?view=ai@1 返回为 AI 智能体整理过的精简视图(只有名称和值,默认不含文本值);它不能与 format 同时使用,除 index(见下文)外的其他 view 值会返回 400 unknown_view。
?view=index 与 format 一起使用时,返回的不是代码,而是每个变量在该格式中得到的标识符——无需解析生成的代码即可核对名称。标识符的写法与输出一致(Swift/Kotlin 关键字保留反引号)。只有当令牌签发时包含文本值、并且加上 include=strings 时,文本(STRING)变量才会出现在索引中。不带 format 的 view=index 会返回 400 unknown_view。
curl -H "Authorization: Bearer vjt_..." \
"https://variablejar.com/api/v1/variables?format=css@1&view=index"
{
"format": "css@1",
"rev": "1-1",
"identifiers": [
{ "collection": "Color", "key": "btn/bg", "identifier": "--color-btn-bg" }
]
}
GET /api/v1/formats 列出此服务器提供的格式和版本,以及各自当前的 rev、文件名和 Content-Type。它使用同一个令牌,但不计入用量和请求频率限制,并与变量端点一样支持 ETag/If-None-Match(没有 X-VJ-Stamp——列表是静态的)。已被新版本取代的版本还会带有 "deprecated": { "since": "YYYY-MM-DD", "sunset": "YYYY-MM-DD" }。只有在已确定日期时才会有 sunset。
{
"contract": "1",
"formats": [
{ "id": "css", "version": 1, "spec": "css@1", "rev": "1-1", "alias": "css", "filename": "variables.css", "mime": "text/css; charset=utf-8" },
{ "id": "swift", "version": 1, "spec": "swift@1", "rev": "1-1", "alias": "swift", "filename": "Tokens.swift", "mime": "text/plain; charset=utf-8" },
{ "id": "compose", "version": 1, "spec": "compose@1", "rev": "1-1", "alias": "compose", "filename": "Tokens.kt", "mime": "text/plain; charset=utf-8" }
],
"views": [{ "view": "ai@1", "rev": "1" }]
}
轮询与 ETag
响应包含 ETag 头。把它作为 If-None-Match 发回,如果没有变化就会得到 304(无正文)——为移动应用和 CI 的定期检查节省带宽。请原样使用收到的 ETag 值(可能包含 W/)。
curl -i -H "Authorization: Bearer vjt_..." \
-H 'If-None-Match: "…"' \
"https://variablejar.com/api/v1/variables"
# HTTP/2 304
200 和 304 响应都带有以下头:
| 头 | 含义 |
|---|---|
ETag / If-None-Match | 把上次收到的 ETag 发回;数据未变化时返回无正文的 304 |
X-VJ-Stamp | 项目内容 + 此令牌范围的新鲜度戳(同一令牌的所有格式取值相同)——戳相同,则所有格式的数据都相同 |
X-VJ-TTL | 再次检查前应等待的秒数(30–600) |
X-VJ-Token-Expires | 此令牌的过期时间 |
X-VJ-Contract | API 契约版本(1) |
X-VJ-Format | ?format= 响应的格式及版本,例如 css@1 |
错误
错误响应的正文为 { "error": "<代码>" }。
| 状态码 | 含义 |
|---|---|
400 unknown_format · unknown_view · unknown_collection | 未知的 format 或 view 值,或项目中不存在的 collection 名称 |
401 unauthorized | 令牌缺失 / 格式错误 / 已撤销 |
401 token_expired | 令牌已过期——请重新签发 |
403 token_inactive | 令牌的签发者已离开工作区,或失去了令牌所需的角色 |
403 plan_required | 工作区的方案不包含 API |
403 scope_denied | include=strings 需要签发时包含文本值的令牌 |
404 not_found | 路径错误,或项目已被删除或移入回收站 |
405 method_not_allowed | GET 或 OPTIONS 以外的方法(OPTIONS 以 204 响应 CORS 预检) |
413 too_large | 项目超出 API 的大小上限(25,000 个变量或 24 MB 的变量数据)——请将部分集合移到另一个项目,或联系 support@variablejar.com |
426 client_outdated | 所报告的客户端(X-VJ-Client)低于此服务器接受的最低版本——请升级 @variablejar/mcp |
429 rate_limited | 请求过多——请等待 Retry-After 指定的秒数后重试 |
500 internal | 服务器错误——如重试后仍然出现,请联系 support@variablejar.com |
502 upstream_unreachable | API 网关无法连接后端——请重试 |
503 not_configured | 服务未配置——请联系 support@variablejar.com |
MCP 服务器(IDE / AI 智能体)
在 IDE 和 AI 编程智能体中,@variablejar/mcp MCP 服务器比 REST 更方便——同一个令牌两者通用。你可以把本页交给 AI 智能体,让它帮你完成集成设置。
添加到你的 MCP 配置中(固定版本):
{
"mcpServers": {
"variablejar": {
"command": "npx",
"args": ["-y", "@variablejar/mcp@0.3.1"],
"env": { "VARIABLEJAR_TOKEN": "vjt_your_token_here" }
}
}
}
配置文件的位置取决于客户端:
| 客户端 | 配置文件 |
|---|---|
| Claude Code | 项目根目录的 .mcp.json |
| Cursor | .cursor/mcp.json |
| 其他 MCP 客户端 | 请参阅客户端的 MCP 服务器设置 |
可用工具:
| 工具 | 输入 | 说明 |
|---|---|---|
list_collections | — | 集合及其模式、令牌数量、类型分布和顶层分组——从这里开始 |
list_tokens | collection? prefix? type? query? format? limit(50,最大 200) cursor? include_strings? | 分页返回令牌,值按模式解析。数据块的第一行始终是 total=<n> returned=<m> nextCursor=<c|none>。指定 format(例如 css@1)时,每个令牌还会带上它在该格式中的标识符 |
get_token | key collection? format? | 按键获取单个令牌(例如 color/primary);如果该键存在于多个集合中,则返回候选项 |
list_formats | — | 服务器可生成的格式和版本,与 GET /formats 相同 |
get_tokens | format collection? | 以生成的代码返回项目(或一个集合)。超过 24,000 个字符的结果不会被截断——工具会告诉智能体如何按集合缩小范围。在 CI 中需要完整文件时,请使用 REST 并提交该文件 |
服务器只在内存中保存结果,每个 TTL(30–600 秒)重新检查一次 API,只要项目的新鲜度戳不变,就复用全部结果。工具结果沿用 API 的错误码(error: unauthorized、error: plan_required 等);无法连接 API 时,会返回上一次的结果,并注明它是多久之前的。令牌数据包裹在随机边界标记中,并带有一段固定的前言,声明其内容是数据而非指令。
环境变量:
| 变量 | 必填 | 说明 |
|---|---|---|
VARIABLEJAR_TOKEN | ✓ | 项目 API 令牌(vjt_…)——一个令牌对应一个项目 |
VARIABLEJAR_API_URL | https://variablejar.com/api/v1(默认)或 https://staging.variablejar.com/api/v1;其他主机一律拒绝 |
从 0.2.0 升级:该版本调用的是已停用的端点,现在会收到 410。工具名称不变,输入只有新增,但输出已改变——list_tokens 改为分页,第一行为 total=…,并使用短键(c、k、t、v);get_token 也使用相同的短键,如果该键存在于多个集合中,则返回候选项;list_collections 不再返回 id;get_tokens 返回一个前言块,以及一个位于边界标记内的代码块。
服务器是只读的——令牌无法写入或删除任何内容。
注意
- 不要从浏览器(网页前端)直接调用——令牌会暴露在客户端代码中。请在令牌不会外泄的服务器、应用或 CI 中使用。
- 暂不提供写入 API 和增量(仅变化部分)查询。
- 作为 LLM 上下文,完整文档以 /llms.txt(索引)和 /llms-full.txt(全部内容合为一个文件)提供(英文)。