API 参考

在任何地方——iOS/Android 应用、CI 流水线——都可以通过 REST 获取 variable Jar 的变量。 只读,使用与 MCP 服务器相同的令牌。

测试版:API 与 MCP 在正式发布前可能会变化;格式现已带有版本号(见“平台代码输出”),不兼容的变更会提前公告,并保留 12 个月的并行期。

签发令牌

  1. variablejar.com/app → 项目卡片的 ⋯ 菜单 → 属性 → API 令牌(MCP) 部分
  2. 输入令牌名称并按 签发——令牌(vjt_…)只在签发后立即显示一次。请妥善保存。
  3. 一个令牌只能访问这一个项目。如果泄露,请立即在同一界面撤销。

令牌会过期(默认 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-ContractAPI 契约版本(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_deniedinclude=strings 需要签发时包含文本值的令牌
404 not_found路径错误,或项目已被删除或移入回收站
405 method_not_allowedGET 或 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_unreachableAPI 网关无法连接后端——请重试
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_tokenscollection? prefix? type? query? format? limit(50,最大 200) cursor? include_strings?分页返回令牌,值按模式解析。数据块的第一行始终是 total=<n> returned=<m> nextCursor=<c|none>。指定 format(例如 css@1)时,每个令牌还会带上它在该格式中的标识符
get_tokenkey collection? format?按键获取单个令牌(例如 color/primary);如果该键存在于多个集合中,则返回候选项
list_formats—服务器可生成的格式和版本,与 GET /formats 相同
get_tokensformat collection?以生成的代码返回项目(或一个集合)。超过 24,000 个字符的结果不会被截断——工具会告诉智能体如何按集合缩小范围。在 CI 中需要完整文件时,请使用 REST 并提交该文件

服务器只在内存中保存结果,每个 TTL(30–600 秒)重新检查一次 API,只要项目的新鲜度戳不变,就复用全部结果。工具结果沿用 API 的错误码(error: unauthorized、error: plan_required 等);无法连接 API 时,会返回上一次的结果,并注明它是多久之前的。令牌数据包裹在随机边界标记中,并带有一段固定的前言,声明其内容是数据而非指令。

环境变量:

变量必填说明
VARIABLEJAR_TOKEN✓项目 API 令牌(vjt_…)——一个令牌对应一个项目
VARIABLEJAR_API_URLhttps://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(全部内容合为一个文件)提供(英文)。