figma-mcp-server 0.1.1 → 2.0.0

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/.env.example +1 -0
  2. package/LICENSE +1 -0
  3. package/README.md +29 -38
  4. package/bun.lock +195 -0
  5. package/index.js +1 -2
  6. package/lib/tools.js +1 -5
  7. package/mcpServer.js +19 -12
  8. package/package.json +3 -2
  9. package/tools/figma/figma-api/create-dev-resources-for-a-file.js +0 -20
  10. package/tools/figma/figma-api/create-variable-collections-for-a-file.js +0 -18
  11. package/tools/figma/figma-api/get-a-published-component-by-key.js +0 -16
  12. package/tools/figma/figma-api/get-a-published-component-set-by-key.js +0 -16
  13. package/tools/figma/figma-api/get-a-published-library-by-id.js +0 -16
  14. package/tools/figma/figma-api/get-a-published-style-by-key.js +0 -16
  15. package/tools/figma/figma-api/get-current-user.js +0 -13
  16. package/tools/figma/figma-api/get-file-nodes.js +0 -17
  17. package/tools/figma/figma-api/get-file-version-history.js +0 -16
  18. package/tools/figma/figma-api/get-file.js +0 -16
  19. package/tools/figma/figma-api/get-image-fills.js +0 -17
  20. package/tools/figma/figma-api/get-library-action-analytics.js +0 -16
  21. package/tools/figma/figma-api/get-library-usage-analytics.js +0 -16
  22. package/tools/figma/figma-api/list-comments-on-a-file.js +0 -16
  23. package/tools/figma/figma-api/list-component-sets-in-a-file.js +0 -16
  24. package/tools/figma/figma-api/list-components-in-a-file.js +0 -16
  25. package/tools/figma/figma-api/list-dev-resources-for-a-file.js +0 -16
  26. package/tools/figma/figma-api/list-files-in-a-project.js +0 -16
  27. package/tools/figma/figma-api/list-projects-in-a-team.js +0 -16
  28. package/tools/figma/figma-api/list-published-libraries.js +0 -13
  29. package/tools/figma/figma-api/list-styles-in-a-file.js +0 -16
  30. package/tools/figma/figma-api/list-variables-for-a-file.js +0 -16
  31. package/tools/figma/figma-api/post-a-comment-to-a-file.js +1 -23
  32. package/Dockerfile +0 -9
package/.env.example ADDED
@@ -0,0 +1 @@
1
+ FIGMA_API_KEY=
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
@@ -7,7 +7,7 @@ Install the server
7
7
  ```bash
8
8
  git clone https://github.com/planetabhi/figma-mcp-server.git
9
9
  cd figma-mcp-server
10
- pnpm i
10
+ bun i
11
11
  ```
12
12
 
13
13
  ### Set tool environment variable
@@ -23,7 +23,7 @@ FIGMA_API_KEY=
23
23
  List descriptions and parameters from all available tools
24
24
 
25
25
  ```bash
26
- pnpm list-tools
26
+ bun list-tools
27
27
  ```
28
28
 
29
29
  ## Run the MCP Server
@@ -58,55 +58,46 @@ realpath mcpServer.js
58
58
 
59
59
  > 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
60
 
61
- ### Run in Postman
62
61
 
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.
62
+ ### Run with Gemini CLI
67
63
 
68
- ```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
- ```
72
-
73
- > [Postman collection](https://www.postman.com/doitagain/workspace/figma/collection/68369062465421c338809955?action=share&creator=17652550).
74
-
75
- ---
76
-
77
- ### Misc
78
-
79
- #### Docker Deployment
80
-
81
- For production deployments, you can use Docker:
82
-
83
- **1. Build Docker image**
64
+ 1. Open a new terminal and create the `.gemini` directory (if it doesn't exist)
84
65
 
85
66
  ```bash
86
- docker build -t figma-mcp-server .
67
+ mkdir -p ~/.gemini
87
68
  ```
88
69
 
89
- **2. Claude Desktop integration**
70
+ 2. Create the `settings.json` file
90
71
 
91
- Add Docker server configuration to Claude Desktop (Settings → Developers → Edit Config):
92
-
93
- ```json
94
- {
72
+ ```bash
73
+ echo '{
95
74
  "mcpServers": {
96
75
  "figma-mcp-server": {
97
- "command": "docker",
98
- "args": ["run", "-i", "--rm", "--env-file=.env", "figma-mcp-server"]
76
+ "command": "<absolute_path_to_node>",
77
+ "args": ["mcpServer.js"],
78
+ "cwd": "<absolute_path_to_working_directory>",
79
+ "env": {
80
+ "FIGMA_API_KEY": "your_figma_api_key_here"
81
+ },
82
+ "trust": true
99
83
  }
100
84
  }
101
- }
85
+ }' > ~/.gemini/settings.json
86
+ ```
87
+
88
+ 3. Start Gemini CLI
89
+
90
+ ```bash
91
+ export GEMINI_API_KEY="your_gemini_api_key_here"
92
+ npx https://github.com/google-gemini/gemini-cli
102
93
  ```
103
94
 
104
- > Add your environment variables inside the `.env` file.
95
+ - Use `/mcp` to list all tools
96
+ - Use `/mcp desc` to show server and tool descriptions
97
+ - Use `/mcp schema` to show tool parameter schemas
98
+ - Use `/mcp nodesc` to hide descriptions
105
99
 
106
- #### Server-Sent Events (SSE)
107
100
 
108
- To run the server with Server-Sent Events (SSE) support, use the `--sse` flag:
101
+ ---
109
102
 
110
- ```bash
111
- node mcpServer.js --sse
112
- ```
103
+ ⋛⋋( ⊙◊⊙)⋌⋚
package/bun.lock ADDED
@@ -0,0 +1,195 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "figma-mcp-server",
6
+ "dependencies": {
7
+ "@modelcontextprotocol/sdk": "^1.12.1",
8
+ "commander": "^14.0.0",
9
+ "dotenv": "^16.5.0",
10
+ "express": "^5.1.0",
11
+ },
12
+ },
13
+ },
14
+ "packages": {
15
+ "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.17.2", "", { "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-EFLRNXR/ixpXQWu6/3Cu30ndDFIFNaqUXcTqsGebujeMan9FzhAaFFswLRiFj61rgygDRr8WO1N+UijjgRxX9g=="],
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.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="],
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.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
44
+
45
+ "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
46
+
47
+ "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
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.3", "", {}, "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA=="],
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.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
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.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="],
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.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="],
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
+ "http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
194
+ }
195
+ }
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
@@ -21,7 +21,9 @@ const __dirname = path.dirname(__filename);
21
21
 
22
22
  dotenv.config({ path: path.resolve(__dirname, ".env") });
23
23
 
24
- const SERVER_NAME = "generated-mcp-server";
24
+ const SERVER_NAME = process.env.SERVER_NAME || "figma-mcp-server";
25
+ const SERVER_VERSION = process.env.SERVER_VERSION || "0.1.2";
26
+ const DEFAULT_PORT = 3001;
25
27
 
26
28
  async function transformTools(tools) {
27
29
  return tools
@@ -37,14 +39,18 @@ async function transformTools(tools) {
37
39
  .filter(Boolean);
38
40
  }
39
41
 
40
- 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
+
41
47
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
42
- tools: await transformTools(tools),
48
+ tools: transformedTools,
43
49
  }));
44
50
 
45
51
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
46
52
  const toolName = request.params.name;
47
- const tool = tools.find((t) => t.definition.function.name === toolName);
53
+ const tool = toolMap.get(toolName);
48
54
  if (!tool) {
49
55
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`);
50
56
  }
@@ -83,6 +89,7 @@ async function run() {
83
89
  const args = process.argv.slice(2);
84
90
  const isSSE = args.includes("--sse");
85
91
  const tools = await discoverTools();
92
+ const transformedTools = await transformTools(tools);
86
93
 
87
94
  if (isSSE) {
88
95
  const app = express();
@@ -90,11 +97,10 @@ async function run() {
90
97
  const servers = {};
91
98
 
92
99
  app.get("/sse", async (_req, res) => {
93
- // Create a new Server instance for each session
94
100
  const server = new Server(
95
101
  {
96
102
  name: SERVER_NAME,
97
- version: "0.1.0",
103
+ version: SERVER_VERSION,
98
104
  },
99
105
  {
100
106
  capabilities: {
@@ -103,7 +109,7 @@ async function run() {
103
109
  }
104
110
  );
105
111
  server.onerror = (error) => console.error("[Error]", error);
106
- await setupServerHandlers(server, tools);
112
+ await setupServerHandlers(server, tools, transformedTools);
107
113
 
108
114
  const transport = new SSEServerTransport("/messages", res);
109
115
  transports[transport.sessionId] = transport;
@@ -130,16 +136,17 @@ async function run() {
130
136
  }
131
137
  });
132
138
 
133
- const port = process.env.PORT || 3001;
139
+ const port = process.env.PORT || DEFAULT_PORT;
134
140
  app.listen(port, () => {
135
141
  console.log(`[SSE Server] running on port ${port}`);
142
+ console.log(`[Server] Name: ${SERVER_NAME}`);
143
+ console.log(`[Server] Version: ${SERVER_VERSION}`);
136
144
  });
137
145
  } else {
138
- // stdio mode: single server instance
139
146
  const server = new Server(
140
147
  {
141
148
  name: SERVER_NAME,
142
- version: "0.1.0",
149
+ version: SERVER_VERSION,
143
150
  },
144
151
  {
145
152
  capabilities: {
@@ -148,7 +155,7 @@ async function run() {
148
155
  }
149
156
  );
150
157
  server.onerror = (error) => console.error("[Error]", error);
151
- await setupServerHandlers(server, tools);
158
+ await setupServerHandlers(server, tools, transformedTools);
152
159
 
153
160
  process.on("SIGINT", async () => {
154
161
  await server.close();
@@ -160,4 +167,4 @@ async function run() {
160
167
  }
161
168
  }
162
169
 
163
- run().catch(console.error);
170
+ run().catch(console.error);
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "figma-mcp-server",
3
- "version": "0.1.1",
3
+ "version": "2.0.0",
4
4
  "description": "A simple MCP server for Figma",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
- "list-tools": "node index.js tools"
8
+ "list-tools": "node index.js tools",
9
+ "start": "node mcpServer.js --sse"
9
10
  },
10
11
  "dependencies": {
11
12
  "@modelcontextprotocol/sdk": "^1.12.1",
@@ -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: {
@@ -1,35 +1,23 @@
1
- /**
2
- * Function to get metadata for a published component in Figma by its key.
3
- *
4
- * @param {Object} args - Arguments for the request.
5
- * @param {string} args.key - The key of the component to retrieve.
6
- * @returns {Promise<Object>} - The metadata of the published component.
7
- */
8
1
  const executeFunction = async ({ key }) => {
9
2
  const baseUrl = 'https://api.figma.com/v1/components';
10
3
  const token = process.env.FIGMA_API_KEY;
11
4
  try {
12
- // Construct the URL with the component key
13
5
  const url = `${baseUrl}/${key}`;
14
6
 
15
- // Set up headers for the request
16
7
  const headers = {
17
8
  'X-Figma-Token': token
18
9
  };
19
10
 
20
- // Perform the fetch request
21
11
  const response = await fetch(url, {
22
12
  method: 'GET',
23
13
  headers
24
14
  });
25
15
 
26
- // Check if the response was successful
27
16
  if (!response.ok) {
28
17
  const errorData = await response.json();
29
18
  throw new Error(errorData);
30
19
  }
31
20
 
32
- // Parse and return the response data
33
21
  const data = await response.json();
34
22
  return data;
35
23
  } catch (error) {
@@ -38,10 +26,6 @@ const executeFunction = async ({ key }) => {
38
26
  }
39
27
  };
40
28
 
41
- /**
42
- * Tool configuration for retrieving component metadata from Figma.
43
- * @type {Object}
44
- */
45
29
  const apiTool = {
46
30
  function: executeFunction,
47
31
  definition: {