figma-mcp-server 0.1.2 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +57 -43
  3. package/bun.lock +197 -0
  4. package/index.js +1 -2
  5. package/lib/tools.js +1 -5
  6. package/mcpServer.js +11 -10
  7. package/package.json +9 -8
  8. package/tools/figma/figma-api/create-dev-resources-for-a-file.js +0 -20
  9. package/tools/figma/figma-api/create-variable-collections-for-a-file.js +0 -18
  10. package/tools/figma/figma-api/get-a-published-component-by-key.js +0 -16
  11. package/tools/figma/figma-api/get-a-published-component-set-by-key.js +0 -16
  12. package/tools/figma/figma-api/get-a-published-library-by-id.js +0 -16
  13. package/tools/figma/figma-api/get-a-published-style-by-key.js +0 -16
  14. package/tools/figma/figma-api/get-current-user.js +0 -13
  15. package/tools/figma/figma-api/get-file-nodes.js +0 -17
  16. package/tools/figma/figma-api/get-file-version-history.js +0 -16
  17. package/tools/figma/figma-api/get-file.js +0 -16
  18. package/tools/figma/figma-api/get-image-fills.js +0 -17
  19. package/tools/figma/figma-api/get-library-action-analytics.js +0 -16
  20. package/tools/figma/figma-api/get-library-usage-analytics.js +0 -16
  21. package/tools/figma/figma-api/list-comments-on-a-file.js +0 -16
  22. package/tools/figma/figma-api/list-component-sets-in-a-file.js +0 -16
  23. package/tools/figma/figma-api/list-components-in-a-file.js +0 -16
  24. package/tools/figma/figma-api/list-dev-resources-for-a-file.js +0 -16
  25. package/tools/figma/figma-api/list-files-in-a-project.js +0 -16
  26. package/tools/figma/figma-api/list-projects-in-a-team.js +0 -16
  27. package/tools/figma/figma-api/list-published-libraries.js +0 -13
  28. package/tools/figma/figma-api/list-styles-in-a-file.js +0 -16
  29. package/tools/figma/figma-api/list-variables-for-a-file.js +0 -16
  30. package/tools/figma/figma-api/post-a-comment-to-a-file.js +1 -23
  31. package/Dockerfile +0 -28
  32. package/smithery.yaml +0 -39
package/LICENSE CHANGED
@@ -1,6 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) 2025 Abhimanyu Rana @planetabhi
4
+ Copyright (c) 2025 Method Black Studio
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Figma MCP Server
2
- A simple MCP server for Figma
2
+ A comprehensive local MCP server for Figma. Connect Figma with the Gemini CLI, Cursor, and Claude Desktop.
3
+
4
+ ### Prerequisites
5
+
6
+ - [Node](https://nodejs.org/) (>= 20)
7
+ - [Bun](https://bun.sh/) (>= 1.1.0)
3
8
 
4
9
  ## Install
5
10
  Install the server
@@ -7,7 +12,7 @@ Install the server
7
12
  ```bash
8
13
  git clone https://github.com/planetabhi/figma-mcp-server.git
9
14
  cd figma-mcp-server
10
- pnpm i
15
+ bun i
11
16
  ```
12
17
 
13
18
  ### Set tool environment variable
@@ -23,22 +28,21 @@ FIGMA_API_KEY=
23
28
  List descriptions and parameters from all available tools
24
29
 
25
30
  ```bash
26
- pnpm list-tools
31
+ bun run list-tools
27
32
  ```
28
33
 
29
34
  ## Run the MCP Server
30
35
 
31
- ### Find node and server path
36
+ ### Find bun and server path
32
37
 
33
38
  ```bash
34
- # Find node path
35
- which node
39
+ # Find bun path
40
+ which bun
36
41
 
37
42
  # Get the absolute path of the MCP server
38
43
  realpath mcpServer.js
39
44
  ```
40
45
 
41
-
42
46
  ### Run with Claude Desktop
43
47
 
44
48
  1. Open Claude Desktop → **Settings** → **Developers** → **Edit Config** and add your server:
@@ -47,7 +51,7 @@ realpath mcpServer.js
47
51
  {
48
52
  "mcpServers": {
49
53
  "figma-mcp-server": {
50
- "command": "<absolute_path_to_node>",
54
+ "command": "<absolute_path_to_bun>",
51
55
  "args": ["<absolute_path_to_mcpServer.js>"]
52
56
  }
53
57
  }
@@ -58,55 +62,65 @@ realpath mcpServer.js
58
62
 
59
63
  > To try it out in Claude Desktop, first enable the `get_file_nodes` tool from the tools list. Copy a design node link from a Figma file, then paste it into Claude Desktop prompt. It will return the design node data and other information.
60
64
 
61
- ### Run in Postman
62
65
 
63
- 1. Choose an existing workspace or create a new one.
64
- 2. Select New > MCP. Postman opens a new MCP request in a new tab.
65
- 3. Select the server's communication method STDIO.
66
- 4. Enter the server's command and arguments.
66
+ ### Run with Gemini CLI
67
+
68
+ 1. Open a new terminal and create the `.gemini` directory (if it doesn't exist)
67
69
 
68
70
  ```bash
69
- # Create a new MCP request and add the server's command and arguments
70
- STDIO <absolute_path_to_node> <absolute_path_to_mcpServer.js>
71
+ mkdir -p ~/.gemini
71
72
  ```
72
73
 
73
- > [Postman collection](https://www.postman.com/doitagain/workspace/figma/collection/68369062465421c338809955?action=share&creator=17652550).
74
-
75
- ---
76
-
77
- ### Misc
74
+ 2. Create the `settings.json` file
78
75
 
79
- #### Docker Deployment
80
-
81
- For production deployments, you can use Docker:
76
+ ```bash
77
+ echo '{
78
+ "mcpServers": {
79
+ "figma-mcp-server": {
80
+ "command": "<absolute_path_to_bun>",
81
+ "args": ["mcpServer.js"],
82
+ "cwd": "<absolute_path_to_working_directory>",
83
+ "env": {
84
+ "FIGMA_API_KEY": "your_figma_api_key_here"
85
+ },
86
+ "trust": true
87
+ }
88
+ }
89
+ }' > ~/.gemini/settings.json
90
+ ```
82
91
 
83
- **1. Build Docker image**
92
+ 3. Start Gemini CLI
84
93
 
85
94
  ```bash
86
- docker build -t figma-mcp-server .
95
+ export GEMINI_API_KEY="your_gemini_api_key_here"
96
+ npx https://github.com/google-gemini/gemini-cli
87
97
  ```
88
98
 
89
- **2. Claude Desktop integration**
99
+ - Use `/mcp` to list all tools
100
+ - Use `/mcp desc` to show server and tool descriptions
101
+ - Use `/mcp schema` to show tool parameter schemas
102
+ - Use `/mcp nodesc` to hide descriptions
90
103
 
91
- Add Docker server configuration to Claude Desktop (Settings → Developers → Edit Config):
104
+ ---
92
105
 
93
- ```json
94
- {
95
- "mcpServers": {
96
- "figma-mcp-server": {
97
- "command": "docker",
98
- "args": ["run", "-i", "--rm", "--env-file=.env", "figma-mcp-server"]
99
- }
100
- }
101
- }
102
- ```
106
+ ### Troubleshooting
103
107
 
104
- > Add your environment variables inside the `.env` file.
108
+ - Missing Figma token
109
+ - Error: missing or invalid `FIGMA_API_KEY`.
110
+ - Ensure `.env` exists next to `mcpServer.js` with `FIGMA_API_KEY=...`.
111
+ - Port already in use (SSE mode)
112
+ - Run SSE on a custom port: `PORT=3005 node mcpServer.js --sse`.
113
+ - Bun not found
114
+ - Ensure `which bun` returns a path.
115
+ - Restart your shell after installing Bun.
116
+ - Using npm instead of Bun
117
+ - Replace `bun i` → `npm i`
118
+ - Replace `bun run list-tools` → `node index.js tools`
119
+ - Manual start not required
120
+ - Only start manually for SSE or local web endpoint: `node mcpServer.js --sse`
121
+ - Default port is `3001`, override with `PORT=<port>`
105
122
 
106
- #### Server-Sent Events (SSE)
107
123
 
108
- To run the server with Server-Sent Events (SSE) support, use the `--sse` flag:
124
+ ---
109
125
 
110
- ```bash
111
- node mcpServer.js --sse
112
- ```
126
+ [MIT License](https://raw.githubusercontent.com/planetabhi/figma-mcp-server/refs/heads/main/LICENSE) · By [@planetabhi](https://planetabhi.com/) ⋛⋋( ⊙◊⊙)⋌⋚
package/bun.lock ADDED
@@ -0,0 +1,197 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "figma-mcp-server",
6
+ "dependencies": {
7
+ "@modelcontextprotocol/sdk": "^1.18.1",
8
+ "commander": "^14.0.1",
9
+ "dotenv": "^17.2.2",
10
+ "express": "^5.1.0",
11
+ },
12
+ },
13
+ },
14
+ "packages": {
15
+ "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.18.1", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-d//GE8/Yh7aC3e7p+kZG8JqqEAwwDUmAfvH1quogtbk+ksS6E0RR6toKKESPYYZVre0meqkJb27zb+dhqE9Sgw=="],
16
+
17
+ "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
18
+
19
+ "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
20
+
21
+ "body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
22
+
23
+ "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
24
+
25
+ "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
26
+
27
+ "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
28
+
29
+ "commander": ["commander@14.0.1", "", {}, "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A=="],
30
+
31
+ "content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
32
+
33
+ "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
34
+
35
+ "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
36
+
37
+ "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
38
+
39
+ "cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="],
40
+
41
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
42
+
43
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
44
+
45
+ "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
46
+
47
+ "dotenv": ["dotenv@17.2.2", "", {}, "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q=="],
48
+
49
+ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
50
+
51
+ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
52
+
53
+ "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
54
+
55
+ "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
56
+
57
+ "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
58
+
59
+ "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
60
+
61
+ "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
62
+
63
+ "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
64
+
65
+ "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
66
+
67
+ "eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="],
68
+
69
+ "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
70
+
71
+ "express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="],
72
+
73
+ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
74
+
75
+ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
76
+
77
+ "finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="],
78
+
79
+ "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
80
+
81
+ "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
82
+
83
+ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
84
+
85
+ "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
86
+
87
+ "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
88
+
89
+ "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
90
+
91
+ "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
92
+
93
+ "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
94
+
95
+ "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
96
+
97
+ "iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="],
98
+
99
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
100
+
101
+ "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
102
+
103
+ "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
104
+
105
+ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
106
+
107
+ "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
108
+
109
+ "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
110
+
111
+ "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
112
+
113
+ "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
114
+
115
+ "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
116
+
117
+ "mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
118
+
119
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
120
+
121
+ "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
122
+
123
+ "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
124
+
125
+ "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
126
+
127
+ "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
128
+
129
+ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
130
+
131
+ "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
132
+
133
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
134
+
135
+ "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
136
+
137
+ "pkce-challenge": ["pkce-challenge@5.0.0", "", {}, "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ=="],
138
+
139
+ "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
140
+
141
+ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
142
+
143
+ "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
144
+
145
+ "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
146
+
147
+ "raw-body": ["raw-body@3.0.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.7.0", "unpipe": "1.0.0" } }, "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA=="],
148
+
149
+ "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
150
+
151
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
152
+
153
+ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
154
+
155
+ "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
156
+
157
+ "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
158
+
159
+ "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
160
+
161
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
162
+
163
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
164
+
165
+ "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
166
+
167
+ "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
168
+
169
+ "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
170
+
171
+ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
172
+
173
+ "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
174
+
175
+ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
176
+
177
+ "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
178
+
179
+ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
180
+
181
+ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
182
+
183
+ "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
184
+
185
+ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
186
+
187
+ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
188
+
189
+ "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
190
+
191
+ "zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
192
+
193
+ "body-parser/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
194
+
195
+ "http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
196
+ }
197
+ }
package/index.js CHANGED
@@ -3,7 +3,6 @@ import { registerToolsCommand } from "./commands/tools.js";
3
3
 
4
4
  const program = new Command();
5
5
 
6
- // Register commands
7
6
  registerToolsCommand(program);
8
7
 
9
- program.parse(process.argv);
8
+ program.parse(process.argv);
package/lib/tools.js CHANGED
@@ -1,9 +1,5 @@
1
1
  import { toolPaths } from "../tools/paths.js";
2
2
 
3
- /**
4
- * Discovers and loads available tools from the tools directory
5
- * @returns {Promise<Array>} Array of tool objects
6
- */
7
3
  export async function discoverTools() {
8
4
  const toolPromises = toolPaths.map(async (file) => {
9
5
  const module = await import(`../tools/${file}`);
@@ -13,4 +9,4 @@ export async function discoverTools() {
13
9
  };
14
10
  });
15
11
  return Promise.all(toolPromises);
16
- }
12
+ }
package/mcpServer.js CHANGED
@@ -19,10 +19,8 @@ import { fileURLToPath } from "url";
19
19
  const __filename = fileURLToPath(import.meta.url);
20
20
  const __dirname = path.dirname(__filename);
21
21
 
22
- // Load environment variables
23
22
  dotenv.config({ path: path.resolve(__dirname, ".env") });
24
23
 
25
- // Server configuration
26
24
  const SERVER_NAME = process.env.SERVER_NAME || "figma-mcp-server";
27
25
  const SERVER_VERSION = process.env.SERVER_VERSION || "0.1.2";
28
26
  const DEFAULT_PORT = 3001;
@@ -41,14 +39,18 @@ async function transformTools(tools) {
41
39
  .filter(Boolean);
42
40
  }
43
41
 
44
- async function setupServerHandlers(server, tools) {
42
+ async function setupServerHandlers(server, tools, transformedTools) {
43
+ const toolMap = new Map(
44
+ tools.map((tool) => [tool.definition.function.name, tool])
45
+ );
46
+
45
47
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
46
- tools: await transformTools(tools),
48
+ tools: transformedTools,
47
49
  }));
48
50
 
49
51
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
50
52
  const toolName = request.params.name;
51
- const tool = tools.find((t) => t.definition.function.name === toolName);
53
+ const tool = toolMap.get(toolName);
52
54
  if (!tool) {
53
55
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`);
54
56
  }
@@ -87,6 +89,7 @@ async function run() {
87
89
  const args = process.argv.slice(2);
88
90
  const isSSE = args.includes("--sse");
89
91
  const tools = await discoverTools();
92
+ const transformedTools = await transformTools(tools);
90
93
 
91
94
  if (isSSE) {
92
95
  const app = express();
@@ -94,7 +97,6 @@ async function run() {
94
97
  const servers = {};
95
98
 
96
99
  app.get("/sse", async (_req, res) => {
97
- // Create a new Server instance for each session
98
100
  const server = new Server(
99
101
  {
100
102
  name: SERVER_NAME,
@@ -107,7 +109,7 @@ async function run() {
107
109
  }
108
110
  );
109
111
  server.onerror = (error) => console.error("[Error]", error);
110
- await setupServerHandlers(server, tools);
112
+ await setupServerHandlers(server, tools, transformedTools);
111
113
 
112
114
  const transport = new SSEServerTransport("/messages", res);
113
115
  transports[transport.sessionId] = transport;
@@ -141,7 +143,6 @@ async function run() {
141
143
  console.log(`[Server] Version: ${SERVER_VERSION}`);
142
144
  });
143
145
  } else {
144
- // stdio mode: single server instance
145
146
  const server = new Server(
146
147
  {
147
148
  name: SERVER_NAME,
@@ -154,7 +155,7 @@ async function run() {
154
155
  }
155
156
  );
156
157
  server.onerror = (error) => console.error("[Error]", error);
157
- await setupServerHandlers(server, tools);
158
+ await setupServerHandlers(server, tools, transformedTools);
158
159
 
159
160
  process.on("SIGINT", async () => {
160
161
  await server.close();
@@ -166,4 +167,4 @@ async function run() {
166
167
  }
167
168
  }
168
169
 
169
- run().catch(console.error);
170
+ run().catch(console.error);
package/package.json CHANGED
@@ -1,21 +1,22 @@
1
1
  {
2
2
  "name": "figma-mcp-server",
3
- "version": "0.1.2",
4
- "description": "A simple MCP server for Figma",
3
+ "version": "2.0.1",
4
+ "description": "A comprehensive local MCP server for Figma. Connect Figma with the Gemini CLI, Cursor, and Claude Desktop.",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
- "list-tools": "node index.js tools",
9
- "start": "node mcpServer.js --sse"
8
+ "list-tools": "bun index.js tools",
9
+ "start": "bun mcpServer.js --sse"
10
10
  },
11
11
  "dependencies": {
12
- "@modelcontextprotocol/sdk": "^1.12.1",
13
- "commander": "^14.0.0",
14
- "dotenv": "^16.5.0",
12
+ "@modelcontextprotocol/sdk": "^1.18.1",
13
+ "commander": "^14.0.1",
14
+ "dotenv": "^17.2.2",
15
15
  "express": "^5.1.0"
16
16
  },
17
17
  "engines": {
18
- "node": ">=16.0.0"
18
+ "node": ">=20.0.0",
19
+ "bun": ">=1.1.0"
19
20
  },
20
21
  "keywords": [
21
22
  "figma",
@@ -1,27 +1,14 @@
1
- /**
2
- * Function to create development resources for a Figma file.
3
- *
4
- * @param {Object} args - Arguments for creating development resources.
5
- * @param {string} args.file_key - The key of the Figma file.
6
- * @param {string} args.node_id - The node ID for the resource.
7
- * @param {string} args.name - The name of the development resource.
8
- * @param {string} args.url - The URL for the development resource.
9
- * @returns {Promise<Object>} - The result of the resource creation.
10
- */
11
1
  const executeFunction = async ({ file_key, node_id, name, url }) => {
12
2
  const baseUrl = 'https://api.figma.com';
13
3
  const token = process.env.FIGMA_API_KEY;
14
4
  try {
15
- // Construct the URL for the API request
16
5
  const url = `${baseUrl}/v1/files/${file_key}/dev_resources`;
17
6
 
18
- // Set up headers for the request
19
7
  const headers = {
20
8
  'X-Figma-Token': token,
21
9
  'Content-Type': 'application/json'
22
10
  };
23
11
 
24
- // Create the body for the request
25
12
  const body = JSON.stringify({
26
13
  dev_resources: [
27
14
  {
@@ -33,20 +20,17 @@ const executeFunction = async ({ file_key, node_id, name, url }) => {
33
20
  ]
34
21
  });
35
22
 
36
- // Perform the fetch request
37
23
  const response = await fetch(url, {
38
24
  method: 'POST',
39
25
  headers,
40
26
  body
41
27
  });
42
28
 
43
- // Check if the response was successful
44
29
  if (!response.ok) {
45
30
  const errorData = await response.json();
46
31
  throw new Error(errorData);
47
32
  }
48
33
 
49
- // Parse and return the response data
50
34
  const data = await response.json();
51
35
  return data;
52
36
  } catch (error) {
@@ -55,10 +39,6 @@ const executeFunction = async ({ file_key, node_id, name, url }) => {
55
39
  }
56
40
  };
57
41
 
58
- /**
59
- * Tool configuration for creating development resources for a Figma file.
60
- * @type {Object}
61
- */
62
42
  const apiTool = {
63
43
  function: executeFunction,
64
44
  definition: {
@@ -1,25 +1,14 @@
1
- /**
2
- * Function to create variable collections for a Figma file.
3
- *
4
- * @param {Object} args - Arguments for creating variable collections.
5
- * @param {string} args.file_key - The key of the Figma file where the variable collection will be created.
6
- * @param {string} args.name - The name of the variable collection to create.
7
- * @returns {Promise<Object>} - The result of the variable collection creation.
8
- */
9
1
  const executeFunction = async ({ file_key, name }) => {
10
2
  const baseUrl = 'https://api.figma.com';
11
3
  const token = process.env.FIGMA_API_KEY;
12
4
  try {
13
- // Construct the URL for the request
14
5
  const url = `${baseUrl}/v1/files/${file_key}/variables`;
15
6
 
16
- // Set up headers for the request
17
7
  const headers = {
18
8
  'X-Figma-Token': token,
19
9
  'Content-Type': 'application/json'
20
10
  };
21
11
 
22
- // Define the body of the request
23
12
  const body = JSON.stringify({
24
13
  variableCollections: [
25
14
  {
@@ -29,20 +18,17 @@ const executeFunction = async ({ file_key, name }) => {
29
18
  ]
30
19
  });
31
20
 
32
- // Perform the fetch request
33
21
  const response = await fetch(url, {
34
22
  method: 'POST',
35
23
  headers,
36
24
  body
37
25
  });
38
26
 
39
- // Check if the response was successful
40
27
  if (!response.ok) {
41
28
  const errorData = await response.json();
42
29
  throw new Error(errorData);
43
30
  }
44
31
 
45
- // Parse and return the response data
46
32
  const data = await response.json();
47
33
  return data;
48
34
  } catch (error) {
@@ -51,10 +37,6 @@ const executeFunction = async ({ file_key, name }) => {
51
37
  }
52
38
  };
53
39
 
54
- /**
55
- * Tool configuration for creating variable collections in a Figma file.
56
- * @type {Object}
57
- */
58
40
  const apiTool = {
59
41
  function: executeFunction,
60
42
  definition: {