figmanage 0.2.1 → 1.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.
package/README.md CHANGED
@@ -1,144 +1,127 @@
1
1
  # figmanage
2
2
 
3
- MCP server for managing your Figma workspace.
3
+ Figma workspace management from the command line. 85 commands for seats, teams, permissions, billing, onboarding, and org admin. Also works as an MCP server for AI assistants.
4
4
 
5
- Manages Figma workspaces through AI assistants. 79 tools covering files, projects, teams, permissions, comments, versions, components, webhooks, org admin, and more. Works with Claude Code, Claude Desktop, ChatGPT, and any MCP-compatible client.
5
+ ## install
6
6
 
7
- ## quick start
8
-
9
- ### PAT only (30 seconds)
7
+ ```bash
8
+ npm install -g figmanage
9
+ ```
10
10
 
11
- Get a token at [figma.com/settings](https://www.figma.com/settings) > Security > Personal access tokens, then:
11
+ ## setup
12
12
 
13
13
  ```bash
14
- claude mcp add figmanage -s user -e FIGMA_PAT=figd_xxx -- npx -y figmanage
14
+ figmanage login
15
15
  ```
16
16
 
17
- Restart Claude Code. Gives you 30+ tools (comments, reading, export, components, versions, webhooks).
18
-
19
- ### full setup (2 minutes, all 79 tools)
17
+ 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.
20
18
 
21
19
  ```bash
22
- npx -y figmanage --setup
20
+ figmanage whoami # verify auth
21
+ figmanage logout # clear credentials
23
22
  ```
24
23
 
25
- Extracts your Chrome cookie, prompts for a PAT, registers with Claude Code automatically. Unlocks all 79 tools including workspace management, permissions, and org admin. Restart Claude Code.
24
+ ## usage
26
25
 
27
- Use `--no-prompt --pat figd_xxx` for non-interactive setup.
26
+ ```bash
27
+ figmanage seat-optimization # find inactive paid seats
28
+ figmanage offboard sarah@co.com # audit what a user owns
29
+ figmanage offboard sarah@co.com --execute \
30
+ --transfer-to jake@co.com # execute the offboarding
31
+ figmanage onboard alex@co.com --teams 123,456 \
32
+ --role editor --seat full --confirm # set up a new hire
33
+ figmanage quarterly-report # org-wide design ops snapshot
34
+ figmanage members --search danny # find org members
35
+ figmanage teams # list all teams
36
+ figmanage permissions file abc123 # who has access to a file
37
+ figmanage permission-audit --scope team --id 789 # audit a team's permissions
38
+ figmanage branch-cleanup 573408414 # find stale branches
39
+ ```
28
40
 
29
- ### Claude Desktop / Cowork
41
+ All commands output JSON when piped or when `--json` is passed.
30
42
 
31
- Full setup with cookie extraction:
43
+ ## AI integration (MCP)
32
44
 
33
- ```bash
34
- npx -y figmanage --setup --desktop
35
- ```
45
+ figmanage runs as an MCP server for Claude, ChatGPT, Cursor, and other AI assistants:
36
46
 
37
- Or manually add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
47
+ ```bash
48
+ # Claude Code
49
+ claude mcp add figmanage -- npx -y figmanage --mcp
38
50
 
39
- ```json
51
+ # Claude Desktop / Cowork
52
+ # Add to claude_desktop_config.json:
40
53
  {
41
54
  "mcpServers": {
42
55
  "figmanage": {
43
56
  "command": "npx",
44
- "args": ["-y", "figmanage"],
45
- "env": {
46
- "FIGMA_PAT": "figd_your_token_here"
47
- }
57
+ "args": ["-y", "figmanage", "--mcp"]
48
58
  }
49
59
  }
50
60
  }
51
61
  ```
52
62
 
53
- ## configuration
63
+ Credentials are read from `~/.config/figmanage/` (set up via `figmanage login`). Env vars (`FIGMA_PAT`, `FIGMA_AUTH_COOKIE`, etc.) override the config file for backwards compatibility.
54
64
 
55
- | Env var | Description |
56
- |---------|-------------|
57
- | `FIGMA_PAT` | Personal access token |
58
- | `FIGMA_AUTH_COOKIE` | Session cookie value |
59
- | `FIGMA_USER_ID` | Your Figma user ID |
60
- | `FIGMA_ORG_ID` | Your org ID |
61
- | `FIGMA_TOOLSETS` | Toolset filter or preset name |
62
- | `FIGMA_READ_ONLY` | Set to `1` to disable mutations |
65
+ MCP mode exposes all 85 tools to the AI assistant. HTTP transport available via `--mcp --http <port>`.
63
66
 
64
- The setup script stores credentials as env vars in the MCP server config. You can also set them manually.
67
+ ### toolset presets (MCP only)
65
68
 
66
- ### toolset presets
69
+ Use `FIGMA_TOOLSETS` to expose only specific tool groups:
67
70
 
68
- Use `FIGMA_TOOLSETS` to expose only the tool groups you need. Presets bundle common combinations:
69
-
70
- | Preset | Toolsets included |
71
- |--------|-------------------|
71
+ | Preset | Toolsets |
72
+ |--------|----------|
72
73
  | `starter` | navigate, reading, comments, export |
73
74
  | `admin` | navigate, org, permissions, analytics, teams, libraries |
74
75
  | `readonly` | navigate, reading, comments, export, components, versions |
75
76
  | `full` | everything (default) |
76
77
 
77
- Or pass individual toolsets:
78
-
79
- ```bash
80
- FIGMA_TOOLSETS=navigate,reading,comments
81
- ```
82
-
83
- Available toolsets: `navigate`, `files`, `projects`, `permissions`, `org`, `versions`, `branching`, `comments`, `export`, `analytics`, `reading`, `components`, `webhooks`, `variables`, `compound`, `teams`, `libraries`.
84
-
85
- ### multi-org support
86
-
87
- `list_orgs` discovers all available orgs. `switch_org` changes the active workspace for the session. 12 tools accept an `org_id` override parameter for one-off cross-org queries without switching.
88
-
89
78
  ## auth
90
79
 
91
- figmanage uses two API clients targeting different Figma endpoints:
80
+ figmanage uses two Figma API surfaces:
92
81
 
93
- | Client | Base URL | Auth | Capabilities |
94
- |--------|----------|------|-------------|
95
- | Internal API | `www.figma.com` | Session cookie | Workspace management, search, permissions, org admin, file lifecycle |
96
- | Public API | `api.figma.com` | Personal Access Token | Comments, export, file reading, components, versions, webhooks, variables |
82
+ | Client | Auth | Capabilities |
83
+ |--------|------|-------------|
84
+ | Internal API | Session cookie | Workspace management, search, permissions, org admin, seats, billing |
85
+ | Public API | Personal Access Token | Comments, export, file reading, components, versions, webhooks, variables |
97
86
 
98
- Each tool declares its auth requirement:
87
+ Cookie auth unlocks all 85 tools. PAT-only gives ~30 (reading, comments, export, components). Both together is recommended.
99
88
 
100
- | Requirement | Meaning |
101
- |-------------|---------|
102
- | `cookie` | Internal API only. Needs `FIGMA_AUTH_COOKIE` + `FIGMA_USER_ID`. |
103
- | `pat` | Public API only. Needs `FIGMA_PAT`. |
104
- | `either` | Works with whichever auth is available. Prefers public API when PAT present. |
89
+ Auth resolution: env vars > config file > prompt to run `figmanage login`.
105
90
 
106
- Tools are automatically filtered at startup based on available credentials. If you only have a PAT, cookie-only tools are not registered.
91
+ ## commands
107
92
 
108
- ## tools
93
+ ### navigate (10)
109
94
 
110
- ### navigate (10 tools)
111
-
112
- | Tool | Auth | Description |
113
- |------|------|-------------|
95
+ | Command | Auth | Description |
96
+ |---------|------|-------------|
114
97
  | `check_auth` | either | Validate PAT and cookie authentication |
115
- | `list_orgs` | cookie | List available Figma workspaces (orgs) with names |
98
+ | `list_orgs` | cookie | List available Figma workspaces |
116
99
  | `switch_org` | cookie | Switch active workspace for this session |
117
100
  | `list_teams` | cookie | List teams in your org |
118
101
  | `list_projects` | either | List projects in a team |
119
- | `list_files` | either | List files in a project (paginated) |
120
- | `list_recent_files` | cookie | Recently viewed/edited files across teams |
102
+ | `list_files` | either | List files in a project |
103
+ | `list_recent_files` | cookie | Recently viewed/edited files |
121
104
  | `search` | cookie | Search files across the workspace |
122
105
  | `get_file_info` | either | File metadata: name, project, team, link access |
123
- | `list_favorites` | cookie | List favorited files (broken -- see known limitations) |
106
+ | `list_favorites` | cookie | Favorited files (broken -- Figma BigInt bug) |
124
107
 
125
- ### files (8 tools)
108
+ ### files (8)
126
109
 
127
- | Tool | Auth | Description |
128
- |------|------|-------------|
110
+ | Command | Auth | Description |
111
+ |---------|------|-------------|
129
112
  | `create_file` | cookie | Create design, whiteboard, slides, or sites file |
130
113
  | `rename_file` | cookie | Rename a file |
131
114
  | `move_files` | cookie | Move files between projects (batch) |
132
- | `duplicate_file` | cookie | Copy a file, optionally to another project |
115
+ | `duplicate_file` | cookie | Copy a file |
133
116
  | `trash_files` | cookie | Move files to trash (batch) |
134
117
  | `restore_files` | cookie | Restore files from trash (batch) |
135
- | `favorite_file` | cookie | Add/remove file from sidebar favorites |
136
- | `set_link_access` | cookie | Set link sharing level (inherit/view/edit/org_view/org_edit) |
118
+ | `favorite_file` | cookie | Add/remove from favorites |
119
+ | `set_link_access` | cookie | Set link sharing level |
137
120
 
138
- ### projects (6 tools)
121
+ ### projects (6)
139
122
 
140
- | Tool | Auth | Description |
141
- |------|------|-------------|
123
+ | Command | Auth | Description |
124
+ |---------|------|-------------|
142
125
  | `create_project` | cookie | Create a project in a team |
143
126
  | `rename_project` | cookie | Rename a project |
144
127
  | `move_project` | cookie | Move a project to another team |
@@ -146,206 +129,151 @@ Tools are automatically filtered at startup based on available credentials. If y
146
129
  | `restore_project` | cookie | Restore a project from trash |
147
130
  | `set_project_description` | cookie | Set or update project description |
148
131
 
149
- ### permissions (7 tools)
132
+ ### permissions (7)
150
133
 
151
- | Tool | Auth | Description |
152
- |------|------|-------------|
153
- | `get_permissions` | cookie | List who has access to a file/project/team with roles |
134
+ | Command | Auth | Description |
135
+ |---------|------|-------------|
136
+ | `get_permissions` | cookie | List who has access with roles |
154
137
  | `set_permissions` | cookie | Change a user's access level |
155
- | `share` | cookie | Invite someone by email (viewer or editor) |
138
+ | `share` | cookie | Invite someone by email |
156
139
  | `revoke_access` | cookie | Remove someone's access |
157
- | `list_role_requests` | cookie | List pending file access requests |
140
+ | `list_role_requests` | cookie | List pending access requests |
158
141
  | `approve_role_request` | cookie | Accept an access request |
159
142
  | `deny_role_request` | cookie | Decline an access request |
160
143
 
161
- ### reading (2 tools)
144
+ ### reading (2)
162
145
 
163
- | Tool | Auth | Description |
164
- |------|------|-------------|
165
- | `get_file` | pat | Read file contents as a node tree with depth control |
166
- | `get_nodes` | pat | Read specific nodes by ID from a file |
146
+ | Command | Auth | Description |
147
+ |---------|------|-------------|
148
+ | `get_file` | pat | Read file as a node tree with depth control |
149
+ | `get_nodes` | pat | Read specific nodes by ID |
167
150
 
168
- ### components (4 tools)
151
+ ### components (4)
169
152
 
170
- | Tool | Auth | Description |
171
- |------|------|-------------|
172
- | `list_file_components` | pat | List components published from a file |
173
- | `list_file_styles` | pat | List styles in a file |
174
- | `list_team_components` | pat | List published components across a team (paginated) |
175
- | `list_team_styles` | pat | List published styles across a team (paginated) |
153
+ | Command | Auth | Description |
154
+ |---------|------|-------------|
155
+ | `list_file_components` | pat | Components published from a file |
156
+ | `list_file_styles` | pat | Styles in a file |
157
+ | `list_team_components` | pat | Published components across a team |
158
+ | `list_team_styles` | pat | Published styles across a team |
176
159
 
177
- ### versions (2 tools)
160
+ ### versions (2)
178
161
 
179
- | Tool | Auth | Description |
180
- |------|------|-------------|
181
- | `list_versions` | pat | List version history (named checkpoints and auto-saves) |
162
+ | Command | Auth | Description |
163
+ |---------|------|-------------|
164
+ | `list_versions` | pat | Version history |
182
165
  | `create_version` | cookie | Create a named version checkpoint |
183
166
 
184
- ### branching (3 tools)
167
+ ### branching (3)
185
168
 
186
- | Tool | Auth | Description |
187
- |------|------|-------------|
169
+ | Command | Auth | Description |
170
+ |---------|------|-------------|
188
171
  | `list_branches` | either | List branches of a file |
189
- | `create_branch` | cookie | Create a branch from a file |
190
- | `delete_branch` | cookie | Archive (delete) a branch |
172
+ | `create_branch` | cookie | Create a branch |
173
+ | `delete_branch` | cookie | Archive a branch |
191
174
 
192
- ### comments (4 tools)
175
+ ### comments (4)
193
176
 
194
- | Tool | Auth | Description |
195
- |------|------|-------------|
196
- | `list_comments` | pat | List comments with thread structure (optional markdown format) |
197
- | `post_comment` | pat | Post a comment, optionally pinned to a node or as a reply |
198
- | `delete_comment` | pat | Permanently delete a comment |
199
- | `list_comment_reactions` | pat | List emoji reactions on a comment |
177
+ | Command | Auth | Description |
178
+ |---------|------|-------------|
179
+ | `list_comments` | pat | Comments with thread structure |
180
+ | `post_comment` | pat | Post a comment |
181
+ | `delete_comment` | pat | Delete a comment |
182
+ | `list_comment_reactions` | pat | Emoji reactions on a comment |
200
183
 
201
- ### export (2 tools)
184
+ ### export (2)
202
185
 
203
- | Tool | Auth | Description |
204
- |------|------|-------------|
205
- | `export_nodes` | pat | Export nodes as PNG, SVG, PDF, or JPG (returns temporary URLs) |
206
- | `get_image_fills` | pat | Get URLs for all images used as fills in a file |
186
+ | Command | Auth | Description |
187
+ |---------|------|-------------|
188
+ | `export_nodes` | pat | Export as PNG, SVG, PDF, or JPG |
189
+ | `get_image_fills` | pat | URLs for all images used as fills |
207
190
 
208
- ### webhooks (4 tools)
191
+ ### webhooks (4)
209
192
 
210
- | Tool | Auth | Description |
211
- |------|------|-------------|
193
+ | Command | Auth | Description |
194
+ |---------|------|-------------|
212
195
  | `list_webhooks` | pat | List webhooks for a team |
213
- | `create_webhook` | pat | Create a webhook subscription for a team |
214
- | `update_webhook` | pat | Update a webhook (endpoint, event type, status) |
196
+ | `create_webhook` | pat | Create a webhook subscription |
197
+ | `update_webhook` | pat | Update a webhook |
215
198
  | `delete_webhook` | pat | Delete a webhook |
216
199
 
217
- ### variables (3 tools, Enterprise only)
218
-
219
- | Tool | Auth | Description |
220
- |------|------|-------------|
221
- | `list_local_variables` | pat | List local variables and collections in a file |
222
- | `list_published_variables` | pat | List published variables from a library file |
223
- | `update_variables` | pat | Bulk create, update, or delete variables, collections, modes, and values |
224
-
225
- ### analytics (2 tools)
226
-
227
- | Tool | Auth | Description |
228
- |------|------|-------------|
229
- | `library_usage` | cookie | Team-level library adoption metrics over a lookback period |
230
- | `component_usage` | cookie | Per-file component usage analytics |
231
-
232
- ### org (12 tools)
233
-
234
- | Tool | Auth | Description |
235
- |------|------|-------------|
236
- | `list_admins` | cookie | Org admins with permission levels and seat status |
237
- | `list_org_teams` | cookie | All teams with member counts, project counts, access levels |
238
- | `seat_usage` | cookie | Seat breakdown: permissions, seat types, activity, account types |
239
- | `list_team_members` | cookie | Team members with name, email, role, last active date |
240
- | `list_org_members` | cookie | List org members with seat type, permission, email, last active |
241
- | `contract_rates` | cookie | Seat pricing per product (expert, developer, collaborator) |
242
- | `change_seat` | cookie | Change a user's seat type (confirm flag required for upgrades) |
243
- | `billing_overview` | cookie | Invoice history, billing status, amounts, billing periods |
200
+ ### variables (3, Enterprise)
201
+
202
+ | Command | Auth | Description |
203
+ |---------|------|-------------|
204
+ | `list_local_variables` | pat | Local variables and collections |
205
+ | `list_published_variables` | pat | Published variables from a library |
206
+ | `update_variables` | pat | Bulk create, update, or delete variables |
207
+
208
+ ### analytics (2)
209
+
210
+ | Command | Auth | Description |
211
+ |---------|------|-------------|
212
+ | `library_usage` | cookie | Team-level library adoption metrics |
213
+ | `component_usage` | cookie | Per-file component usage |
214
+
215
+ ### org (12)
216
+
217
+ | Command | Auth | Description |
218
+ |---------|------|-------------|
219
+ | `list_admins` | cookie | Org admins with permission levels |
220
+ | `list_org_teams` | cookie | All teams with member and project counts |
221
+ | `seat_usage` | cookie | Seat breakdown by type and activity |
222
+ | `list_team_members` | cookie | Team members with roles and activity |
223
+ | `list_org_members` | cookie | All org members with seats and activity |
224
+ | `contract_rates` | cookie | Per-seat pricing |
225
+ | `change_seat` | cookie | Change a user's seat type |
226
+ | `billing_overview` | cookie | Invoice history and billing status |
244
227
  | `list_invoices` | cookie | Open and upcoming invoices |
245
- | `org_domains` | cookie | Domain configuration and SSO/SAML settings |
246
- | `ai_credit_usage` | cookie | AI credit usage summary for a billing plan |
247
- | `export_members` | cookie | Trigger async CSV export of all org members (emailed to admin) |
228
+ | `org_domains` | cookie | Domain config and SSO/SAML |
229
+ | `ai_credit_usage` | cookie | AI credit usage summary |
230
+ | `export_members` | cookie | Trigger CSV export of all members |
248
231
 
249
- ### teams (3 tools)
232
+ ### teams (3)
250
233
 
251
- | Tool | Auth | Description |
252
- |------|------|-------------|
253
- | `create_team` | cookie | Create a new team in the org |
254
- | `rename_team` | cookie | Rename an existing team |
255
- | `delete_team` | cookie | Delete a team (destructive, cannot be undone) |
234
+ | Command | Auth | Description |
235
+ |---------|------|-------------|
236
+ | `create_team` | cookie | Create a team |
237
+ | `rename_team` | cookie | Rename a team |
238
+ | `delete_team` | cookie | Delete a team |
256
239
 
257
- ### libraries (1 tool)
240
+ ### libraries (1)
258
241
 
259
- | Tool | Auth | Description |
260
- |------|------|-------------|
261
- | `list_org_libraries` | cookie | All design system libraries in the org with sharing group info |
242
+ | Command | Auth | Description |
243
+ |---------|------|-------------|
244
+ | `list_org_libraries` | cookie | Design system libraries with sharing info |
262
245
 
263
- ### compound (6 tools)
246
+ ### compound (12)
264
247
 
265
248
  Multi-step operations that aggregate data from several API calls.
266
249
 
267
- | Tool | Auth | Description |
268
- |------|------|-------------|
269
- | `file_summary` | pat | Quick overview: pages, components, styles, comment counts |
270
- | `workspace_overview` | cookie | Full org snapshot: teams, seats, billing in one call |
271
- | `open_comments` | pat | Aggregated unresolved comments across all files in a project |
272
- | `cleanup_stale_files` | either | Find files not modified in N days, optionally trash them (dry run by default) |
273
- | `organize_project` | cookie | Batch-move files into a target project |
274
- | `setup_project_structure` | cookie | Create multiple projects in a team from a plan |
275
-
276
- ## transport modes
277
-
278
- | Mode | Flag | Use case |
279
- |------|------|----------|
280
- | stdio | (default) | Claude Code, Claude Desktop, most MCP clients |
281
- | HTTP | `--http <port>` | ChatGPT, web-based clients |
282
-
283
- ```bash
284
- npx figmanage # stdio
285
- npx figmanage --http 3333 # HTTP on port 3333
286
- ```
250
+ | Command | Auth | Description |
251
+ |---------|------|-------------|
252
+ | `file_summary` | pat | Pages, components, styles, comment counts |
253
+ | `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
254
+ | `open_comments` | pat | Unresolved comments across a project |
255
+ | `cleanup_stale_files` | either | Find old files, optionally trash (dry run default) |
256
+ | `organize_project` | cookie | Batch-move files into a project |
257
+ | `setup_project_structure` | cookie | Create multiple projects from a plan |
258
+ | `seat_optimization` | cookie | Inactive seat detection with cost analysis |
259
+ | `permission_audit` | cookie | Team/project access audit with oversharing flags |
260
+ | `branch_cleanup` | either | Stale branch detection with optional archival |
261
+ | `offboard_user` | cookie | Audit + execute user departure |
262
+ | `onboard_user` | cookie | Batch invite to teams, share files, set seat |
263
+ | `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
287
264
 
288
265
  ## security
289
266
 
290
- ### ID validation
291
-
292
- All tool parameters that accept Figma IDs (file keys, team IDs, project IDs, node IDs) are validated against a strict regex (`/^[\w.:-]+$/`) before use. This blocks path traversal in URL templates.
293
-
294
- ### safe retry policy
295
-
296
- Both API clients retry on transient errors with exponential backoff. Rate limit responses (429) are only retried for safe methods (`GET`, `HEAD`, `OPTIONS`). Mutations are never retried on 429 to prevent duplicate writes. Auth failures (401, 403) are never retried.
297
-
298
- ### response shaping
299
-
300
- Org admin tools extract documented fields and strip PII (e.g., `shipping_address` is removed from billing responses).
301
-
302
- ## architecture
303
-
304
- ```
305
- src/
306
- index.ts MCP server entry point (stdio transport, toolset parsing)
307
- setup.ts Chrome cookie extraction + Claude MCP config
308
- auth/
309
- client.ts AuthConfig, env var loading
310
- health.ts Auth validation
311
- clients/
312
- internal-api.ts Axios client for www.figma.com (cookie auth, safe retry)
313
- public-api.ts Axios client for api.figma.com (PAT auth, safe retry)
314
- tools/
315
- register.ts defineTool() pattern, toolset filtering, read-only mode, figmaId validation
316
- navigate.ts Browse and search (10 tools)
317
- files.ts File lifecycle (8 tools)
318
- projects.ts Project management (6 tools)
319
- permissions.ts Sharing, access control, role requests (7 tools)
320
- reading.ts File and node reading via public API (2 tools)
321
- components.ts Components and styles via public API (4 tools)
322
- versions.ts Version history (2 tools)
323
- branching.ts Branch CRUD (3 tools)
324
- comments.ts Comments and reactions via public API (4 tools)
325
- export.ts Image export and fills via public API (2 tools)
326
- webhooks.ts Webhook CRUD via V2 public API (4 tools)
327
- variables.ts Variables via public API, Enterprise only (3 tools)
328
- analytics.ts Library and component analytics via internal API (2 tools)
329
- org.ts Org admin, billing, seats, domains via internal API (9 tools)
330
- teams.ts Team CRUD (3 tools)
331
- libraries.ts Design system libraries via internal API (1 tool)
332
- compound.ts Multi-step aggregation tools (6 tools)
333
- types/
334
- figma.ts Shared types (Toolset, AuthConfig, etc.)
335
- ```
336
-
337
- Tools self-register via `defineTool()` side-effect imports. Each tool declares its toolset, auth requirement, and whether it mutates. `registerTools()` filters at startup based on available credentials, enabled toolsets, and read-only mode.
267
+ All parameters that accept Figma IDs are validated against `/^[\w.:-]+$/` before use. Rate limit retries are restricted to safe HTTP methods. Mutations are never retried. Billing responses strip PII. Destructive operations default to dry-run mode. Config file is stored with 0o600 permissions.
338
268
 
339
269
  ## known limitations
340
270
 
341
- - **list_favorites**: Figma's server has a BigInt overflow bug on large user IDs. The `favorite_file` tool for adding/removing favorites works fine.
342
- - **Branch merging**: Figma merges branches through its real-time multiplayer protocol, not a REST endpoint. Must be done in the Figma UI.
343
- - **Cookie expiry**: Session cookies expire roughly every 30 days. Re-run `npm run setup` to refresh.
344
- - **Windows cookie extraction**: Best-effort via DPAPI/PowerShell. Falls back to PAT-only setup if extraction fails.
345
- - **Variables require Enterprise**: The `file_variables:read` and `file_variables:write` scopes are not available in the standard PAT UI. Variables tools return a clear error on non-Enterprise plans.
346
- - **No org-level member list**: There is no single REST endpoint to list all org members. Use `list_admins` + `list_team_members` per team, or `export_members` for a full CSV.
347
- - **No activity log API**: Figma's activity log is SSR only with no REST endpoint.
348
- - **get_file returns full tree**: Without a `depth` parameter, `get_file` returns the entire document. Use `depth` or `get_nodes` for large files.
271
+ - **list_favorites**: Figma BigInt overflow bug on their server. `favorite_file` works fine.
272
+ - **Branch merging**: Requires Figma's multiplayer protocol, no REST endpoint.
273
+ - **Cookie expiry**: ~30 days. Run `figmanage login --refresh` to renew.
274
+ - **Windows cookies**: Best-effort DPAPI extraction. Falls back to PAT-only.
275
+ - **Variables**: Enterprise-gated scopes.
276
+ - **get_file**: Returns full document tree. Use `depth` param or `get_nodes`.
349
277
 
350
278
  ## development
351
279
 
@@ -353,11 +281,8 @@ Tools self-register via `defineTool()` side-effect imports. Each tool declares i
353
281
  git clone https://github.com/dannykeane/figmanage.git
354
282
  cd figmanage
355
283
  npm install
356
- npm run build # compile
357
- npm run setup # configure auth + MCP client
358
- npm run dev # watch mode
359
- npm run lint # type-check
360
- npm test # run tests
284
+ npm run build
285
+ npm test
361
286
  ```
362
287
 
363
288
  ## license
@@ -9,6 +9,22 @@ export interface AuthConfig {
9
9
  orgId?: string;
10
10
  orgs?: OrgEntry[];
11
11
  }
12
+ /**
13
+ * Load auth from environment variables. This is the original path --
14
+ * env vars set by MCP client config or shell.
15
+ */
16
+ export declare function loadFromEnv(): AuthConfig;
17
+ /**
18
+ * Load auth from the config file's active workspace.
19
+ * Returns null if no config file or active workspace found.
20
+ */
21
+ export declare function loadFromConfigFile(): AuthConfig | null;
22
+ /**
23
+ * Load auth config with fallback chain:
24
+ * 1. Environment variables (backwards compatible)
25
+ * 2. Config file (~/.config/figmanage/config.json)
26
+ * 3. Empty config (caller decides what to do)
27
+ */
12
28
  export declare function loadAuthConfig(): AuthConfig;
13
29
  export declare function hasPat(config: AuthConfig): boolean;
14
30
  export declare function hasCookie(config: AuthConfig): boolean;
@@ -1,3 +1,4 @@
1
+ import { getActiveWorkspace } from '../config.js';
1
2
  function parseOrgs(raw) {
2
3
  if (!raw)
3
4
  return undefined;
@@ -11,7 +12,11 @@ function parseOrgs(raw) {
11
12
  return undefined;
12
13
  }
13
14
  }
14
- export function loadAuthConfig() {
15
+ /**
16
+ * Load auth from environment variables. This is the original path --
17
+ * env vars set by MCP client config or shell.
18
+ */
19
+ export function loadFromEnv() {
15
20
  return {
16
21
  pat: process.env.FIGMA_PAT,
17
22
  cookie: process.env.FIGMA_AUTH_COOKIE,
@@ -20,6 +25,44 @@ export function loadAuthConfig() {
20
25
  orgs: parseOrgs(process.env.FIGMA_ORGS),
21
26
  };
22
27
  }
28
+ /**
29
+ * Load auth from the config file's active workspace.
30
+ * Returns null if no config file or active workspace found.
31
+ */
32
+ export function loadFromConfigFile() {
33
+ const workspace = getActiveWorkspace();
34
+ if (!workspace)
35
+ return null;
36
+ // Only return if the workspace has usable credentials
37
+ const hasCreds = workspace.pat || (workspace.cookie && workspace.user_id);
38
+ if (!hasCreds)
39
+ return null;
40
+ return {
41
+ pat: workspace.pat,
42
+ cookie: workspace.cookie,
43
+ userId: workspace.user_id,
44
+ orgId: workspace.org_id,
45
+ };
46
+ }
47
+ /**
48
+ * Load auth config with fallback chain:
49
+ * 1. Environment variables (backwards compatible)
50
+ * 2. Config file (~/.config/figmanage/config.json)
51
+ * 3. Empty config (caller decides what to do)
52
+ */
53
+ export function loadAuthConfig() {
54
+ // Env vars take precedence -- backwards compatible
55
+ const envConfig = loadFromEnv();
56
+ if (envConfig.pat || (envConfig.cookie && envConfig.userId)) {
57
+ return envConfig;
58
+ }
59
+ // Fall back to config file
60
+ const fileConfig = loadFromConfigFile();
61
+ if (fileConfig)
62
+ return fileConfig;
63
+ // Return env config as-is (empty or partial)
64
+ return envConfig;
65
+ }
23
66
  export function hasPat(config) {
24
67
  return !!config.pat;
25
68
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Chrome cookie extraction and Figma session validation.
3
+ *
4
+ * Extracted from setup.ts so both the setup flow and the CLI login
5
+ * command can reuse this logic.
6
+ */
7
+ export interface ParsedCookie {
8
+ userId: string;
9
+ token: string;
10
+ cookieValue: string;
11
+ }
12
+ export declare function parseCookieValue(raw: string): ParsedCookie;
13
+ export interface SessionInfo {
14
+ orgId: string;
15
+ orgs: {
16
+ id: string;
17
+ name: string;
18
+ }[];
19
+ teams: {
20
+ id: string;
21
+ name: string;
22
+ }[];
23
+ }
24
+ export declare function validateSession(cookieValue: string, userId: string): Promise<SessionInfo>;
25
+ export declare function validatePat(pat: string): Promise<string>;
26
+ export interface FigmaAccount {
27
+ userId: string;
28
+ cookieValue: string;
29
+ profile: string;
30
+ }
31
+ /**
32
+ * Extract Figma auth cookies from all Chrome profiles.
33
+ * Returns an array of accounts found (may be empty on Windows failure).
34
+ * Throws on non-Windows platforms if no Chrome profiles exist.
35
+ */
36
+ export declare function extractCookies(): FigmaAccount[];
37
+ //# sourceMappingURL=cookie.d.ts.map