{"_id":"10x-variables-mcp","name":"10x-variables-mcp","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"10x-variables-mcp","version":"0.1.0","description":"MCP server for the 10x Variables Figma plugin","license":"MIT","author":{"name":"Maxim Melnikov"},"keywords":["mcp","figma","figma-plugin","variables","design-tokens","model-context-protocol"],"bin":{"10x-variables-mcp":"dist/mcp-server/src/index.js"},"main":"dist/mcp-server/src/index.js","scripts":{"build":"tsc","test":"jest","prepublishOnly":"npm run build"},"engines":{"node":">=18"},"dependencies":{"@modelcontextprotocol/sdk":"^1.0.0","ws":"^8.18.0"},"devDependencies":{"@figma/plugin-typings":"^1.68.0","@types/jest":"^29.0.0","@types/ws":"^8.5.0","jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0"},"_id":"10x-variables-mcp@0.1.0","gitHead":"96e7790a8cf22cf7c0d2f1c77851d5ffc59e9573","_nodeVersion":"22.12.0","_npmVersion":"11.5.2","dist":{"integrity":"sha512-LWikVibmy+1rGQNop+eoPzIEbpPo/TUBuCg69rHW2+94XKmlt/V0s4CErLmMH/Jx4rA7x70gL8UUmo+t8AIXqg==","shasum":"99f4abe791e5b67742a862e70a6588b73b6a3b90","tarball":"https://registry.npmjs.org/10x-variables-mcp/-/10x-variables-mcp-0.1.0.tgz","fileCount":20,"unpackedSize":149049,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDuZkscQTJ1RK6r0GX88S+So5a3zw/pcZ8qKd3z2s7AwwIgQJMI6s/knFLU+m5HlDcv2AtzFyWPl7eBX5ws0BykyeE="}]},"_npmUser":{"name":"bbsody","email":"mxmmlnkv@gmail.com"},"directories":{},"maintainers":[{"name":"bbsody","email":"mxmmlnkv@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/10x-variables-mcp_0.1.0_1783593438116_0.9519488611798876"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-09T10:37:18.074Z","0.1.0":"2026-07-09T10:37:18.235Z","modified":"2026-07-09T10:37:18.471Z"},"maintainers":[{"name":"bbsody","email":"mxmmlnkv@gmail.com"}],"description":"MCP server for the 10x Variables Figma plugin","keywords":["mcp","figma","figma-plugin","variables","design-tokens","model-context-protocol"],"author":{"name":"Maxim Melnikov"},"license":"MIT","readme":"# 10x-variables-mcp\n\nMCP server for the [10x Variables](https://www.figma.com/community) Figma plugin. Lets AI agents (Claude Code, Cursor, and any MCP client) manage variable collections, variables, JavaScript expressions, external libraries, reusable helpers, and the update interval inside your Figma document.\n\n## Setup\n\n1. Add the server to your MCP client config:\n\n   ```json\n   {\n     \"mcpServers\": {\n       \"10x-variables\": {\n         \"command\": \"npx\",\n         \"args\": [\"-y\", \"10x-variables-mcp\"]\n       }\n     }\n   }\n   ```\n\n2. In Figma, open the 10x Variables plugin and enable **Enable agent control (MCP)** in plugin Settings. The status line shows \"Connected to agent\" when the link is up.\n\n## How it works\n\nThe server exposes 20 MCP tools over stdio and hosts a localhost WebSocket server (default port `38472`, override with `TENX_MCP_PORT`). The WebSocket server binds to `127.0.0.1` only and rejects connections from web pages — only the Figma plugin and local processes can reach it. The plugin's UI dials into that socket and relays commands into the plugin. That means:\n\n- **The plugin window must stay open in Figma.** If it isn't, tools return `[PLUGIN_NOT_CONNECTED]` with recovery instructions. The only exception is `get_expression_docs`, which is answered by the server itself.\n- Commands run one at a time in each plugin (strict FIFO), so mutations never interleave.\n\n## Multiple documents\n\nEvery open Figma document with the plugin running is its own connected instance, and agents can work with several at once:\n\n- `get_status` (no arguments) lists every instance with its id and document name.\n- While more than one instance is connected, every other tool call must pass the optional `instance` argument (a document name or instance id) — unqualified calls fail with `[AMBIGUOUS_INSTANCE]` listing the choices, so a mutation can never land in a document the agent didn't name.\n- Every result is stamped with the `instance` it came from.\n- Variable/collection ids are file-scoped; agents are instructed never to reuse ids across documents.\n\nDead connections are reaped by a WebSocket ping every 30 s.\n\n## Tools\n\n| Area | Tools |\n|------|-------|\n| Read | `get_status`, `get_snapshot`, `get_variable`, `list_libraries`, `get_helpers` |\n| Variables | `create_variable`, `set_expression`, `set_mode_value`, `rename_variable`, `remove_variables` |\n| Collections | `create_collection`, `rename_collection`, `remove_collection`, `manage_modes` |\n| Libraries & config | `save_library`, `delete_library`, `toggle_library`, `set_helpers`, `set_interval` |\n| Documentation | `get_expression_docs` |\n\n`remove_variables` and `remove_collection` are destructive and permanently delete content — agents are instructed to confirm with you first. `remove_variables` deletes in order and stops at the first error; earlier deletions stay applied, and the response's `removedVariableIds` lists exactly which ids were deleted.\n\n`get_expression_docs` teaches the agent how to write expressions: topic `guide` (default) covers expression shape, `$` / `$$` / `$this` reference syntax, built-in globals, color semantics, and gotchas; topics `colordx` and `culori` return the full TypeScript API of the built-in color libraries — the same generated definitions the plugin's expression editor uses, so they never drift from the runtime.\n\n## License behavior\n\n`get_status` reports a `license` block: `licensed`, `expressionVariables`, `freeLimit`, `evaluationActive`, and a purchase link when unlicensed. On the free tier, expression evaluation pauses when the document exceeds the free limit; expression writes (`set_expression`, `create_variable` with an expression) then return an error — the expression is stored but won't evaluate until the plugin is licensed.\n\n## Development\n\n```sh\nyarn install\nyarn test    # Jest suite (broker + tools)\nyarn build   # tsc → dist/\n```\n\nThe wire protocol is shared with the plugin source at `../src/shared/mcp/protocol.ts`.\n","readmeFilename":"README.md","_rev":"1-ee6f3f348d653d7734c040b3865e0bb9"}