@rui.branco/jira-mcp 1.7.11 → 1.7.12

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 (5) hide show
  1. package/README.md +358 -358
  2. package/config-store.js +553 -553
  3. package/index.js +5773 -5763
  4. package/package.json +36 -36
  5. package/setup.js +393 -392
package/README.md CHANGED
@@ -1,358 +1,358 @@
1
- # Jira MCP Server
2
-
3
- A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that brings Jira ticket context directly into any MCP-compatible AI client — Claude Code, Codex CLI, Google's Antigravity (Gemini), Cursor, Windsurf, Zed, and others. Fetch complete ticket information including descriptions, comments, attachments, and linked Figma designs without leaving your development environment.
4
-
5
- ## Overview
6
-
7
- When working on development tasks, context switching between Jira and your code editor breaks flow and wastes time. This MCP server solves that by:
8
-
9
- - **Fetching complete ticket context** - Get descriptions, comments, status, and metadata instantly
10
- - **Downloading attachments** - Image attachments are downloaded and displayed inline
11
- - **Auto-fetching Figma designs** - Linked Figma URLs are automatically detected and exported as images
12
- - **Enabling natural queries** - Search tickets with JQL directly from your AI client
13
-
14
- ## Features
15
-
16
- | Feature | Description |
17
- |---------|-------------|
18
- | Full Ticket Details | Summary, description, status, priority, assignee, reporter, sprint, parent |
19
- | Comments | All comments with author and timestamp |
20
- | Attachments | Auto-download image attachments (PNG, JPG, GIF, WebP) |
21
- | Linked Issues | View related tickets and their relationships |
22
- | Figma Integration | Auto-detect and export Figma designs linked in tickets |
23
- | JQL Search | Search across your Jira instance with powerful queries |
24
-
25
- ## Installation
26
-
27
- ### Prerequisites
28
-
29
- - Node.js 18+
30
- - An MCP-compatible AI client (see [Step 1](#step-1-register-with-your-mcp-client) below)
31
- - Jira Cloud account with API access
32
-
33
- ### Step 1: Register with your MCP client
34
-
35
- Pick the snippet for your client. All of them launch the server over stdio.
36
-
37
- **Claude Code:**
38
-
39
- ```bash
40
- claude mcp add --transport stdio jira -- npx -y @rui.branco/jira-mcp
41
- ```
42
-
43
- **Codex CLI:** add to `~/.codex/config.toml`:
44
-
45
- ```toml
46
- [mcp_servers.jira]
47
- command = "npx"
48
- args = ["-y", "@rui.branco/jira-mcp"]
49
- ```
50
-
51
- **Google Antigravity / Gemini CLI:** add to `~/.gemini/settings.json`:
52
-
53
- ```json
54
- {
55
- "mcpServers": {
56
- "jira": { "command": "npx", "args": ["-y", "@rui.branco/jira-mcp"] }
57
- }
58
- }
59
- ```
60
-
61
- **Cursor, Windsurf, Zed, Cline, Continue, etc.:** add the same `command`/`args` pair to whatever JSON config that client uses for MCP servers (the exact path varies, but the shape is standard across clients).
62
-
63
- ### Step 2: Get Your Jira API Token
64
-
65
- 1. Go to [Atlassian API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
66
- 2. Click **"Create API token"**
67
- 3. Enter a label (e.g., "jira-mcp")
68
- 4. Click **"Create"**
69
- 5. Copy the token (you won't be able to see it again)
70
-
71
- ### Step 3: Configure Credentials
72
-
73
- Run the setup with your credentials:
74
-
75
- ```bash
76
- npx @rui.branco/jira-mcp setup "your@email.com" "YOUR_API_TOKEN" "https://company.atlassian.net"
77
- ```
78
-
79
- | Parameter | Description | Example |
80
- |-----------|-------------|---------|
81
- | Email | Your Atlassian account email | `john@company.com` |
82
- | API Token | The token you created in Step 2 | `ATATT3xFfGF0...` |
83
- | Base URL | Your Jira instance URL | `https://company.atlassian.net` |
84
-
85
- Or run interactively (will prompt for each value):
86
-
87
- ```bash
88
- npx @rui.branco/jira-mcp setup
89
- ```
90
-
91
- ### Step 4: Verify
92
-
93
- Restart your AI client and check its MCP status (e.g. `/mcp` in Claude Code, `mcp` in Codex CLI, or the equivalent panel in your client) to verify the server is connected.
94
-
95
- ### Alternative: Manual Installation
96
-
97
- If you prefer to install manually:
98
-
99
- ```bash
100
- git clone https://github.com/rui-branco/jira-mcp.git ~/.config/jira-mcp
101
- cd ~/.config/jira-mcp && npm install
102
- node setup.js
103
- ```
104
-
105
- Then register the local entry point with your MCP client (replace the `npx -y @rui.branco/jira-mcp` command from Step 1 with `node $HOME/.config/jira-mcp/index.js`). Example for Claude Code:
106
-
107
- ```bash
108
- claude mcp add --transport stdio jira -- node $HOME/.config/jira-mcp/index.js
109
- ```
110
-
111
- ## Usage
112
-
113
- ### Fetch a Ticket
114
-
115
- ```
116
- > Get ticket PROJ-123
117
-
118
- # Returns full ticket with description, comments, attachments, and Figma designs
119
- ```
120
-
121
- ### Search Tickets
122
-
123
- ```
124
- > Search for my open tickets
125
-
126
- # Uses JQL: assignee = currentUser() AND status != Done
127
- ```
128
-
129
- ### Add Comments with Mentions
130
-
131
- Use `@FirstName LastName` syntax to mention users in comments:
132
-
133
- ```
134
- > Add a comment to PROJ-123: "@John Doe Please review this implementation"
135
-
136
- # The mention is automatically resolved and the user gets notified
137
- ```
138
-
139
- ### Example Output
140
-
141
- ```
142
- # PROJ-123: Implement user authentication
143
-
144
- Status: In Progress | Type: Story | Priority: High
145
- Assignee: John Doe | Reporter: Jane Smith
146
-
147
- ## Description
148
- Implement OAuth2 authentication flow...
149
-
150
- ## Comments (2)
151
- ### Jane Smith - Jan 15, 2025
152
- Please ensure we support Google SSO...
153
-
154
- ## Attachments (1)
155
- - mockup.png (image/png, 245KB)
156
- [Image displayed inline]
157
-
158
- ## Figma Designs (1)
159
- ### Auth Flow Design - Login Screen
160
- - Exported 3 image(s):
161
- - Login Form: ~/.config/figma-mcp/exports/...
162
- - Error States: ~/.config/figma-mcp/exports/...
163
- - Success State: ~/.config/figma-mcp/exports/...
164
- ```
165
-
166
- ## Figma Integration
167
-
168
- This MCP automatically detects Figma URLs in ticket descriptions and comments. When [figma-mcp](https://github.com/rui-branco/figma-mcp) is configured:
169
-
170
- - Figma links are automatically fetched
171
- - Large frames are split into sections for better readability
172
- - Images are exported at 2x scale for clarity
173
- - All images are displayed inline in clients that support image content blocks (Claude Code, Codex, Antigravity, etc.)
174
-
175
- To enable Figma integration:
176
- 1. Install and configure [figma-mcp](https://github.com/rui-branco/figma-mcp)
177
- 2. Restart your AI client
178
- 3. Figma links will be auto-fetched when you get a ticket
179
-
180
- ## API Reference
181
-
182
- ### Tools
183
-
184
- | Tool | Description | Parameters |
185
- |------|-------------|------------|
186
- | `jira_get_myself` | Get the current authenticated user's accountId and info (use for assigning tickets) | none |
187
- | `jira_get_ticket` | Fetch a ticket by key with description, comments, attachments, and Figma designs | `issueKey` (required), `downloadImages`, `fetchFigma` |
188
- | `jira_search` | Search tickets using JQL | `jql` (required), `maxResults` |
189
- | `jira_add_comment` | Add a comment to a ticket (supports @mentions) | `issueKey` (required), `comment` (required) |
190
- | `jira_reply_comment` | Reply to a specific comment with quote and mention | `issueKey` (required), `commentId` (required), `reply` (required) |
191
- | `jira_edit_comment` | Edit an existing comment (supports @mentions) | `issueKey` (required), `commentId` (required), `comment` (required) |
192
- | `jira_delete_comment` | Delete a comment (irreversible) | `issueKey` (required), `commentId` (required) |
193
- | `jira_transition` | Change ticket status by name or ID (auto-handles intermediate steps) | `issueKey` (required), `targetStatus` or `transitionId` |
194
- | `jira_update_ticket` | Update ticket fields (summary, description, assignee, priority, labels) | `issueKey` (required), plus optional field parameters |
195
-
196
- ### Confluence Tools
197
-
198
- This MCP also exposes Confluence via the same Atlassian credentials. On Atlassian Cloud, the API token you configured for Jira works for Confluence too, and the Confluence base URL is derived as `<jiraBaseUrl>/wiki` — **no extra setup required**. Just use the `confluence_*` tools below against any configured instance.
199
-
200
- For Server / Data Center deployments where Confluence lives on a different host, set `confluenceBaseUrl` explicitly on the stored instance in `config.json`.
201
-
202
- | Tool | Description | Parameters |
203
- |------|-------------|------------|
204
- | `confluence_get_spaces` | List global spaces (`key`, `name`, `id`) | `instance` |
205
- | `confluence_get_space` | Get a single space with description and homepage | `spaceKey` (required), `instance` |
206
- | `confluence_create_space` | Create a new global space | `spaceKey` (required), `name` (required), `description`, `instance` |
207
- | `confluence_update_space` | Update a space's name and/or description | `spaceKey` (required), `name`, `description`, `instance` |
208
- | `confluence_delete_space` | Delete a space (async on Cloud) | `spaceKey` (required), `instance` |
209
- | `confluence_search` | CQL text search (`text ~ "<query>" AND type = <type>`) | `query` (required), `spaceKey`, `type`, `limit`, `instance` |
210
- | `confluence_get_recent_pages` | Pages modified in the last N days | `sinceDays` (default 30), `spaceKey`, `limit`, `instance` |
211
- | `confluence_get_space_root_pages` | Top-level pages in a space with `childTypes.page` | `spaceKey` (required), `limit`, `instance` |
212
- | `confluence_get_page_children` | Direct child pages of a page | `pageId` (required), `limit`, `instance` |
213
- | `confluence_get_page` | Full page with `body.view`, `body.storage` and (by default) v2 `body.atlas_doc_format` merged in | `pageId` (required), `includeAdf`, `instance` |
214
- | `confluence_get_comments` | List comments on a page | `pageId` (required), `limit`, `instance` |
215
- | `confluence_add_comment` | Add a footer comment (plain text wrapped into storage XHTML by default) | `pageId` (required), `body` (required), `format` (`text`/`storage`), `instance` |
216
- | `confluence_update_page` | Update title/body; auto-bumps version if not supplied | `pageId` (required), `title`, `body` (storage XHTML), `version`, `instance` |
217
- | `confluence_create_page` | Create a page with optional parent | `spaceKey`, `title`, `body` (storage XHTML) (all required), `parentId`, `instance` |
218
- | `confluence_delete_page` | Delete a page | `pageId` (required), `instance` |
219
- | `confluence_get_labels` | List labels on a page | `pageId` (required), `instance` |
220
- | `confluence_add_label` | Add a label to a page | `pageId` (required), `label` (required), `instance` |
221
- | `confluence_remove_label` | Remove a label from a page | `pageId` (required), `label` (required), `instance` |
222
- | `confluence_list_attachments` | List attachments on a page | `pageId` (required), `limit`, `instance` |
223
- | `confluence_upload_attachment` | Upload a file from disk or base64 content | `pageId` (required), `filePath` or `fileContent`+`fileName`, `comment`, `instance` |
224
- | `confluence_download_attachment` | Download an attachment by filename to the local attachment dir | `pageId` (required), `filename` (required), `instance` |
225
-
226
- **Why ADF for `confluence_get_page`?** The v1 `body.atlas_doc_format` expand is unreliable on modern Cloud pages — table cell background colors and some newer node types only survive the v2 `/api/v2/pages/<id>?body-format=atlas_doc_format` endpoint. `confluence_get_page` therefore does both requests in parallel and merges the v2 ADF body onto the v1 response, so callers get `body.view`, `body.storage` and `body.atlas_doc_format` in one shot.
227
-
228
- ### Confluence On-Demand Activation
229
-
230
- By default, the 21 `confluence_*` tools are hidden from `tools/list` to reduce token footprint. A lightweight `confluence_enable` gateway tool is exposed instead. When a task needs Confluence, the client calls `confluence_enable` and the full tool set appears (the server sends `notifications/tools/list_changed`). Activation is per-process (not persisted to config) and does not bypass instance scopes.
231
-
232
- To expose Confluence tools from boot (skip the activation step), set the `confluence` config key or the `JIRA_MCP_CONFLUENCE` environment variable:
233
-
234
- | Method | Value |
235
- |--------|-------|
236
- | Config (`~/.config/jira-mcp/config.json`) | `"confluence": "always"` |
237
- | Environment variable | `JIRA_MCP_CONFLUENCE=always` |
238
-
239
- The default value is `"on-demand"`.
240
-
241
- ### Configuration
242
-
243
- Config stored at `~/.config/jira-mcp/config.json`:
244
-
245
- ```json
246
- {
247
- "email": "your@email.com",
248
- "token": "YOUR_API_TOKEN",
249
- "baseUrl": "https://company.atlassian.net"
250
- }
251
- ```
252
-
253
- ## Error Handling
254
-
255
- The server provides clear error messages:
256
-
257
- | Error | Meaning |
258
- |-------|---------|
259
- | `Figma API rate limit exceeded` | Too many Figma requests, wait a few minutes |
260
- | `Figma access denied` | Check Figma token or file permissions |
261
- | `Figma not configured` | Install and configure figma-mcp |
262
-
263
- ## Security
264
-
265
- - API tokens are stored locally in `~/.config/jira-mcp/config.json`
266
- - Config files are excluded from git via `.gitignore`
267
- - Tokens are never logged or transmitted except to Jira/Figma APIs
268
- - Attachments are downloaded to `~/.config/jira-mcp/attachments/`
269
-
270
- ## Safety & Observability
271
-
272
- Four opt-in controls limit what an agent can do without your approval and give you a trail when something goes wrong. All four are off by default for existing installs — drop the relevant config block into `~/.config/jira-mcp/config.json` to turn them on.
273
-
274
- ### Per-tool scopes
275
-
276
- Restrict which tools each instance can call. Useful for "this Atlassian instance is read-only" or "this one only allows comments".
277
-
278
- ```json
279
- {
280
- "instances": [
281
- {
282
- "name": "prod",
283
- "email": "you@company.com",
284
- "token": "...",
285
- "baseUrl": "https://company.atlassian.net",
286
- "scopes": { "preset": "read-only" }
287
- },
288
- {
289
- "name": "sandbox",
290
- "email": "you@company.com",
291
- "token": "...",
292
- "baseUrl": "https://sandbox.atlassian.net",
293
- "scopes": { "preset": "no-destructive", "deny": ["jira_remove_attachment"] }
294
- }
295
- ]
296
- }
297
- ```
298
-
299
- Presets: `read-only`, `comments-only`, `no-destructive`, `unrestricted`. You can combine a preset with `allow: [...]` and `deny: [...]` — deny wins. If `scopes` is present, an unknown tool name fails closed. If `scopes` is omitted, the instance behaves as before (no restrictions).
300
-
301
- ### Dry-run mode
302
-
303
- For any mutating tool call, return the HTTP request that *would* be sent without actually calling Atlassian. Useful for previewing what an agent is about to do.
304
-
305
- Three layers of precedence (most-specific wins):
306
-
307
- 1. **Per call:** pass `dryRun: true` to any mutating tool.
308
- 2. **Per instance:** add `"dryRun": true` to an instance in `config.json`.
309
- 3. **Environment:** export `JIRA_MCP_DRY_RUN=1` before launching your AI client.
310
-
311
- Read tools ignore the flag. The response looks like:
312
-
313
- ```json
314
- {
315
- "dryRun": true,
316
- "plan": [{ "api": "jira", "method": "POST", "endpoint": "/issue/PROJ-1/comment", "body": { ... } }]
317
- }
318
- ```
319
-
320
- For multi-step tools (e.g. `jira_transition` with intermediate statuses) only the first write is captured.
321
-
322
- ### Audit log
323
-
324
- Every write attempt — successful, failed, denied by scope, denied by rate limit, or dry-run — is appended as a JSON line to `~/.config/jira-mcp/audit.log`. Token-like fields (`token`, `authorization`, `password`, `apiKey`, `fileContent`, etc.) are redacted before they hit disk. Rotates at 10 MB, keeps 5 historical files.
325
-
326
- Disable with `"audit": { "enabled": false }` at the top level of `config.json`.
327
-
328
- ### Rate limiting
329
-
330
- Layered in-memory token buckets prevent runaway loops. Defaults:
331
-
332
- - **global:** 60 writes/minute
333
- - **per-instance:** 30 writes/minute
334
- - **destructive tools** (`*_delete_*`, `jira_remove_*`, `confluence_delete_*`): 5/minute
335
-
336
- On limit hit the tool call fails immediately with a `Rate limit exceeded` error — no sleeping, no queueing. Reads bypass the limiter entirely. Dry-runs don't consume tokens.
337
-
338
- Override or disable in `config.json`:
339
-
340
- ```json
341
- {
342
- "rateLimit": {
343
- "enabled": true,
344
- "global": 120,
345
- "perInstance": 60,
346
- "destructive": 10
347
- }
348
- }
349
- ```
350
-
351
- ## License
352
-
353
- MIT
354
-
355
- ## Related
356
-
357
- - [figma-mcp](https://github.com/rui-branco/figma-mcp) - Figma MCP server (works with any MCP-compatible AI client)
358
- - [Model Context Protocol](https://modelcontextprotocol.io/) - MCP specification
1
+ # Jira MCP Server
2
+
3
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that brings Jira ticket context directly into any MCP-compatible AI client — Claude Code, Codex CLI, Google's Antigravity (Gemini), Cursor, Windsurf, Zed, and others. Fetch complete ticket information including descriptions, comments, attachments, and linked Figma designs without leaving your development environment.
4
+
5
+ ## Overview
6
+
7
+ When working on development tasks, context switching between Jira and your code editor breaks flow and wastes time. This MCP server solves that by:
8
+
9
+ - **Fetching complete ticket context** - Get descriptions, comments, status, and metadata instantly
10
+ - **Downloading attachments** - Image attachments are downloaded and displayed inline
11
+ - **Auto-fetching Figma designs** - Linked Figma URLs are automatically detected and exported as images
12
+ - **Enabling natural queries** - Search tickets with JQL directly from your AI client
13
+
14
+ ## Features
15
+
16
+ | Feature | Description |
17
+ |---------|-------------|
18
+ | Full Ticket Details | Summary, description, status, priority, assignee, reporter, sprint, parent |
19
+ | Comments | All comments with author and timestamp |
20
+ | Attachments | Auto-download image attachments (PNG, JPG, GIF, WebP) |
21
+ | Linked Issues | View related tickets and their relationships |
22
+ | Figma Integration | Auto-detect and export Figma designs linked in tickets |
23
+ | JQL Search | Search across your Jira instance with powerful queries |
24
+
25
+ ## Installation
26
+
27
+ ### Prerequisites
28
+
29
+ - Node.js 18+
30
+ - An MCP-compatible AI client (see [Step 1](#step-1-register-with-your-mcp-client) below)
31
+ - Jira Cloud account with API access
32
+
33
+ ### Step 1: Register with your MCP client
34
+
35
+ Pick the snippet for your client. All of them launch the server over stdio.
36
+
37
+ **Claude Code:**
38
+
39
+ ```bash
40
+ claude mcp add --transport stdio jira -- npx -y @rui.branco/jira-mcp
41
+ ```
42
+
43
+ **Codex CLI:** add to `~/.codex/config.toml`:
44
+
45
+ ```toml
46
+ [mcp_servers.jira]
47
+ command = "npx"
48
+ args = ["-y", "@rui.branco/jira-mcp"]
49
+ ```
50
+
51
+ **Google Antigravity / Gemini CLI:** add to `~/.gemini/settings.json`:
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "jira": { "command": "npx", "args": ["-y", "@rui.branco/jira-mcp"] }
57
+ }
58
+ }
59
+ ```
60
+
61
+ **Cursor, Windsurf, Zed, Cline, Continue, etc.:** add the same `command`/`args` pair to whatever JSON config that client uses for MCP servers (the exact path varies, but the shape is standard across clients).
62
+
63
+ ### Step 2: Get Your Jira API Token
64
+
65
+ 1. Go to [Atlassian API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
66
+ 2. Click **"Create API token"**
67
+ 3. Enter a label (e.g., "jira-mcp")
68
+ 4. Click **"Create"**
69
+ 5. Copy the token (you won't be able to see it again)
70
+
71
+ ### Step 3: Configure Credentials
72
+
73
+ Run the setup with your credentials:
74
+
75
+ ```bash
76
+ npx @rui.branco/jira-mcp setup "your@email.com" "YOUR_API_TOKEN" "https://company.atlassian.net"
77
+ ```
78
+
79
+ | Parameter | Description | Example |
80
+ |-----------|-------------|---------|
81
+ | Email | Your Atlassian account email | `john@company.com` |
82
+ | API Token | The token you created in Step 2 | `ATATT3xFfGF0...` |
83
+ | Base URL | Your Jira instance URL | `https://company.atlassian.net` |
84
+
85
+ Or run interactively (will prompt for each value):
86
+
87
+ ```bash
88
+ npx @rui.branco/jira-mcp setup
89
+ ```
90
+
91
+ ### Step 4: Verify
92
+
93
+ Restart your AI client and check its MCP status (e.g. `/mcp` in Claude Code, `mcp` in Codex CLI, or the equivalent panel in your client) to verify the server is connected.
94
+
95
+ ### Alternative: Manual Installation
96
+
97
+ If you prefer to install manually:
98
+
99
+ ```bash
100
+ git clone https://github.com/rui-branco/jira-mcp.git ~/.config/jira-mcp
101
+ cd ~/.config/jira-mcp && npm install
102
+ node setup.js
103
+ ```
104
+
105
+ Then register the local entry point with your MCP client (replace the `npx -y @rui.branco/jira-mcp` command from Step 1 with `node $HOME/.config/jira-mcp/index.js`). Example for Claude Code:
106
+
107
+ ```bash
108
+ claude mcp add --transport stdio jira -- node $HOME/.config/jira-mcp/index.js
109
+ ```
110
+
111
+ ## Usage
112
+
113
+ ### Fetch a Ticket
114
+
115
+ ```
116
+ > Get ticket PROJ-123
117
+
118
+ # Returns full ticket with description, comments, attachments, and Figma designs
119
+ ```
120
+
121
+ ### Search Tickets
122
+
123
+ ```
124
+ > Search for my open tickets
125
+
126
+ # Uses JQL: assignee = currentUser() AND status != Done
127
+ ```
128
+
129
+ ### Add Comments with Mentions
130
+
131
+ Use `@FirstName LastName` syntax to mention users in comments:
132
+
133
+ ```
134
+ > Add a comment to PROJ-123: "@John Doe Please review this implementation"
135
+
136
+ # The mention is automatically resolved and the user gets notified
137
+ ```
138
+
139
+ ### Example Output
140
+
141
+ ```
142
+ # PROJ-123: Implement user authentication
143
+
144
+ Status: In Progress | Type: Story | Priority: High
145
+ Assignee: John Doe | Reporter: Jane Smith
146
+
147
+ ## Description
148
+ Implement OAuth2 authentication flow...
149
+
150
+ ## Comments (2)
151
+ ### Jane Smith - Jan 15, 2025
152
+ Please ensure we support Google SSO...
153
+
154
+ ## Attachments (1)
155
+ - mockup.png (image/png, 245KB)
156
+ [Image displayed inline]
157
+
158
+ ## Figma Designs (1)
159
+ ### Auth Flow Design - Login Screen
160
+ - Exported 3 image(s):
161
+ - Login Form: ~/.config/figma-mcp/exports/...
162
+ - Error States: ~/.config/figma-mcp/exports/...
163
+ - Success State: ~/.config/figma-mcp/exports/...
164
+ ```
165
+
166
+ ## Figma Integration
167
+
168
+ This MCP automatically detects Figma URLs in ticket descriptions and comments. When [figma-mcp](https://github.com/rui-branco/figma-mcp) is configured:
169
+
170
+ - Figma links are automatically fetched
171
+ - Large frames are split into sections for better readability
172
+ - Images are exported at 2x scale for clarity
173
+ - All images are displayed inline in clients that support image content blocks (Claude Code, Codex, Antigravity, etc.)
174
+
175
+ To enable Figma integration:
176
+ 1. Install and configure [figma-mcp](https://github.com/rui-branco/figma-mcp)
177
+ 2. Restart your AI client
178
+ 3. Figma links will be auto-fetched when you get a ticket
179
+
180
+ ## API Reference
181
+
182
+ ### Tools
183
+
184
+ | Tool | Description | Parameters |
185
+ |------|-------------|------------|
186
+ | `jira_get_myself` | Get the current authenticated user's accountId and info (use for assigning tickets) | none |
187
+ | `jira_get_ticket` | Fetch a ticket by key with description, comments, attachments, and Figma designs | `issueKey` (required), `downloadImages`, `fetchFigma` |
188
+ | `jira_search` | Search tickets using JQL | `jql` (required), `maxResults` |
189
+ | `jira_add_comment` | Add a comment to a ticket (supports @mentions) | `issueKey` (required), `comment` (required) |
190
+ | `jira_reply_comment` | Reply to a specific comment with quote and mention | `issueKey` (required), `commentId` (required), `reply` (required) |
191
+ | `jira_edit_comment` | Edit an existing comment (supports @mentions) | `issueKey` (required), `commentId` (required), `comment` (required) |
192
+ | `jira_delete_comment` | Delete a comment (irreversible) | `issueKey` (required), `commentId` (required) |
193
+ | `jira_transition` | Change ticket status by name or ID (auto-handles intermediate steps) | `issueKey` (required), `targetStatus` or `transitionId` |
194
+ | `jira_update_ticket` | Update ticket fields (summary, description, assignee, priority, labels) | `issueKey` (required), plus optional field parameters |
195
+
196
+ ### Confluence Tools
197
+
198
+ This MCP also exposes Confluence via the same Atlassian credentials. On Atlassian Cloud, the API token you configured for Jira works for Confluence too, and the Confluence base URL is derived as `<jiraBaseUrl>/wiki` — **no extra setup required**. Just use the `confluence_*` tools below against any configured instance.
199
+
200
+ For Server / Data Center deployments where Confluence lives on a different host, set `confluenceBaseUrl` explicitly on the stored instance in `config.json`.
201
+
202
+ | Tool | Description | Parameters |
203
+ |------|-------------|------------|
204
+ | `confluence_get_spaces` | List global spaces (`key`, `name`, `id`) | `instance` |
205
+ | `confluence_get_space` | Get a single space with description and homepage | `spaceKey` (required), `instance` |
206
+ | `confluence_create_space` | Create a new global space | `spaceKey` (required), `name` (required), `description`, `instance` |
207
+ | `confluence_update_space` | Update a space's name and/or description | `spaceKey` (required), `name`, `description`, `instance` |
208
+ | `confluence_delete_space` | Delete a space (async on Cloud) | `spaceKey` (required), `instance` |
209
+ | `confluence_search` | CQL text search (`text ~ "<query>" AND type = <type>`) | `query` (required), `spaceKey`, `type`, `limit`, `instance` |
210
+ | `confluence_get_recent_pages` | Pages modified in the last N days | `sinceDays` (default 30), `spaceKey`, `limit`, `instance` |
211
+ | `confluence_get_space_root_pages` | Top-level pages in a space with `childTypes.page` | `spaceKey` (required), `limit`, `instance` |
212
+ | `confluence_get_page_children` | Direct child pages of a page | `pageId` (required), `limit`, `instance` |
213
+ | `confluence_get_page` | Full page with `body.view`, `body.storage` and (by default) v2 `body.atlas_doc_format` merged in | `pageId` (required), `includeAdf`, `instance` |
214
+ | `confluence_get_comments` | List comments on a page | `pageId` (required), `limit`, `instance` |
215
+ | `confluence_add_comment` | Add a footer comment (plain text wrapped into storage XHTML by default) | `pageId` (required), `body` (required), `format` (`text`/`storage`), `instance` |
216
+ | `confluence_update_page` | Update title/body; auto-bumps version if not supplied | `pageId` (required), `title`, `body` (storage XHTML), `version`, `instance` |
217
+ | `confluence_create_page` | Create a page with optional parent | `spaceKey`, `title`, `body` (storage XHTML) (all required), `parentId`, `instance` |
218
+ | `confluence_delete_page` | Delete a page | `pageId` (required), `instance` |
219
+ | `confluence_get_labels` | List labels on a page | `pageId` (required), `instance` |
220
+ | `confluence_add_label` | Add a label to a page | `pageId` (required), `label` (required), `instance` |
221
+ | `confluence_remove_label` | Remove a label from a page | `pageId` (required), `label` (required), `instance` |
222
+ | `confluence_list_attachments` | List attachments on a page | `pageId` (required), `limit`, `instance` |
223
+ | `confluence_upload_attachment` | Upload a file from disk or base64 content | `pageId` (required), `filePath` or `fileContent`+`fileName`, `comment`, `instance` |
224
+ | `confluence_download_attachment` | Download an attachment by filename to the local attachment dir | `pageId` (required), `filename` (required), `instance` |
225
+
226
+ **Why ADF for `confluence_get_page`?** The v1 `body.atlas_doc_format` expand is unreliable on modern Cloud pages — table cell background colors and some newer node types only survive the v2 `/api/v2/pages/<id>?body-format=atlas_doc_format` endpoint. `confluence_get_page` therefore does both requests in parallel and merges the v2 ADF body onto the v1 response, so callers get `body.view`, `body.storage` and `body.atlas_doc_format` in one shot.
227
+
228
+ ### Confluence On-Demand Activation
229
+
230
+ By default, the 21 `confluence_*` tools are hidden from `tools/list` to reduce token footprint. A lightweight `confluence_enable` gateway tool is exposed instead. When a task needs Confluence, the client calls `confluence_enable` and the full tool set appears (the server sends `notifications/tools/list_changed`). Activation is per-process (not persisted to config) and does not bypass instance scopes.
231
+
232
+ To expose Confluence tools from boot (skip the activation step), set the `confluence` config key or the `JIRA_MCP_CONFLUENCE` environment variable:
233
+
234
+ | Method | Value |
235
+ |--------|-------|
236
+ | Config (`~/.config/jira-mcp/config.json`) | `"confluence": "always"` |
237
+ | Environment variable | `JIRA_MCP_CONFLUENCE=always` |
238
+
239
+ The default value is `"on-demand"`.
240
+
241
+ ### Configuration
242
+
243
+ Config stored at `~/.config/jira-mcp/config.json`:
244
+
245
+ ```json
246
+ {
247
+ "email": "your@email.com",
248
+ "token": "YOUR_API_TOKEN",
249
+ "baseUrl": "https://company.atlassian.net"
250
+ }
251
+ ```
252
+
253
+ ## Error Handling
254
+
255
+ The server provides clear error messages:
256
+
257
+ | Error | Meaning |
258
+ |-------|---------|
259
+ | `Figma API rate limit exceeded` | Too many Figma requests, wait a few minutes |
260
+ | `Figma access denied` | Check Figma token or file permissions |
261
+ | `Figma not configured` | Install and configure figma-mcp |
262
+
263
+ ## Security
264
+
265
+ - API tokens are stored locally in `~/.config/jira-mcp/config.json`
266
+ - Config files are excluded from git via `.gitignore`
267
+ - Tokens are never logged or transmitted except to Jira/Figma APIs
268
+ - Attachments are downloaded to `~/.config/jira-mcp/attachments/`
269
+
270
+ ## Safety & Observability
271
+
272
+ Four opt-in controls limit what an agent can do without your approval and give you a trail when something goes wrong. All four are off by default for existing installs — drop the relevant config block into `~/.config/jira-mcp/config.json` to turn them on.
273
+
274
+ ### Per-tool scopes
275
+
276
+ Restrict which tools each instance can call. Useful for "this Atlassian instance is read-only" or "this one only allows comments".
277
+
278
+ ```json
279
+ {
280
+ "instances": [
281
+ {
282
+ "name": "prod",
283
+ "email": "you@company.com",
284
+ "token": "...",
285
+ "baseUrl": "https://company.atlassian.net",
286
+ "scopes": { "preset": "read-only" }
287
+ },
288
+ {
289
+ "name": "sandbox",
290
+ "email": "you@company.com",
291
+ "token": "...",
292
+ "baseUrl": "https://sandbox.atlassian.net",
293
+ "scopes": { "preset": "no-destructive", "deny": ["jira_remove_attachment"] }
294
+ }
295
+ ]
296
+ }
297
+ ```
298
+
299
+ Presets: `read-only`, `comments-only`, `no-destructive`, `unrestricted`. You can combine a preset with `allow: [...]` and `deny: [...]` — deny wins. If `scopes` is present, an unknown tool name fails closed. If `scopes` is omitted, the instance behaves as before (no restrictions).
300
+
301
+ ### Dry-run mode
302
+
303
+ For any mutating tool call, return the HTTP request that *would* be sent without actually calling Atlassian. Useful for previewing what an agent is about to do.
304
+
305
+ Three layers of precedence (most-specific wins):
306
+
307
+ 1. **Per call:** pass `dryRun: true` to any mutating tool.
308
+ 2. **Per instance:** add `"dryRun": true` to an instance in `config.json`.
309
+ 3. **Environment:** export `JIRA_MCP_DRY_RUN=1` before launching your AI client.
310
+
311
+ Read tools ignore the flag. The response looks like:
312
+
313
+ ```json
314
+ {
315
+ "dryRun": true,
316
+ "plan": [{ "api": "jira", "method": "POST", "endpoint": "/issue/PROJ-1/comment", "body": { ... } }]
317
+ }
318
+ ```
319
+
320
+ For multi-step tools (e.g. `jira_transition` with intermediate statuses) only the first write is captured.
321
+
322
+ ### Audit log
323
+
324
+ Every write attempt — successful, failed, denied by scope, denied by rate limit, or dry-run — is appended as a JSON line to `~/.config/jira-mcp/audit.log`. Token-like fields (`token`, `authorization`, `password`, `apiKey`, `fileContent`, etc.) are redacted before they hit disk. Rotates at 10 MB, keeps 5 historical files.
325
+
326
+ Disable with `"audit": { "enabled": false }` at the top level of `config.json`.
327
+
328
+ ### Rate limiting
329
+
330
+ Layered in-memory token buckets prevent runaway loops. Defaults:
331
+
332
+ - **global:** 60 writes/minute
333
+ - **per-instance:** 30 writes/minute
334
+ - **destructive tools** (`*_delete_*`, `jira_remove_*`, `confluence_delete_*`): 5/minute
335
+
336
+ On limit hit the tool call fails immediately with a `Rate limit exceeded` error — no sleeping, no queueing. Reads bypass the limiter entirely. Dry-runs don't consume tokens.
337
+
338
+ Override or disable in `config.json`:
339
+
340
+ ```json
341
+ {
342
+ "rateLimit": {
343
+ "enabled": true,
344
+ "global": 120,
345
+ "perInstance": 60,
346
+ "destructive": 10
347
+ }
348
+ }
349
+ ```
350
+
351
+ ## License
352
+
353
+ MIT
354
+
355
+ ## Related
356
+
357
+ - [figma-mcp](https://github.com/rui-branco/figma-mcp) - Figma MCP server (works with any MCP-compatible AI client)
358
+ - [Model Context Protocol](https://modelcontextprotocol.io/) - MCP specification