figma-mcp-server 0.1.0 → 0.1.2

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 (34) hide show
  1. package/.env.example +1 -0
  2. package/Dockerfile +21 -2
  3. package/README.md +40 -40
  4. package/mcpServer.js +59 -35
  5. package/package.json +5 -4
  6. package/smithery.yaml +39 -0
  7. package/tools/figma/figma-api/create-dev-resources-for-a-file.js +95 -0
  8. package/tools/figma/figma-api/{create-variable-collection.js → create-variable-collections-for-a-file.js} +12 -13
  9. package/tools/figma/figma-api/get-a-published-component-by-key.js +66 -0
  10. package/tools/figma/figma-api/get-a-published-component-set-by-key.js +66 -0
  11. package/tools/figma/figma-api/get-a-published-library-by-id.js +66 -0
  12. package/tools/figma/figma-api/get-a-published-style-by-key.js +66 -0
  13. package/tools/figma/figma-api/{get-all-webhooks-for-team.js → get-current-user.js} +10 -10
  14. package/tools/figma/figma-api/{get-design-node.js → get-file-nodes.js} +17 -15
  15. package/tools/figma/figma-api/get-file-version-history.js +66 -0
  16. package/tools/figma/figma-api/{get-design.js → get-file.js} +8 -8
  17. package/tools/figma/figma-api/{get-image-node.js → get-image-fills.js} +17 -17
  18. package/tools/figma/figma-api/{get-library-analytics.js → get-library-action-analytics.js} +12 -12
  19. package/tools/figma/figma-api/{get-actions-analytics.js → get-library-usage-analytics.js} +12 -13
  20. package/tools/figma/figma-api/list-comments-on-a-file.js +66 -0
  21. package/tools/figma/figma-api/{get-dev-resources.js → list-component-sets-in-a-file.js} +11 -11
  22. package/tools/figma/figma-api/list-components-in-a-file.js +66 -0
  23. package/tools/figma/figma-api/list-dev-resources-for-a-file.js +66 -0
  24. package/tools/figma/figma-api/{get-project-files.js → list-files-in-a-project.js} +12 -11
  25. package/tools/figma/figma-api/{get-team-projects.js → list-projects-in-a-team.js} +11 -11
  26. package/tools/figma/figma-api/{add-webhook.js → list-published-libraries.js} +11 -12
  27. package/tools/figma/figma-api/{get-file-comments.js → list-styles-in-a-file.js} +11 -11
  28. package/tools/figma/figma-api/{get-images.js → list-variables-for-a-file.js} +13 -13
  29. package/tools/figma/figma-api/post-a-comment-to-a-file.js +102 -0
  30. package/tools/paths.js +23 -17
  31. package/tools/figma/figma-api/delete-webhook.js +0 -64
  32. package/tools/figma/figma-api/post-a-new-comment.js +0 -89
  33. package/tools/figma/figma-api/post-dev-resource.js +0 -93
  34. package/tools/figma/figma-api/reply-to-comment.js +0 -84
package/.env.example ADDED
@@ -0,0 +1 @@
1
+ FIGMA_API_KEY=
package/Dockerfile CHANGED
@@ -1,9 +1,28 @@
1
1
  FROM node:22.12-alpine AS builder
2
2
 
3
+ RUN corepack enable && corepack prepare pnpm@latest --activate
4
+
3
5
  WORKDIR /app
4
- COPY package.json package-lock.json ./
5
- RUN npm install
6
+ COPY package.json pnpm-lock.yaml ./
7
+ RUN pnpm install --frozen-lockfile
6
8
 
7
9
  COPY . .
8
10
 
11
+ # Production stage
12
+ FROM node:22.12-alpine
13
+
14
+ WORKDIR /app
15
+
16
+ RUN corepack enable && corepack prepare pnpm@latest --activate
17
+
18
+ COPY package.json pnpm-lock.yaml ./
19
+ RUN pnpm install --prod --frozen-lockfile
20
+
21
+ COPY --from=builder /app/mcpServer.js ./
22
+
23
+ ENV NODE_ENV=production
24
+
25
+ HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
26
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
27
+
9
28
  ENTRYPOINT ["node", "mcpServer.js"]
package/README.md CHANGED
@@ -1,50 +1,43 @@
1
1
  # Figma MCP Server
2
- MCP server for Figma
2
+ A simple MCP server for Figma
3
3
 
4
4
  ## Install
5
5
  Install the server
6
6
 
7
- ```sh
7
+ ```bash
8
8
  git clone https://github.com/planetabhi/figma-mcp-server.git
9
9
  cd figma-mcp-server
10
10
  pnpm i
11
11
  ```
12
12
 
13
- ### Set tool environment variables
14
- In the `.env` file, set the `FIGMA_API_KEY` to your Figma API key.
13
+ ### Set tool environment variable
14
+ Create a `.env` file and set the `FIGMA_API_KEY` to your Figma API key.
15
15
 
16
- ```
16
+ ```bash
17
17
  FIGMA_API_KEY=
18
18
  ```
19
19
 
20
- ### List Figma Tools
21
- List descriptions and parameters from all available Figma tools
20
+ > To generate a new personal access token, log in to your Figma account, then from the top-left menu, head to Settings, click on the security tab, find the Personal access tokens section, and click Generate new token to open the configuration modal where you can set the expiration and scopes before clicking Generate token.
21
+
22
+ ### List All Tools
23
+ List descriptions and parameters from all available tools
22
24
 
23
- ```sh
25
+ ```bash
24
26
  pnpm list-tools
25
27
  ```
26
28
 
27
29
  ## Run the MCP Server
28
30
 
29
- MCP Server `mcpServer.js` exposes your Figma API tools to MCP-compatible clients.
30
-
31
- 1. Find node path: `which node`
32
- 2. Find mcpServer.js path: `realpath mcpServer.js`
33
-
34
- ### Run with Postman
31
+ ### Find node and server path
35
32
 
36
- Postman desktop app is the easiest way to [run and test MCP servers](https://learning.postman.com/docs/postman-ai-agent-builder/mcp-requests/overview/).
37
-
38
- 1. Choose an existing workspace or create a new one.
39
- 2. Select New > MCP icon MCP. Postman opens a new MCP request in a new tab.
40
- 3. Select the server's communication method STDIO.
41
- 4. Enter the server's command and arguments.
33
+ ```bash
34
+ # Find node path
35
+ which node
42
36
 
43
- ```sh
44
- STDIO <absolute_path_to_node> <absolute_path_to_mcpServer.js>
37
+ # Get the absolute path of the MCP server
38
+ realpath mcpServer.js
45
39
  ```
46
40
 
47
- Or you can fork Postman [collection here](https://www.postman.com/doitagain/workspace/figma/collection/68369062465421c338809955?action=share&creator=17652550).
48
41
 
49
42
  ### Run with Claude Desktop
50
43
 
@@ -53,7 +46,7 @@ Or you can fork Postman [collection here](https://www.postman.com/doitagain/work
53
46
  ```json
54
47
  {
55
48
  "mcpServers": {
56
- "<server_name>": {
49
+ "figma-mcp-server": {
57
50
  "command": "<absolute_path_to_node>",
58
51
  "args": ["<absolute_path_to_mcpServer.js>"]
59
52
  }
@@ -61,52 +54,59 @@ Or you can fork Postman [collection here](https://www.postman.com/doitagain/work
61
54
  }
62
55
  ```
63
56
 
64
- 2. Restart Claude Desktop to activate this change.
57
+ 2. Restart Claude Desktop to activate config change.
58
+
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.
65
60
 
66
- #### Try it out:
61
+ ### Run in Postman
62
+
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.
67
67
 
68
- 1. Open Claude Desktop, then click on the search and tools icon button and select your server name from the list.
69
- 2. Enable the `get_design_node` tool from the tools list.
70
- 3. Copy a design node link from a Figma file, then paste it in Claude Desktop.
71
- 4. It will return the design node data and other information.
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
72
 
73
- > Note: Some tools may be non-functional at the moment because of changes to the Figma API. Working on updating the endpoints in future updates.
73
+ > [Postman collection](https://www.postman.com/doitagain/workspace/figma/collection/68369062465421c338809955?action=share&creator=17652550).
74
74
 
75
75
  ---
76
76
 
77
- ### Additional Options
77
+ ### Misc
78
78
 
79
- #### Docker Deployment (Production)
79
+ #### Docker Deployment
80
80
 
81
81
  For production deployments, you can use Docker:
82
82
 
83
83
  **1. Build Docker image**
84
84
 
85
- ```sh
86
- docker build -t <your_server_name> .
85
+ ```bash
86
+ docker build -t figma-mcp-server .
87
87
  ```
88
88
 
89
- **2. Claude Desktop Integration**
89
+ **2. Claude Desktop integration**
90
90
 
91
91
  Add Docker server configuration to Claude Desktop (Settings → Developers → Edit Config):
92
92
 
93
93
  ```json
94
94
  {
95
95
  "mcpServers": {
96
- "<your_server_name>": {
96
+ "figma-mcp-server": {
97
97
  "command": "docker",
98
- "args": ["run", "-i", "--rm", "--env-file=.env", "<your_server_name>"]
98
+ "args": ["run", "-i", "--rm", "--env-file=.env", "figma-mcp-server"]
99
99
  }
100
100
  }
101
101
  }
102
102
  ```
103
103
 
104
- > Add your environment variables (API keys, etc.) inside the `.env` file.
104
+ > Add your environment variables inside the `.env` file.
105
105
 
106
106
  #### Server-Sent Events (SSE)
107
107
 
108
108
  To run the server with Server-Sent Events (SSE) support, use the `--sse` flag:
109
109
 
110
- ```sh
110
+ ```bash
111
111
  node mcpServer.js --sse
112
112
  ```
package/mcpServer.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+
2
3
  import dotenv from "dotenv";
3
4
  import express from "express";
4
5
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -18,9 +19,13 @@ import { fileURLToPath } from "url";
18
19
  const __filename = fileURLToPath(import.meta.url);
19
20
  const __dirname = path.dirname(__filename);
20
21
 
22
+ // Load environment variables
21
23
  dotenv.config({ path: path.resolve(__dirname, ".env") });
22
24
 
23
- const SERVER_NAME = "generated-mcp-server";
25
+ // Server configuration
26
+ const SERVER_NAME = process.env.SERVER_NAME || "figma-mcp-server";
27
+ const SERVER_VERSION = process.env.SERVER_VERSION || "0.1.2";
28
+ const DEFAULT_PORT = 3001;
24
29
 
25
30
  async function transformTools(tools) {
26
31
  return tools
@@ -36,32 +41,7 @@ async function transformTools(tools) {
36
41
  .filter(Boolean);
37
42
  }
38
43
 
39
- async function run() {
40
- const args = process.argv.slice(2);
41
- const isSSE = args.includes("--sse");
42
-
43
- const server = new Server(
44
- {
45
- name: SERVER_NAME,
46
- version: "0.1.0",
47
- },
48
- {
49
- capabilities: {
50
- tools: {},
51
- },
52
- }
53
- );
54
-
55
- server.onerror = (error) => console.error("[Error]", error);
56
-
57
- // Gracefully shutdown on SIGINT
58
- process.on("SIGINT", async () => {
59
- await server.close();
60
- process.exit(0);
61
- });
62
-
63
- const tools = await discoverTools();
64
-
44
+ async function setupServerHandlers(server, tools) {
65
45
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
66
46
  tools: await transformTools(tools),
67
47
  }));
@@ -69,15 +49,12 @@ async function run() {
69
49
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
70
50
  const toolName = request.params.name;
71
51
  const tool = tools.find((t) => t.definition.function.name === toolName);
72
-
73
52
  if (!tool) {
74
53
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`);
75
54
  }
76
-
77
55
  const args = request.params.arguments;
78
56
  const requiredParameters =
79
57
  tool.definition?.function?.parameters?.required || [];
80
-
81
58
  for (const requiredParameter of requiredParameters) {
82
59
  if (!(requiredParameter in args)) {
83
60
  throw new McpError(
@@ -86,7 +63,6 @@ async function run() {
86
63
  );
87
64
  }
88
65
  }
89
-
90
66
  try {
91
67
  const result = await tool.function(args);
92
68
  return {
@@ -105,17 +81,42 @@ async function run() {
105
81
  );
106
82
  }
107
83
  });
84
+ }
85
+
86
+ async function run() {
87
+ const args = process.argv.slice(2);
88
+ const isSSE = args.includes("--sse");
89
+ const tools = await discoverTools();
108
90
 
109
91
  if (isSSE) {
110
92
  const app = express();
111
93
  const transports = {};
94
+ const servers = {};
112
95
 
113
96
  app.get("/sse", async (_req, res) => {
97
+ // Create a new Server instance for each session
98
+ const server = new Server(
99
+ {
100
+ name: SERVER_NAME,
101
+ version: SERVER_VERSION,
102
+ },
103
+ {
104
+ capabilities: {
105
+ tools: {},
106
+ },
107
+ }
108
+ );
109
+ server.onerror = (error) => console.error("[Error]", error);
110
+ await setupServerHandlers(server, tools);
111
+
114
112
  const transport = new SSEServerTransport("/messages", res);
115
113
  transports[transport.sessionId] = transport;
114
+ servers[transport.sessionId] = server;
116
115
 
117
- res.on("close", () => {
116
+ res.on("close", async () => {
118
117
  delete transports[transport.sessionId];
118
+ await server.close();
119
+ delete servers[transport.sessionId];
119
120
  });
120
121
 
121
122
  await server.connect(transport);
@@ -124,19 +125,42 @@ async function run() {
124
125
  app.post("/messages", async (req, res) => {
125
126
  const sessionId = req.query.sessionId;
126
127
  const transport = transports[sessionId];
128
+ const server = servers[sessionId];
127
129
 
128
- if (transport) {
130
+ if (transport && server) {
129
131
  await transport.handlePostMessage(req, res);
130
132
  } else {
131
- res.status(400).send("No transport found for sessionId");
133
+ res.status(400).send("No transport/server found for sessionId");
132
134
  }
133
135
  });
134
136
 
135
- const port = process.env.PORT || 3001;
137
+ const port = process.env.PORT || DEFAULT_PORT;
136
138
  app.listen(port, () => {
137
139
  console.log(`[SSE Server] running on port ${port}`);
140
+ console.log(`[Server] Name: ${SERVER_NAME}`);
141
+ console.log(`[Server] Version: ${SERVER_VERSION}`);
138
142
  });
139
143
  } else {
144
+ // stdio mode: single server instance
145
+ const server = new Server(
146
+ {
147
+ name: SERVER_NAME,
148
+ version: SERVER_VERSION,
149
+ },
150
+ {
151
+ capabilities: {
152
+ tools: {},
153
+ },
154
+ }
155
+ );
156
+ server.onerror = (error) => console.error("[Error]", error);
157
+ await setupServerHandlers(server, tools);
158
+
159
+ process.on("SIGINT", async () => {
160
+ await server.close();
161
+ process.exit(0);
162
+ });
163
+
140
164
  const transport = new StdioServerTransport();
141
165
  await server.connect(transport);
142
166
  }
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "figma-mcp-server",
3
- "version": "0.1.0",
4
- "description": "MCP server for Figma",
3
+ "version": "0.1.2",
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
- "@modelcontextprotocol/sdk": "^1.12.0",
12
+ "@modelcontextprotocol/sdk": "^1.12.1",
12
13
  "commander": "^14.0.0",
13
14
  "dotenv": "^16.5.0",
14
15
  "express": "^5.1.0"
package/smithery.yaml ADDED
@@ -0,0 +1,39 @@
1
+ startCommand:
2
+ type: http
3
+ command: node mcpServer.js --sse
4
+ configSchema:
5
+ type: object
6
+ required: ["port"]
7
+ properties:
8
+ port:
9
+ type: number
10
+ title: "Server Port"
11
+ description: "Port number for the MCP server"
12
+ default: 3001
13
+ mode:
14
+ type: string
15
+ title: "Server Mode"
16
+ description: "Choose between SSE (Server-Sent Events) or stdio mode"
17
+ enum: ["sse", "stdio"]
18
+ default: "sse"
19
+ serverName:
20
+ type: string
21
+ title: "Server Name"
22
+ description: "Name of the MCP server instance"
23
+ default: "generated-mcp-server"
24
+ version:
25
+ type: string
26
+ title: "Server Version"
27
+ description: "Version of the MCP server"
28
+ default: "0.1.2"
29
+
30
+ connection:
31
+ type: sse
32
+ configSchema:
33
+ type: object
34
+ properties:
35
+ baseUrl:
36
+ type: string
37
+ title: "Base URL"
38
+ description: "Base URL for the MCP server"
39
+ default: "http://localhost:3001"
@@ -0,0 +1,95 @@
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
+ const executeFunction = async ({ file_key, node_id, name, url }) => {
12
+ const baseUrl = 'https://api.figma.com';
13
+ const token = process.env.FIGMA_API_KEY;
14
+ try {
15
+ // Construct the URL for the API request
16
+ const url = `${baseUrl}/v1/files/${file_key}/dev_resources`;
17
+
18
+ // Set up headers for the request
19
+ const headers = {
20
+ 'X-Figma-Token': token,
21
+ 'Content-Type': 'application/json'
22
+ };
23
+
24
+ // Create the body for the request
25
+ const body = JSON.stringify({
26
+ dev_resources: [
27
+ {
28
+ name,
29
+ url,
30
+ file_key,
31
+ node_id
32
+ }
33
+ ]
34
+ });
35
+
36
+ // Perform the fetch request
37
+ const response = await fetch(url, {
38
+ method: 'POST',
39
+ headers,
40
+ body
41
+ });
42
+
43
+ // Check if the response was successful
44
+ if (!response.ok) {
45
+ const errorData = await response.json();
46
+ throw new Error(errorData);
47
+ }
48
+
49
+ // Parse and return the response data
50
+ const data = await response.json();
51
+ return data;
52
+ } catch (error) {
53
+ console.error('Error creating development resources:', error);
54
+ return { error: 'An error occurred while creating development resources.' };
55
+ }
56
+ };
57
+
58
+ /**
59
+ * Tool configuration for creating development resources for a Figma file.
60
+ * @type {Object}
61
+ */
62
+ const apiTool = {
63
+ function: executeFunction,
64
+ definition: {
65
+ type: 'function',
66
+ function: {
67
+ name: 'create_dev_resources',
68
+ description: 'Create development resources for a Figma file.',
69
+ parameters: {
70
+ type: 'object',
71
+ properties: {
72
+ file_key: {
73
+ type: 'string',
74
+ description: 'The key of the Figma file.'
75
+ },
76
+ node_id: {
77
+ type: 'string',
78
+ description: 'The node ID for the resource.'
79
+ },
80
+ name: {
81
+ type: 'string',
82
+ description: 'The name of the development resource.'
83
+ },
84
+ url: {
85
+ type: 'string',
86
+ description: 'The URL for the development resource.'
87
+ }
88
+ },
89
+ required: ['file_key', 'node_id', 'name', 'url']
90
+ }
91
+ }
92
+ }
93
+ };
94
+
95
+ export { apiTool };
@@ -1,18 +1,17 @@
1
1
  /**
2
- * Function to create a variable collection in Figma.
2
+ * Function to create variable collections for a Figma file.
3
3
  *
4
- * @param {Object} args - Arguments for creating the variable collection.
4
+ * @param {Object} args - Arguments for creating variable collections.
5
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 new variable collection to be created.
6
+ * @param {string} args.name - The name of the variable collection to create.
7
7
  * @returns {Promise<Object>} - The result of the variable collection creation.
8
8
  */
9
9
  const executeFunction = async ({ file_key, name }) => {
10
- const baseUrl = 'https://api.figma.com/v1';
10
+ const baseUrl = 'https://api.figma.com';
11
11
  const token = process.env.FIGMA_API_KEY;
12
-
13
12
  try {
14
13
  // Construct the URL for the request
15
- const url = `${baseUrl}/files/${file_key}/variables`;
14
+ const url = `${baseUrl}/v1/files/${file_key}/variables`;
16
15
 
17
16
  // Set up headers for the request
18
17
  const headers = {
@@ -20,7 +19,7 @@ const executeFunction = async ({ file_key, name }) => {
20
19
  'Content-Type': 'application/json'
21
20
  };
22
21
 
23
- // Create the request body
22
+ // Define the body of the request
24
23
  const body = JSON.stringify({
25
24
  variableCollections: [
26
25
  {
@@ -47,13 +46,13 @@ const executeFunction = async ({ file_key, name }) => {
47
46
  const data = await response.json();
48
47
  return data;
49
48
  } catch (error) {
50
- console.error('Error creating variable collection:', error);
51
- return { error: 'An error occurred while creating the variable collection.' };
49
+ console.error('Error creating variable collections:', error);
50
+ return { error: 'An error occurred while creating variable collections.' };
52
51
  }
53
52
  };
54
53
 
55
54
  /**
56
- * Tool configuration for creating a variable collection in Figma.
55
+ * Tool configuration for creating variable collections in a Figma file.
57
56
  * @type {Object}
58
57
  */
59
58
  const apiTool = {
@@ -61,8 +60,8 @@ const apiTool = {
61
60
  definition: {
62
61
  type: 'function',
63
62
  function: {
64
- name: 'create_variable_collection',
65
- description: 'Create a new variable collection in Figma.',
63
+ name: 'create_variable_collections',
64
+ description: 'Create variable collections for a Figma file.',
66
65
  parameters: {
67
66
  type: 'object',
68
67
  properties: {
@@ -72,7 +71,7 @@ const apiTool = {
72
71
  },
73
72
  name: {
74
73
  type: 'string',
75
- description: 'The name of the new variable collection to be created.'
74
+ description: 'The name of the variable collection to create.'
76
75
  }
77
76
  },
78
77
  required: ['file_key', 'name']
@@ -0,0 +1,66 @@
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
+ const executeFunction = async ({ key }) => {
9
+ const baseUrl = 'https://api.figma.com/v1/components';
10
+ const token = process.env.FIGMA_API_KEY;
11
+ try {
12
+ // Construct the URL with the component key
13
+ const url = `${baseUrl}/${key}`;
14
+
15
+ // Set up headers for the request
16
+ const headers = {
17
+ 'X-Figma-Token': token
18
+ };
19
+
20
+ // Perform the fetch request
21
+ const response = await fetch(url, {
22
+ method: 'GET',
23
+ headers
24
+ });
25
+
26
+ // Check if the response was successful
27
+ if (!response.ok) {
28
+ const errorData = await response.json();
29
+ throw new Error(errorData);
30
+ }
31
+
32
+ // Parse and return the response data
33
+ const data = await response.json();
34
+ return data;
35
+ } catch (error) {
36
+ console.error('Error retrieving component metadata:', error);
37
+ return { error: 'An error occurred while retrieving component metadata.' };
38
+ }
39
+ };
40
+
41
+ /**
42
+ * Tool configuration for retrieving component metadata from Figma.
43
+ * @type {Object}
44
+ */
45
+ const apiTool = {
46
+ function: executeFunction,
47
+ definition: {
48
+ type: 'function',
49
+ function: {
50
+ name: 'get_published_component_by_key',
51
+ description: 'Retrieve metadata for a published component by its key.',
52
+ parameters: {
53
+ type: 'object',
54
+ properties: {
55
+ key: {
56
+ type: 'string',
57
+ description: 'The key of the component to retrieve.'
58
+ }
59
+ },
60
+ required: ['key']
61
+ }
62
+ }
63
+ }
64
+ };
65
+
66
+ export { apiTool };