figmanage 1.3.8 → 1.4.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.
- package/README.md +164 -133
- package/dist/auth/client.d.ts +1 -0
- package/dist/auth/health.js +2 -1
- package/dist/cli/comments.js +79 -2
- package/dist/cli/components.js +66 -0
- package/dist/cli/compound-commands.js +2 -0
- package/dist/cli/org.js +143 -5
- package/dist/cli/teams.js +41 -1
- package/dist/cli/webhooks.js +20 -1
- package/dist/clients/internal-api.js +1 -1
- package/dist/clients/public-api.js +1 -1
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +10 -4
- package/dist/operations/comments.d.ts +25 -0
- package/dist/operations/comments.js +22 -0
- package/dist/operations/compound-manager.d.ts +1 -0
- package/dist/operations/compound-manager.js +17 -3
- package/dist/operations/dev-resources.d.ts +25 -0
- package/dist/operations/dev-resources.js +31 -0
- package/dist/operations/navigate.d.ts +5 -0
- package/dist/operations/navigate.js +20 -0
- package/dist/operations/org.d.ts +68 -1
- package/dist/operations/org.js +112 -1
- package/dist/operations/teams.d.ts +9 -0
- package/dist/operations/teams.js +23 -0
- package/dist/operations/webhooks.d.ts +14 -0
- package/dist/operations/webhooks.js +12 -0
- package/dist/tools/analytics.js +2 -0
- package/dist/tools/comments.js +99 -3
- package/dist/tools/compound-manager.js +7 -2
- package/dist/tools/compound.js +3 -0
- package/dist/tools/dev-resources.d.ts +2 -0
- package/dist/tools/dev-resources.js +78 -0
- package/dist/tools/org.js +203 -8
- package/dist/tools/permissions.js +3 -0
- package/dist/tools/register.d.ts +2 -1
- package/dist/tools/register.js +4 -1
- package/dist/tools/teams.js +53 -1
- package/dist/tools/webhooks.js +25 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,27 +1,55 @@
|
|
|
1
1
|
# figmanage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Let agents manage your Figma workspace. Seats, teams, permissions, billing, offboarding, cleanup -- handled in conversation instead of clicking through admin panels.
|
|
4
|
+
|
|
5
|
+
Every Figma MCP is design-to-code. figmanage is the management layer: 102 tools that let agents operate on the workspace itself. Works with Claude Code, Cursor, OpenClaw, or as a standalone CLI.
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/figmanage)
|
|
6
8
|
[](https://www.npmjs.com/package/figmanage)
|
|
7
|
-
[](https://github.com/dannykeane/figmanage)
|
|
8
10
|
[](LICENSE)
|
|
9
11
|
[](https://mcp-marketplace.io/server/io-github-dannykeane-figmanage)
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
## examples
|
|
14
|
+
|
|
15
|
+
### workspace management (admins)
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
"which paid seats haven't been active in 30 days? how much would we save?"
|
|
19
|
+
|
|
20
|
+
"offboard sarah@company.com -- show me everything she owns, then transfer it
|
|
21
|
+
to jake and remove her from the org"
|
|
22
|
+
|
|
23
|
+
"set up a new hire: invite alex@company.com to Design and Engineering as an editor"
|
|
24
|
+
|
|
25
|
+
"create a user group called Platform Design and add the three designers"
|
|
26
|
+
|
|
27
|
+
"run a quarterly design ops report for the org"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### everyday design work (everyone)
|
|
31
|
+
|
|
13
32
|
```
|
|
33
|
+
"clean up the Mobile App project -- find stale files and archive dead branches"
|
|
34
|
+
|
|
35
|
+
"what are the unresolved comments across the Platform project?"
|
|
36
|
+
|
|
37
|
+
"export all the icons from the Design System file as SVGs"
|
|
14
38
|
|
|
15
|
-
|
|
39
|
+
"move the Q4 files into the Archive project"
|
|
40
|
+
|
|
41
|
+
"share the Homepage mockup with alex@company.com and set link access to view-only"
|
|
42
|
+
|
|
43
|
+
"summarize the Brand Guidelines file -- pages, components, styles"
|
|
44
|
+
```
|
|
16
45
|
|
|
17
|
-
|
|
46
|
+
## install
|
|
18
47
|
|
|
19
48
|
```bash
|
|
20
49
|
# Claude Code
|
|
21
50
|
claude mcp add figmanage -- npx -y figmanage
|
|
22
51
|
|
|
23
52
|
# Cursor / OpenClaw / other MCP clients
|
|
24
|
-
# Add to your MCP config:
|
|
25
53
|
{
|
|
26
54
|
"mcpServers": {
|
|
27
55
|
"figmanage": {
|
|
@@ -32,97 +60,83 @@ claude mcp add figmanage -- npx -y figmanage
|
|
|
32
60
|
}
|
|
33
61
|
```
|
|
34
62
|
|
|
35
|
-
On first run, figmanage walks you through setup
|
|
63
|
+
On first run, figmanage walks you through setup in the conversation -- extracts your Chrome session cookie, asks you to create a PAT, stores credentials locally. No env vars, no JSON editing.
|
|
36
64
|
|
|
37
|
-
|
|
65
|
+
Also works as a CLI:
|
|
38
66
|
|
|
67
|
+
```bash
|
|
68
|
+
npm install -g figmanage
|
|
69
|
+
figmanage login
|
|
39
70
|
```
|
|
40
|
-
"which paid seats haven't been active in 30 days? how much would we save?"
|
|
41
71
|
|
|
42
|
-
|
|
72
|
+
## how it works
|
|
43
73
|
|
|
44
|
-
|
|
74
|
+
Figma's public REST API covers design files but nothing on the management side -- no seats, no teams, no permissions, no billing. figmanage uses both APIs:
|
|
45
75
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
76
|
+
| API | Auth | What it covers |
|
|
77
|
+
|-----|------|---------------|
|
|
78
|
+
| Internal | Session cookie | Seats, teams, permissions, billing, user groups, org admin, search |
|
|
79
|
+
| Public | Personal Access Token | Files, comments, export, components, versions, webhooks, variables |
|
|
49
80
|
|
|
50
|
-
|
|
51
|
-
```
|
|
81
|
+
Both together unlock all 102 tools. Cookie-only or PAT-only works but limits available tools.
|
|
52
82
|
|
|
53
|
-
|
|
83
|
+
**Admin auto-detection.** At startup, figmanage checks whether you're an org admin. Admins see all 102 tools. Non-admins see 68 -- everything except org management, seat changes, billing, user groups, and offboarding. No configuration needed.
|
|
54
84
|
|
|
55
|
-
Use `FIGMA_TOOLSETS` to expose only specific tool groups:
|
|
85
|
+
**Toolset presets.** Use `FIGMA_TOOLSETS` to expose only specific tool groups:
|
|
56
86
|
|
|
57
|
-
| Preset |
|
|
58
|
-
|
|
87
|
+
| Preset | What's included |
|
|
88
|
+
|--------|----------------|
|
|
59
89
|
| `starter` | navigate, reading, comments, export |
|
|
60
90
|
| `admin` | navigate, org, permissions, analytics, teams, libraries |
|
|
61
91
|
| `readonly` | navigate, reading, comments, export, components, versions |
|
|
62
92
|
| `full` | everything (default) |
|
|
63
93
|
|
|
64
|
-
##
|
|
94
|
+
## CLI
|
|
65
95
|
|
|
66
|
-
|
|
96
|
+
Commands use a noun-verb pattern: `figmanage <group> <action>`.
|
|
67
97
|
|
|
68
98
|
```bash
|
|
69
99
|
figmanage org seat-optimization # find inactive paid seats
|
|
70
100
|
figmanage org offboard sarah@co.com # audit what a user owns
|
|
71
101
|
figmanage org offboard sarah@co.com --execute \
|
|
72
|
-
--transfer-to jake@co.com #
|
|
102
|
+
--transfer-to jake@co.com # soft offboard
|
|
103
|
+
figmanage org offboard sarah@co.com --execute \
|
|
104
|
+
--transfer-to jake@co.com --remove-from-org # hard offboard (permanent)
|
|
73
105
|
figmanage org onboard alex@co.com --teams 123,456 \
|
|
74
106
|
--role editor --seat full --confirm # set up a new hire
|
|
75
107
|
figmanage org quarterly-report # org-wide design ops snapshot
|
|
76
108
|
figmanage org members --search danny # find org members
|
|
77
|
-
figmanage navigate list-teams # list all teams
|
|
78
|
-
figmanage permissions get file abc123 # who has access to a file
|
|
79
109
|
figmanage permissions audit --scope team --id 789 # audit a team's permissions
|
|
80
110
|
figmanage branches cleanup 573408414 # find stale branches
|
|
81
|
-
figmanage files summary abc123 # pages, components, styles overview
|
|
82
111
|
```
|
|
83
112
|
|
|
84
|
-
|
|
113
|
+
All commands output JSON when piped or when `--json` is passed. Run `figmanage <group> --help` for subcommands.
|
|
85
114
|
|
|
86
115
|
## setup
|
|
87
116
|
|
|
88
117
|
Log into figma.com in Chrome, then:
|
|
89
118
|
|
|
90
119
|
```bash
|
|
91
|
-
figmanage login
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Extracts your Chrome session cookie, prompts for a PAT, and stores credentials locally at `~/.config/figmanage/`. One-time setup -- no env vars, no JSON config editing.
|
|
95
|
-
|
|
96
|
-
```bash
|
|
120
|
+
figmanage login # extract cookie, create PAT, store credentials
|
|
97
121
|
figmanage whoami # verify auth
|
|
98
122
|
figmanage logout # clear credentials
|
|
99
123
|
```
|
|
100
124
|
|
|
101
|
-
|
|
125
|
+
Credentials stored at `~/.config/figmanage/` with 0o600 permissions.
|
|
102
126
|
|
|
103
|
-
Env vars (`FIGMA_PAT`, `FIGMA_AUTH_COOKIE`, etc.) override the config file
|
|
127
|
+
Env vars (`FIGMA_PAT`, `FIGMA_AUTH_COOKIE`, etc.) override the config file. HTTP transport available via `--mcp --http <port>`.
|
|
104
128
|
|
|
105
|
-
##
|
|
129
|
+
## tool reference
|
|
106
130
|
|
|
107
|
-
|
|
131
|
+
<details>
|
|
132
|
+
<summary>All 102 tools across 17 groups (click to expand)</summary>
|
|
108
133
|
|
|
109
|
-
|
|
110
|
-
|--------|------|-------------|
|
|
111
|
-
| Internal API | Session cookie | Workspace management, search, permissions, org admin, seats, billing |
|
|
112
|
-
| Public API | Personal Access Token | Comments, export, file reading, components, versions, webhooks, variables |
|
|
113
|
-
|
|
114
|
-
Both together give full access to all 85 tools. Cookie-only or PAT-only work but limit available tools.
|
|
115
|
-
|
|
116
|
-
Auth resolution: env vars > config file > interactive setup (MCP) or `figmanage login` (CLI).
|
|
117
|
-
|
|
118
|
-
## commands
|
|
119
|
-
|
|
120
|
-
The tables below list all 85 commands. The Command column shows MCP tool names (snake_case). The CLI equivalent is the noun-verb form: `figmanage <group> <action>` where `<action>` is the kebab-case version of the tool name without the group prefix (e.g. `list_recent_files` becomes `figmanage navigate list-recent-files`).
|
|
134
|
+
The tables below show MCP tool names (snake_case). CLI equivalents use kebab-case: `list_recent_files` becomes `figmanage navigate list-recent-files`.
|
|
121
135
|
|
|
122
136
|
### navigate (10)
|
|
123
137
|
|
|
124
|
-
|
|
|
125
|
-
|
|
138
|
+
| Tool | Auth | Description |
|
|
139
|
+
|------|------|-------------|
|
|
126
140
|
| `check_auth` | either | Validate PAT and cookie authentication |
|
|
127
141
|
| `list_orgs` | cookie | List available Figma workspaces |
|
|
128
142
|
| `switch_org` | cookie | Switch active workspace for this session |
|
|
@@ -136,8 +150,8 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
136
150
|
|
|
137
151
|
### files (10)
|
|
138
152
|
|
|
139
|
-
|
|
|
140
|
-
|
|
153
|
+
| Tool | Auth | Description |
|
|
154
|
+
|------|------|-------------|
|
|
141
155
|
| `create_file` | cookie | Create design, whiteboard, slides, or sites file |
|
|
142
156
|
| `rename_file` | cookie | Rename a file |
|
|
143
157
|
| `move_files` | cookie | Move files between projects (batch) |
|
|
@@ -151,8 +165,8 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
151
165
|
|
|
152
166
|
### projects (8)
|
|
153
167
|
|
|
154
|
-
|
|
|
155
|
-
|
|
168
|
+
| Tool | Auth | Description |
|
|
169
|
+
|------|------|-------------|
|
|
156
170
|
| `create_project` | cookie | Create a project in a team |
|
|
157
171
|
| `rename_project` | cookie | Rename a project |
|
|
158
172
|
| `move_project` | cookie | Move a project to another team |
|
|
@@ -164,8 +178,8 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
164
178
|
|
|
165
179
|
### permissions (8)
|
|
166
180
|
|
|
167
|
-
|
|
|
168
|
-
|
|
181
|
+
| Tool | Auth | Description |
|
|
182
|
+
|------|------|-------------|
|
|
169
183
|
| `get_permissions` | cookie | List who has access with roles |
|
|
170
184
|
| `set_permissions` | cookie | Change a user's access level |
|
|
171
185
|
| `share` | cookie | Invite someone by email |
|
|
@@ -175,127 +189,146 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
175
189
|
| `deny_role_request` | cookie | Decline an access request |
|
|
176
190
|
| `permission_audit` | cookie | Team/project access audit with oversharing flags |
|
|
177
191
|
|
|
192
|
+
### org (24, admin-only)
|
|
193
|
+
|
|
194
|
+
| Tool | Auth | Description |
|
|
195
|
+
|------|------|-------------|
|
|
196
|
+
| `list_admins` | cookie | Org admins with permission levels |
|
|
197
|
+
| `list_org_teams` | cookie | All teams with member and project counts |
|
|
198
|
+
| `seat_usage` | cookie | Seat breakdown by type and activity |
|
|
199
|
+
| `list_team_members` | cookie | Team members with roles and activity |
|
|
200
|
+
| `list_org_members` | cookie | All org members with seats and activity |
|
|
201
|
+
| `contract_rates` | cookie | Per-seat pricing |
|
|
202
|
+
| `change_seat` | cookie | Change a user's seat type |
|
|
203
|
+
| `billing_overview` | cookie | Invoice history and billing status |
|
|
204
|
+
| `list_invoices` | cookie | Open and upcoming invoices |
|
|
205
|
+
| `list_payments` | cookie | Paid invoices / payment history |
|
|
206
|
+
| `org_domains` | cookie | Domain config and SSO/SAML |
|
|
207
|
+
| `ai_credit_usage` | cookie | AI credit usage (resolves plan from team) |
|
|
208
|
+
| `export_members` | cookie | Trigger CSV export of all members |
|
|
209
|
+
| `activity_log` | cookie | Org audit log with email filtering and pagination |
|
|
210
|
+
| `create_user_group` | cookie | Create a user group |
|
|
211
|
+
| `delete_user_groups` | cookie | Delete user groups |
|
|
212
|
+
| `add_user_group_members` | cookie | Add members to a user group by email |
|
|
213
|
+
| `remove_user_group_members` | cookie | Remove members from a user group |
|
|
214
|
+
| `remove_org_member` | cookie | Permanently remove a member from the org |
|
|
215
|
+
| `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
|
|
216
|
+
| `seat_optimization` | cookie | Inactive seat detection with cost analysis |
|
|
217
|
+
| `offboard_user` | cookie | Audit + execute user departure (soft or hard) |
|
|
218
|
+
| `onboard_user` | cookie | Batch invite to teams, share files, set seat |
|
|
219
|
+
| `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
|
|
220
|
+
|
|
221
|
+
### teams (5, admin-only)
|
|
222
|
+
|
|
223
|
+
| Tool | Auth | Description |
|
|
224
|
+
|------|------|-------------|
|
|
225
|
+
| `create_team` | cookie | Create a team |
|
|
226
|
+
| `rename_team` | cookie | Rename a team |
|
|
227
|
+
| `delete_team` | cookie | Delete a team |
|
|
228
|
+
| `add_team_member` | cookie | Add a member by email |
|
|
229
|
+
| `remove_team_member` | cookie | Remove a member |
|
|
230
|
+
|
|
231
|
+
### analytics (2, admin-only)
|
|
232
|
+
|
|
233
|
+
| Tool | Auth | Description |
|
|
234
|
+
|------|------|-------------|
|
|
235
|
+
| `library_usage` | cookie | Team-level library adoption metrics |
|
|
236
|
+
| `component_usage` | cookie | Per-file component usage |
|
|
237
|
+
|
|
238
|
+
### comments (9)
|
|
239
|
+
|
|
240
|
+
| Tool | Auth | Description |
|
|
241
|
+
|------|------|-------------|
|
|
242
|
+
| `list_comments` | pat | Comments with thread structure |
|
|
243
|
+
| `post_comment` | pat | Post a comment |
|
|
244
|
+
| `delete_comment` | pat | Delete a comment |
|
|
245
|
+
| `resolve_comment` | cookie | Resolve or unresolve a comment thread |
|
|
246
|
+
| `edit_comment` | cookie | Edit the text of an existing comment |
|
|
247
|
+
| `list_comment_reactions` | pat | Emoji reactions on a comment |
|
|
248
|
+
| `add_comment_reaction` | pat | Add an emoji reaction |
|
|
249
|
+
| `remove_comment_reaction` | pat | Remove an emoji reaction |
|
|
250
|
+
| `open_comments` | pat | Unresolved comments across a project |
|
|
251
|
+
|
|
178
252
|
### versions (2)
|
|
179
253
|
|
|
180
|
-
|
|
|
181
|
-
|
|
254
|
+
| Tool | Auth | Description |
|
|
255
|
+
|------|------|-------------|
|
|
182
256
|
| `list_versions` | pat | Version history |
|
|
183
257
|
| `create_version` | cookie | Create a named version checkpoint |
|
|
184
258
|
|
|
185
259
|
### branches (4)
|
|
186
260
|
|
|
187
|
-
|
|
|
188
|
-
|
|
261
|
+
| Tool | Auth | Description |
|
|
262
|
+
|------|------|-------------|
|
|
189
263
|
| `list_branches` | either | List branches of a file |
|
|
190
264
|
| `create_branch` | cookie | Create a branch |
|
|
191
265
|
| `delete_branch` | cookie | Archive a branch |
|
|
192
266
|
| `branch_cleanup` | either | Stale branch detection with optional archival |
|
|
193
267
|
|
|
194
|
-
###
|
|
268
|
+
### reading (2)
|
|
195
269
|
|
|
196
|
-
|
|
|
197
|
-
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `delete_comment` | pat | Delete a comment |
|
|
201
|
-
| `list_comment_reactions` | pat | Emoji reactions on a comment |
|
|
202
|
-
| `open_comments` | pat | Unresolved comments across a project |
|
|
270
|
+
| Tool | Auth | Description |
|
|
271
|
+
|------|------|-------------|
|
|
272
|
+
| `get_file` | pat | Read file as a node tree with depth control |
|
|
273
|
+
| `get_nodes` | pat | Read specific nodes by ID |
|
|
203
274
|
|
|
204
275
|
### export (2)
|
|
205
276
|
|
|
206
|
-
|
|
|
207
|
-
|
|
277
|
+
| Tool | Auth | Description |
|
|
278
|
+
|------|------|-------------|
|
|
208
279
|
| `export_nodes` | pat | Export as PNG, SVG, PDF, or JPG |
|
|
209
280
|
| `get_image_fills` | pat | URLs for all images used as fills |
|
|
210
281
|
|
|
211
|
-
###
|
|
212
|
-
|
|
213
|
-
| Command | Auth | Description |
|
|
214
|
-
|---------|------|-------------|
|
|
215
|
-
| `get_file` | pat | Read file as a node tree with depth control |
|
|
216
|
-
| `get_nodes` | pat | Read specific nodes by ID |
|
|
282
|
+
### components (7)
|
|
217
283
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
| Command | Auth | Description |
|
|
221
|
-
|---------|------|-------------|
|
|
284
|
+
| Tool | Auth | Description |
|
|
285
|
+
|------|------|-------------|
|
|
222
286
|
| `list_file_components` | pat | Components published from a file |
|
|
223
287
|
| `list_file_styles` | pat | Styles in a file |
|
|
224
288
|
| `list_team_components` | pat | Published components across a team |
|
|
225
289
|
| `list_team_styles` | pat | Published styles across a team |
|
|
290
|
+
| `list_dev_resources` | pat | Dev resources (links, annotations) on a file |
|
|
291
|
+
| `create_dev_resource` | pat | Attach a dev resource to a node |
|
|
292
|
+
| `delete_dev_resource` | pat | Remove a dev resource |
|
|
226
293
|
|
|
227
|
-
### webhooks (
|
|
294
|
+
### webhooks (5)
|
|
228
295
|
|
|
229
|
-
|
|
|
230
|
-
|
|
296
|
+
| Tool | Auth | Description |
|
|
297
|
+
|------|------|-------------|
|
|
231
298
|
| `list_webhooks` | pat | List webhooks for a team |
|
|
232
299
|
| `create_webhook` | pat | Create a webhook subscription |
|
|
233
300
|
| `update_webhook` | pat | Update a webhook |
|
|
234
301
|
| `delete_webhook` | pat | Delete a webhook |
|
|
302
|
+
| `webhook_requests` | pat | Delivery history (last 7 days) |
|
|
235
303
|
|
|
236
304
|
### variables (3, Enterprise)
|
|
237
305
|
|
|
238
|
-
|
|
|
239
|
-
|
|
306
|
+
| Tool | Auth | Description |
|
|
307
|
+
|------|------|-------------|
|
|
240
308
|
| `list_local_variables` | pat | Local variables and collections |
|
|
241
309
|
| `list_published_variables` | pat | Published variables from a library |
|
|
242
310
|
| `update_variables` | pat | Bulk create, update, or delete variables |
|
|
243
311
|
|
|
244
|
-
### analytics (2)
|
|
245
|
-
|
|
246
|
-
| Command | Auth | Description |
|
|
247
|
-
|---------|------|-------------|
|
|
248
|
-
| `library_usage` | cookie | Team-level library adoption metrics |
|
|
249
|
-
| `component_usage` | cookie | Per-file component usage |
|
|
250
|
-
|
|
251
|
-
### org (17)
|
|
252
|
-
|
|
253
|
-
| Command | Auth | Description |
|
|
254
|
-
|---------|------|-------------|
|
|
255
|
-
| `list_admins` | cookie | Org admins with permission levels |
|
|
256
|
-
| `list_org_teams` | cookie | All teams with member and project counts |
|
|
257
|
-
| `seat_usage` | cookie | Seat breakdown by type and activity |
|
|
258
|
-
| `list_team_members` | cookie | Team members with roles and activity |
|
|
259
|
-
| `list_org_members` | cookie | All org members with seats and activity |
|
|
260
|
-
| `contract_rates` | cookie | Per-seat pricing |
|
|
261
|
-
| `change_seat` | cookie | Change a user's seat type |
|
|
262
|
-
| `billing_overview` | cookie | Invoice history and billing status |
|
|
263
|
-
| `list_invoices` | cookie | Open and upcoming invoices |
|
|
264
|
-
| `org_domains` | cookie | Domain config and SSO/SAML |
|
|
265
|
-
| `ai_credit_usage` | cookie | AI credit usage summary |
|
|
266
|
-
| `export_members` | cookie | Trigger CSV export of all members |
|
|
267
|
-
| `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
|
|
268
|
-
| `seat_optimization` | cookie | Inactive seat detection with cost analysis |
|
|
269
|
-
| `offboard_user` | cookie | Audit + execute user departure |
|
|
270
|
-
| `onboard_user` | cookie | Batch invite to teams, share files, set seat |
|
|
271
|
-
| `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
|
|
272
|
-
|
|
273
312
|
### libraries (1)
|
|
274
313
|
|
|
275
|
-
|
|
|
276
|
-
|
|
314
|
+
| Tool | Auth | Description |
|
|
315
|
+
|------|------|-------------|
|
|
277
316
|
| `list_org_libraries` | cookie | Design system libraries with sharing info |
|
|
278
317
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
| Command | Auth | Description |
|
|
282
|
-
|---------|------|-------------|
|
|
283
|
-
| `create_team` | cookie | Create a team |
|
|
284
|
-
| `rename_team` | cookie | Rename a team |
|
|
285
|
-
| `delete_team` | cookie | Delete a team |
|
|
318
|
+
</details>
|
|
286
319
|
|
|
287
320
|
## security
|
|
288
321
|
|
|
289
|
-
All parameters
|
|
322
|
+
All ID parameters validated against `/^[\w.:-]+$/`. Rate limit retries restricted to safe HTTP methods -- mutations never retried. Billing responses strip PII. Destructive operations default to dry-run mode. Org removal requires explicit double-confirmation. Config file stored with 0o600 permissions.
|
|
290
323
|
|
|
291
324
|
## known limitations
|
|
292
325
|
|
|
293
326
|
- **list_favorites**: Figma BigInt overflow bug on their server. `favorite_file` works fine.
|
|
294
|
-
- **Branch merging**:
|
|
327
|
+
- **Branch merging / version restore**: Require Figma's multiplayer protocol, no REST endpoint.
|
|
295
328
|
- **Cookie expiry**: ~30 days. Run `figmanage login --refresh` to renew.
|
|
296
329
|
- **Windows cookies**: Best-effort DPAPI extraction. Falls back to PAT-only.
|
|
297
330
|
- **Variables**: Enterprise-gated scopes.
|
|
298
|
-
- **
|
|
331
|
+
- **User groups**: Write-only (create, delete, add/remove members). No list endpoint -- Figma renders the page server-side.
|
|
299
332
|
|
|
300
333
|
## development
|
|
301
334
|
|
|
@@ -307,18 +340,16 @@ npm run build
|
|
|
307
340
|
npm test
|
|
308
341
|
```
|
|
309
342
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
Three-layer design: shared operations power both the CLI and MCP server.
|
|
343
|
+
Three-layer architecture: operations hold all business logic, tools and CLI are thin wrappers.
|
|
313
344
|
|
|
314
345
|
```
|
|
315
346
|
src/
|
|
316
347
|
index.ts Entry: --setup, --mcp, or CLI mode
|
|
317
|
-
mcp.ts MCP server setup, toolset presets
|
|
348
|
+
mcp.ts MCP server setup, admin detection, toolset presets
|
|
318
349
|
setup.ts Cross-platform Chrome cookie extraction
|
|
319
350
|
auth/ AuthConfig from env vars and config file
|
|
320
351
|
clients/ Axios clients for internal (cookie) and public (PAT) APIs
|
|
321
|
-
operations/ Shared business logic (
|
|
352
|
+
operations/ Shared business logic (19 modules)
|
|
322
353
|
tools/ MCP tool wrappers (thin, call operations)
|
|
323
354
|
cli/ CLI Commander wrappers (thin, call operations)
|
|
324
355
|
types/figma.ts Shared types including Toolset union
|
package/dist/auth/client.d.ts
CHANGED
package/dist/auth/health.js
CHANGED
|
@@ -73,7 +73,8 @@ export function formatAuthStatus(status, config) {
|
|
|
73
73
|
if (config.orgId) {
|
|
74
74
|
const currentOrg = config.orgs?.find(o => o.id === config.orgId);
|
|
75
75
|
const orgLabel = currentOrg ? `${currentOrg.name} (${config.orgId})` : config.orgId;
|
|
76
|
-
|
|
76
|
+
const role = config.isAdmin ? 'admin' : 'member';
|
|
77
|
+
lines.push(`\nWorkspace: ${orgLabel} (${role})`);
|
|
77
78
|
const others = (config.orgs || []).filter(o => o.id !== config.orgId);
|
|
78
79
|
if (others.length > 0) {
|
|
79
80
|
lines.push(`Other workspaces: ${others.map(o => `${o.name} (${o.id})`).join(', ')}`);
|
package/dist/cli/comments.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { listComments, formatCommentsAsMarkdown, postComment, deleteComment, listCommentReactions, } from '../operations/comments.js';
|
|
2
|
+
import { listComments, formatCommentsAsMarkdown, postComment, deleteComment, resolveComment, editComment, addCommentReaction, removeCommentReaction, listCommentReactions, } from '../operations/comments.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
4
|
import { formatApiError } from '../helpers.js';
|
|
5
|
-
import { requirePat } from './helpers.js';
|
|
5
|
+
import { requirePat, requireCookie } from './helpers.js';
|
|
6
6
|
export function commentsCommand() {
|
|
7
7
|
const comments = new Command('comments')
|
|
8
8
|
.description('Manage file comments');
|
|
@@ -87,6 +87,83 @@ export function commentsCommand() {
|
|
|
87
87
|
process.exit(1);
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
|
+
comments
|
|
91
|
+
.command('resolve <file-key> <comment-id>')
|
|
92
|
+
.description('Resolve a comment thread')
|
|
93
|
+
.option('--unresolve', 'Unresolve instead of resolve')
|
|
94
|
+
.option('--json', 'Force JSON output')
|
|
95
|
+
.action(async (fileKey, commentId, options) => {
|
|
96
|
+
try {
|
|
97
|
+
const config = requireCookie();
|
|
98
|
+
const msg = await resolveComment(config, {
|
|
99
|
+
file_key: fileKey,
|
|
100
|
+
comment_id: commentId,
|
|
101
|
+
resolved: !options.unresolve,
|
|
102
|
+
});
|
|
103
|
+
output({ message: msg }, options);
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
error(formatApiError(e));
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
comments
|
|
111
|
+
.command('edit <file-key> <comment-id> <message>')
|
|
112
|
+
.description('Edit the text of an existing comment')
|
|
113
|
+
.option('--json', 'Force JSON output')
|
|
114
|
+
.action(async (fileKey, commentId, message, options) => {
|
|
115
|
+
try {
|
|
116
|
+
const config = requireCookie();
|
|
117
|
+
const msg = await editComment(config, {
|
|
118
|
+
file_key: fileKey,
|
|
119
|
+
comment_id: commentId,
|
|
120
|
+
message,
|
|
121
|
+
});
|
|
122
|
+
output({ message: msg }, options);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
error(formatApiError(e));
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
comments
|
|
130
|
+
.command('react <file-key> <comment-id> <emoji>')
|
|
131
|
+
.description('Add an emoji reaction to a comment')
|
|
132
|
+
.option('--json', 'Force JSON output')
|
|
133
|
+
.action(async (fileKey, commentId, emoji, options) => {
|
|
134
|
+
try {
|
|
135
|
+
const config = requirePat();
|
|
136
|
+
const result = await addCommentReaction(config, {
|
|
137
|
+
file_key: fileKey,
|
|
138
|
+
comment_id: commentId,
|
|
139
|
+
emoji,
|
|
140
|
+
});
|
|
141
|
+
output(result, options);
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
error(formatApiError(e));
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
comments
|
|
149
|
+
.command('unreact <file-key> <comment-id> <emoji>')
|
|
150
|
+
.description('Remove an emoji reaction from a comment')
|
|
151
|
+
.option('--json', 'Force JSON output')
|
|
152
|
+
.action(async (fileKey, commentId, emoji, options) => {
|
|
153
|
+
try {
|
|
154
|
+
const config = requirePat();
|
|
155
|
+
await removeCommentReaction(config, {
|
|
156
|
+
file_key: fileKey,
|
|
157
|
+
comment_id: commentId,
|
|
158
|
+
emoji,
|
|
159
|
+
});
|
|
160
|
+
output({ removed: emoji, comment_id: commentId }, options);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
error(formatApiError(e));
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
90
167
|
return comments;
|
|
91
168
|
}
|
|
92
169
|
//# sourceMappingURL=comments.js.map
|
package/dist/cli/components.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { listFileComponents, listFileStyles, listTeamComponents, listTeamStyles, } from '../operations/components.js';
|
|
3
|
+
import { listDevResources, createDevResource, deleteDevResource, } from '../operations/dev-resources.js';
|
|
3
4
|
import { output, error } from './format.js';
|
|
4
5
|
import { formatApiError } from '../helpers.js';
|
|
5
6
|
import { requirePat } from './helpers.js';
|
|
@@ -94,6 +95,71 @@ export function componentsCommand() {
|
|
|
94
95
|
process.exit(1);
|
|
95
96
|
}
|
|
96
97
|
});
|
|
98
|
+
components
|
|
99
|
+
.command('list-dev-resources <file-key>')
|
|
100
|
+
.description('List dev resources (links, annotations) on a file')
|
|
101
|
+
.option('--node-ids <ids>', 'Comma-separated node IDs to filter')
|
|
102
|
+
.option('--json', 'Force JSON output')
|
|
103
|
+
.action(async (fileKey, options) => {
|
|
104
|
+
try {
|
|
105
|
+
const config = requirePat();
|
|
106
|
+
const result = await listDevResources(config, {
|
|
107
|
+
file_key: fileKey,
|
|
108
|
+
node_ids: options.nodeIds?.split(','),
|
|
109
|
+
});
|
|
110
|
+
if (result.length === 0) {
|
|
111
|
+
console.log('No dev resources found.');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
output(result, options);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
error(formatApiError(e));
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
components
|
|
122
|
+
.command('create-dev-resource <file-key> <node-id>')
|
|
123
|
+
.description('Create a dev resource on a node')
|
|
124
|
+
.requiredOption('--name <name>', 'Resource name/label')
|
|
125
|
+
.requiredOption('--url <url>', 'Resource URL')
|
|
126
|
+
.option('--json', 'Force JSON output')
|
|
127
|
+
.action(async (fileKey, nodeId, options) => {
|
|
128
|
+
try {
|
|
129
|
+
const config = requirePat();
|
|
130
|
+
const result = await createDevResource(config, {
|
|
131
|
+
file_key: fileKey,
|
|
132
|
+
node_id: nodeId,
|
|
133
|
+
name: options.name,
|
|
134
|
+
url: options.url,
|
|
135
|
+
});
|
|
136
|
+
output(result, options);
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
error(formatApiError(e));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
components
|
|
144
|
+
.command('delete-dev-resource <file-key> <dev-resource-id>')
|
|
145
|
+
.description('Delete a dev resource')
|
|
146
|
+
.option('--json', 'Force JSON output')
|
|
147
|
+
.action(async (fileKey, devResourceId, options) => {
|
|
148
|
+
try {
|
|
149
|
+
const config = requirePat();
|
|
150
|
+
const { confirmAction } = await import('./helpers.js');
|
|
151
|
+
if (!await confirmAction(`Delete dev resource ${devResourceId}?`)) {
|
|
152
|
+
console.log('Cancelled.');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
await deleteDevResource(config, { file_key: fileKey, dev_resource_id: devResourceId });
|
|
156
|
+
output({ deleted: devResourceId }, options);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
error(formatApiError(e));
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
97
163
|
return components;
|
|
98
164
|
}
|
|
99
165
|
//# sourceMappingURL=components.js.map
|
|
@@ -219,6 +219,7 @@ export function offboardUserCommand() {
|
|
|
219
219
|
.argument('<user>', 'Email or user_id to offboard')
|
|
220
220
|
.option('--execute', 'Execute the offboarding (default: audit only)')
|
|
221
221
|
.option('--transfer-to <user>', 'Email or user_id to transfer file ownership to')
|
|
222
|
+
.option('--remove-from-org', 'Permanently remove from org after offboarding (cannot be undone)')
|
|
222
223
|
.option('--json', 'Force JSON output')
|
|
223
224
|
.action(async (user, options) => {
|
|
224
225
|
try {
|
|
@@ -227,6 +228,7 @@ export function offboardUserCommand() {
|
|
|
227
228
|
user_identifier: user,
|
|
228
229
|
execute: options.execute === true,
|
|
229
230
|
transfer_to: options.transferTo,
|
|
231
|
+
remove_from_org: options.removeFromOrg === true,
|
|
230
232
|
});
|
|
231
233
|
output(result, options);
|
|
232
234
|
}
|