@stubbedev/atlassian-mcp 0.5.10 → 0.5.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.
- package/README.md +234 -50
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
|
|
|
13
13
|
| Tool | Description |
|
|
14
14
|
|---|---|
|
|
15
15
|
| `get_dev_context` | Master entry point: git state + linked Jira ticket + open PR with reviewer/blocker status and next-step hints |
|
|
16
|
-
| `start_work` | Start a Jira ticket:
|
|
16
|
+
| `start_work` | Start a Jira ticket: resolves it by key or free-text `query` (with a picker when several match), creates a local branch (`feature/FOO-123-slug`) off the repository default branch, fetches the project README from Bitbucket so commit/PR conventions are in context, and optionally transitions the ticket |
|
|
17
17
|
| `complete_work` | Close out finished work: merges the open PR and transitions the Jira ticket to Done. Refuses to merge while reviewers have not approved or a build failed (`force=true` overrides) |
|
|
18
18
|
|
|
19
19
|
### Git
|
|
@@ -28,16 +28,16 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
|
|
|
28
28
|
|---|---|
|
|
29
29
|
| `jira_search` | Discover resources: `issues`, `projects`, `issue_types`, `boards`, `sprints`, `board_overview`, `versions`, `components`, `fields`, or `users` via `resource` param |
|
|
30
30
|
| `jira_get` | Full details for one issue: summary, description, status, sprint, transitions, comments, and attachment list |
|
|
31
|
-
| `jira_mutate` | Create, update, transition, comment (`commentAction`: `add` / `update` / `delete`),
|
|
31
|
+
| `jira_mutate` | Create, update, transition, comment (`commentAction`: `add` / `update` / `delete`), upload local files as attachments, link, add to sprint, log work, change issue type, set any custom field by name (`create.customFields` / `update.customFields`), or manage a fix version (`version.action`: `create` / `update` / `release` / `archive` / `delete`) — several in one call. Markdown in any text field is converted to Jira wiki markup |
|
|
32
32
|
|
|
33
33
|
### Bitbucket
|
|
34
34
|
|
|
35
35
|
| Tool | Description |
|
|
36
36
|
|---|---|
|
|
37
|
-
| `bitbucket_search` | Discover resources: `pull_requests` (default), `repos`, `branches`, or `users` via `resource` param; `mine=true` for your inbox |
|
|
37
|
+
| `bitbucket_search` | Discover resources: `pull_requests` (default), `repos`, `branches`, or `users` via `resource` param; `mine=true` for your inbox, narrowed with `role=author` / `reviewer` / `participant` |
|
|
38
38
|
| `bitbucket_get_pr` | Full PR details: metadata, commits, comments, blockers, build status, optional diff, and any attachments referenced from the description or comments |
|
|
39
39
|
| `bitbucket_mutate` | Create/update a PR, or perform lifecycle actions: `approve`, `unapprove`, `needs_work`, `merge`, `decline`. Reviewer names are verified against Bitbucket, and an update that would drop existing reviewers needs `update.replaceReviewers=true` |
|
|
40
|
-
| `bitbucket_comment` | Add, update, or delete a PR comment; for code changes use `suggestion` so Bitbucket shows Apply suggestion. Enforced here: one reply per thread, no new top-level comment on your own PR (`asAuthor=true` to override), `#123` references rewritten as links |
|
|
40
|
+
| `bitbucket_comment` | Add, update, or delete a PR comment; for code changes use `suggestion` so Bitbucket shows Apply suggestion. Enforced here: one reply per thread, no new top-level comment on your own PR (`asAuthor=true` to override), `#123` references rewritten as links. `pending=true` posts an unpublished draft-review comment |
|
|
41
41
|
| `bitbucket_get_file` | Raw file content at a branch, tag, or commit — or pass `prId` to read the PR source branch. Every response names the path and ref it came from, and pages via `maxChars`/`charOffset` |
|
|
42
42
|
| `bitbucket_pr_tasks` | Manage PR tasks (checklist items): `list`, `create`, `resolve`, `reopen`, `delete` |
|
|
43
43
|
|
|
@@ -47,6 +47,12 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
|
|
|
47
47
|
|---|---|
|
|
48
48
|
| `get_attachment` | Fetch an attachment by ID from Jira (`source=jira`, IDs from `jira_get`) or Bitbucket (`source=bitbucket`, IDs from `bitbucket_get_pr`). Images, videos, animated images (GIF/APNG/animated WebP), audio, and PDFs are decoded inline so the model can see/hear them; text/JSON inline. Oversized or non-renderable attachments are auto-saved to a temp file and the path is returned. `saveTo=/absolute/path` streams the original to disk |
|
|
49
49
|
|
|
50
|
+
### Resources
|
|
51
|
+
|
|
52
|
+
| URI | Description |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `dev-context://current` | The same live report as `get_dev_context` — branch state, linked Jira tickets, open PR — as an MCP resource. Re-read it for fresh state instead of spending another tool call. The repo is resolved per read from the caller's session, so the static URI serves whatever workspace the client is in |
|
|
55
|
+
|
|
50
56
|
### Natural language examples
|
|
51
57
|
|
|
52
58
|
- "what am I working on?" → `get_dev_context`
|
|
@@ -137,7 +143,7 @@ The `$schema` field is optional but enables editor autocomplete and validation.
|
|
|
137
143
|
- Jira: `project` (alias of `projectKey`)
|
|
138
144
|
- Bitbucket: `project` and `repo` (aliases of `projectKey` and `repoSlug`)
|
|
139
145
|
- For Bitbucket tools, `projectKey` and `repoSlug` are usually auto-detected from your local `origin` remote.
|
|
140
|
-
- `
|
|
146
|
+
- `bitbucket_mutate` with `create` auto-detects `fromBranch` from your current branch and returns the existing open PR if one already exists for that branch. Other Bitbucket tools auto-target that PR when `prId` is omitted.
|
|
141
147
|
- Jira project-scoped calls accept `projectKey` and work best when provided.
|
|
142
148
|
- If `projectKey` is omitted for Jira issue creation/type lookup, the server tries to infer it from your current branch ticket key, falls back to auto-select when only one project is visible, and otherwise returns a numbered project list to pick from.
|
|
143
149
|
|
|
@@ -150,12 +156,23 @@ BITBUCKET_URL=https://bitbucket.example.com
|
|
|
150
156
|
BITBUCKET_ACCESS_TOKEN=your-bitbucket-personal-access-token
|
|
151
157
|
```
|
|
152
158
|
|
|
153
|
-
Config is resolved in this order: `--config <path>` CLI arg → `ATLASSIAN_MCP_CONFIG` env var → `~/.atlassian-mcp.json` → `$XDG_CONFIG_HOME/atlassian-mcp/config.json` (default `~/.config/atlassian-mcp/config.json`) → `.atlassian-mcp.json` in cwd → environment variables.
|
|
159
|
+
Config is resolved in this order: `--config <path>` CLI arg → `ATLASSIAN_MCP_CONFIG` env var → `~/.atlassian-mcp.json` → `$XDG_CONFIG_HOME/atlassian-mcp/config.json` (default `~/.config/atlassian-mcp/config.json`) → `.atlassian-mcp.json` in cwd → environment variables. A leading `~` in the first two is expanded by the server, so a client that spawns it without a shell still resolves the path. Within a file, per-field: a value in the config file wins, environment variables fill the gaps.
|
|
154
160
|
|
|
155
161
|
### 2. Connect to your AI tool
|
|
156
162
|
|
|
157
163
|
No cloning or building required — just point your tool at `npx @stubbedev/atlassian-mcp@latest` and it will install and run automatically.
|
|
158
164
|
|
|
165
|
+
CLI-driven clients need one line:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
claude mcp add atlassian -- npx -y @stubbedev/atlassian-mcp@latest # Claude Code
|
|
169
|
+
codex mcp add atlassian -- npx -y @stubbedev/atlassian-mcp@latest # Codex CLI / IDE / app
|
|
170
|
+
code --add-mcp '{"name":"atlassian","command":"npx","args":["-y","@stubbedev/atlassian-mcp@latest"]}' # VS Code
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Desktop apps: **Claude Desktop** installs a one-click [`.mcpb` bundle](#claude-desktop) —
|
|
174
|
+
no Node, no JSON. Everything else takes a config file; see below.
|
|
175
|
+
|
|
159
176
|
> Note: `--prefer-online` can break MCP startup in some clients. Keep the command simple and use the update steps below when you want to refresh.
|
|
160
177
|
|
|
161
178
|
---
|
|
@@ -168,6 +185,66 @@ claude mcp add atlassian -- npx -y @stubbedev/atlassian-mcp@latest --config ~/.a
|
|
|
168
185
|
|
|
169
186
|
---
|
|
170
187
|
|
|
188
|
+
#### Claude Desktop
|
|
189
|
+
|
|
190
|
+
**One-click (recommended).** Grab the `.mcpb` bundle for your platform from the
|
|
191
|
+
[latest release](https://github.com/stubbedev/atlassian-mcp/releases/latest) —
|
|
192
|
+
`atlassian-mcp_darwin_arm64.mcpb` (Apple Silicon), `atlassian-mcp_darwin_amd64.mcpb`
|
|
193
|
+
(Intel Mac), `atlassian-mcp_windows_amd64.mcpb` — then **double-click it**, drag it onto the
|
|
194
|
+
Claude Desktop window, or use **Settings → Extensions → Advanced settings → Install
|
|
195
|
+
Extension…**. The install dialog asks for Jira/Bitbucket URL and token (tokens are stored
|
|
196
|
+
by Claude Desktop, not in a file) plus **Repository**, the working tree the git and PR tools
|
|
197
|
+
default to. Leaving URL/token blank reuses an existing `~/.atlassian-mcp.json`.
|
|
198
|
+
|
|
199
|
+
The bundle carries the binary, so there is no Node, no `npx`, no `PATH` to fix and no JSON
|
|
200
|
+
to edit. [MCP Bundles](https://github.com/modelcontextprotocol/mcpb) are a Claude Desktop
|
|
201
|
+
feature today; other clients use the config files below.
|
|
202
|
+
|
|
203
|
+
**Manual config.** Claude Desktop is a GUI app: it launches the server with a minimal
|
|
204
|
+
`PATH`, no shell, and `/` as the working directory. So `command` must be an **absolute
|
|
205
|
+
path** (a bare `npx` fails with `spawn npx ENOENT`), a `.env` file or relative
|
|
206
|
+
`--config` path never resolves, and nothing expands `~` for you — the server expands a
|
|
207
|
+
leading `~` in `--config` / `ATLASSIAN_MCP_CONFIG` itself, but a client that inserts `~`
|
|
208
|
+
anywhere else will not. Config file:
|
|
209
|
+
|
|
210
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
211
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"mcpServers": {
|
|
216
|
+
"atlassian": {
|
|
217
|
+
"command": "/absolute/path/to/atlassian-mcp",
|
|
218
|
+
"env": {
|
|
219
|
+
"JIRA_URL": "https://jira.example.com",
|
|
220
|
+
"JIRA_ACCESS_TOKEN": "your-jira-personal-access-token",
|
|
221
|
+
"BITBUCKET_URL": "https://bitbucket.example.com",
|
|
222
|
+
"BITBUCKET_ACCESS_TOKEN": "your-bitbucket-personal-access-token",
|
|
223
|
+
"ATLASSIAN_MCP_REPO_ROOT": "/Users/you/code/my-repo"
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
To keep `npx`, set `command` to the absolute path of your launcher (`which npx`, e.g.
|
|
231
|
+
`/opt/homebrew/bin/npx`) with `"args": ["-y", "@stubbedev/atlassian-mcp@latest"]`.
|
|
232
|
+
|
|
233
|
+
`ATLASSIAN_MCP_REPO_ROOT` is what makes `get_dev_context`, `git_get_context`,
|
|
234
|
+
`start_work`, `complete_work` and Bitbucket repo auto-detection usable here: a desktop app
|
|
235
|
+
has no workspace, so it advertises no MCP roots and there is no useful cwd to fall back to.
|
|
236
|
+
Comma-separate several worktrees (first git repo wins); a per-call `repoPath` still
|
|
237
|
+
overrides it.
|
|
238
|
+
|
|
239
|
+
On Windows, Git is frequently absent from a GUI app's `PATH`. The server probes the usual
|
|
240
|
+
install locations before giving up; set `ATLASSIAN_MCP_GIT_PATH` if yours lives elsewhere.
|
|
241
|
+
|
|
242
|
+
Server stderr is logged to `~/Library/Logs/Claude/mcp-server-atlassian.log` (macOS) or
|
|
243
|
+
`%APPDATA%\Claude\logs\mcp-server-atlassian.log` (Windows) — read that first when a
|
|
244
|
+
connection fails.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
171
248
|
#### Cursor
|
|
172
249
|
|
|
173
250
|
Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-only):
|
|
@@ -231,34 +308,116 @@ Add to `opencode.json` in your project root (or `~/.config/opencode/opencode.jso
|
|
|
231
308
|
"mcp": {
|
|
232
309
|
"atlassian": {
|
|
233
310
|
"type": "local",
|
|
234
|
-
"command": ["npx", "-y", "@stubbedev/atlassian-mcp@latest", "--config", "/home/you/.atlassian-mcp.json"]
|
|
311
|
+
"command": ["npx", "-y", "@stubbedev/atlassian-mcp@latest", "--config", "/home/you/.atlassian-mcp.json"],
|
|
312
|
+
"environment": { "ATLASSIAN_MCP_REPO_ROOT": "/home/you/code/my-repo" }
|
|
235
313
|
}
|
|
236
314
|
}
|
|
237
315
|
}
|
|
238
316
|
```
|
|
239
317
|
|
|
318
|
+
`environment` also accepts the `JIRA_*` / `BITBUCKET_*` variables if you would rather not
|
|
319
|
+
keep a config file. Set `"type": "remote"` with `"url"` and `"headers"` to point at a
|
|
320
|
+
shared [HTTP server](#running-as-an-http-server-shared--behind-a-proxy) instead.
|
|
321
|
+
|
|
240
322
|
---
|
|
241
323
|
|
|
242
|
-
#### Codex CLI
|
|
324
|
+
#### Codex (CLI, IDE extension, app)
|
|
325
|
+
|
|
326
|
+
One command — it writes the config for all three:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
codex mcp add atlassian -- npx -y @stubbedev/atlassian-mcp@latest
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Or edit `~/.codex/config.toml` directly (`.codex/config.toml` in a trusted project for a
|
|
333
|
+
project-scoped server). Note the TOML table name is `mcp_servers`, with an underscore:
|
|
334
|
+
|
|
335
|
+
```toml
|
|
336
|
+
[mcp_servers.atlassian]
|
|
337
|
+
command = "npx"
|
|
338
|
+
args = ["-y", "@stubbedev/atlassian-mcp@latest", "--config", "/home/you/.atlassian-mcp.json"]
|
|
339
|
+
|
|
340
|
+
# Optional — instead of a config file, and to pin the repo for the git/PR tools:
|
|
341
|
+
[mcp_servers.atlassian.env]
|
|
342
|
+
JIRA_URL = "https://jira.example.com"
|
|
343
|
+
JIRA_ACCESS_TOKEN = "…"
|
|
344
|
+
ATLASSIAN_MCP_REPO_ROOT = "/home/you/code/my-repo"
|
|
345
|
+
```
|
|
243
346
|
|
|
244
|
-
|
|
347
|
+
Codex picks the transport from the keys present: `command` means stdio, `url` means
|
|
348
|
+
streamable HTTP. To share one [HTTP server](#running-as-an-http-server-shared--behind-a-proxy):
|
|
349
|
+
|
|
350
|
+
```toml
|
|
351
|
+
[mcp_servers.atlassian]
|
|
352
|
+
url = "http://127.0.0.1:7337/mcp"
|
|
353
|
+
bearer_token_env_var = "ATLASSIAN_MCP_HTTP_TOKEN"
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
#### VS Code / GitHub Copilot
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
code --add-mcp '{"name":"atlassian","command":"npx","args":["-y","@stubbedev/atlassian-mcp@latest"]}'
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Or commit `.vscode/mcp.json` with a `servers` object of the same shape to share it with the
|
|
365
|
+
repo.
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
#### Any other MCP-compatible tool
|
|
370
|
+
|
|
371
|
+
Most clients accept the Claude Desktop shape — an `mcpServers` object keyed by name, with
|
|
372
|
+
`command`, `args` and `env`:
|
|
373
|
+
|
|
374
|
+
```json
|
|
375
|
+
{
|
|
376
|
+
"mcpServers": {
|
|
377
|
+
"atlassian": {
|
|
378
|
+
"command": "npx",
|
|
379
|
+
"args": ["-y", "@stubbedev/atlassian-mcp@latest"],
|
|
380
|
+
"env": {
|
|
381
|
+
"JIRA_URL": "https://jira.example.com",
|
|
382
|
+
"JIRA_ACCESS_TOKEN": "…",
|
|
383
|
+
"BITBUCKET_URL": "https://bitbucket.example.com",
|
|
384
|
+
"BITBUCKET_ACCESS_TOKEN": "…",
|
|
385
|
+
"ATLASSIAN_MCP_REPO_ROOT": "/home/you/code/my-repo"
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
LM Studio uses exactly that shape in its own `mcp.json` (edit it from the app's plugin
|
|
393
|
+
panel); Cherry Studio, Witsy, Jan and 5ire have in-app MCP dialogs with the same fields.
|
|
394
|
+
|
|
395
|
+
Goose is the exception — its `~/.config/goose/config.yaml` uses `extensions:` with `cmd`
|
|
396
|
+
rather than `command`:
|
|
245
397
|
|
|
246
398
|
```yaml
|
|
247
|
-
|
|
399
|
+
extensions:
|
|
248
400
|
atlassian:
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
401
|
+
enabled: true
|
|
402
|
+
type: stdio
|
|
403
|
+
cmd: npx
|
|
404
|
+
args: ["-y", "@stubbedev/atlassian-mcp@latest"]
|
|
405
|
+
envs:
|
|
406
|
+
ATLASSIAN_MCP_REPO_ROOT: /home/you/code/my-repo
|
|
255
407
|
```
|
|
256
408
|
|
|
409
|
+
Every GUI client brings the caveats from the [Claude Desktop](#claude-desktop) section:
|
|
410
|
+
absolute `command` path, no usable cwd, no MCP roots — so set `ATLASSIAN_MCP_REPO_ROOT`.
|
|
411
|
+
|
|
257
412
|
---
|
|
258
413
|
|
|
259
|
-
####
|
|
414
|
+
#### ChatGPT (desktop / web) — not supported
|
|
260
415
|
|
|
261
|
-
|
|
416
|
+
ChatGPT connectors accept **remote HTTPS MCP servers only** (streamable HTTP or SSE, with
|
|
417
|
+
OAuth or no auth); it cannot spawn a local stdio server. This server's `--http` mode speaks
|
|
418
|
+
the right protocol, but making it work would mean exposing an endpoint that reaches your
|
|
419
|
+
self-hosted Jira/Bitbucket to OpenAI's servers, and ChatGPT offers no place for the static
|
|
420
|
+
bearer token this server uses. Use a client from the list above.
|
|
262
421
|
|
|
263
422
|
### Updating existing installs
|
|
264
423
|
|
|
@@ -275,7 +434,9 @@ Then restart your MCP client.
|
|
|
275
434
|
### Install without npm
|
|
276
435
|
|
|
277
436
|
The server is a single static Go binary. The `npx` path above downloads the prebuilt
|
|
278
|
-
binary for your platform on first run; these alternatives skip Node entirely
|
|
437
|
+
binary for your platform on first run; these alternatives skip Node entirely — as does the
|
|
438
|
+
[`.mcpb` bundle](#claude-desktop) for Claude Desktop, and the per-platform binaries
|
|
439
|
+
attached to every [release](https://github.com/stubbedev/atlassian-mcp/releases/latest):
|
|
279
440
|
|
|
280
441
|
```bash
|
|
281
442
|
# Go toolchain — installs to $GOBIN / $GOPATH/bin
|
|
@@ -286,9 +447,11 @@ nix run github:stubbedev/atlassian-mcp -- --config ~/.atlassian-mcp.json
|
|
|
286
447
|
```
|
|
287
448
|
|
|
288
449
|
Then point your MCP client's `command` at the resulting `atlassian-mcp` binary
|
|
289
|
-
instead of `npx`. On these paths `
|
|
290
|
-
|
|
291
|
-
|
|
450
|
+
instead of `npx`. On these Node-free paths (`go install`, Nix, a release binary or the
|
|
451
|
+
`.mcpb` bundle) `ffmpeg`/`ffprobe` must be available on `PATH` for video and
|
|
452
|
+
animated-image attachments (or set `ATLASSIAN_MCP_FFMPEG_PATH` /
|
|
453
|
+
`ATLASSIAN_MCP_FFPROBE_PATH`); the npm wrapper bundles them automatically. Everything
|
|
454
|
+
else — still images, PDF text, JSON/text — is pure Go and needs nothing extra.
|
|
292
455
|
|
|
293
456
|
### Running as an HTTP server (shared / behind a proxy)
|
|
294
457
|
|
|
@@ -307,19 +470,21 @@ ATLASSIAN_MCP_HTTP=1 atlassian-mcp # same, via env
|
|
|
307
470
|
`initialize` mints a session and returns an `Mcp-Session-Id` header, which the client
|
|
308
471
|
**must** echo on every subsequent request and on the SSE stream. Requests with a
|
|
309
472
|
missing/unknown/expired session id get **HTTP 404** so the client re-initializes
|
|
310
|
-
(standard MCP-client behaviour). Each connected client/worktree is an isolated session
|
|
473
|
+
(standard MCP-client behaviour). Each connected client/worktree is an isolated session;
|
|
474
|
+
per-session state (cached roots, PR review anchors) is dropped once the session ends.
|
|
311
475
|
- **Auth:** on a loopback bind no token is needed. Binding a non-loopback address
|
|
312
476
|
**requires** `ATLASSIAN_MCP_HTTP_TOKEN` (sent by clients as `Authorization: Bearer …`);
|
|
313
477
|
the server refuses to start otherwise. Terminate TLS at your proxy.
|
|
314
478
|
- **`GET /healthz`** is an unauthenticated liveness probe (returns `ok`) for proxies/load
|
|
315
|
-
balancers.
|
|
479
|
+
balancers.
|
|
316
480
|
|
|
317
481
|
**Repo context comes from the client, not the server's working directory.** Tools that
|
|
318
482
|
need a repo (`git_get_context`, `get_dev_context`, `start_work`, `complete_work`, and
|
|
319
483
|
Bitbucket project/repo auto-detection) resolve it in this order: an explicit `repoPath`
|
|
320
|
-
argument → a **root pinned via request header** (see below) →
|
|
321
|
-
|
|
322
|
-
|
|
484
|
+
argument → a **root pinned via request header** (see below) → **`ATLASSIAN_MCP_REPO_ROOT`**
|
|
485
|
+
(comma-separated for several worktrees — the only workspace signal a GUI desktop client
|
|
486
|
+
can give) → the client's **MCP workspace roots** (the server asks via `roots/list`, caches
|
|
487
|
+
per session, and refreshes on `notifications/roots/list_changed`) → the process cwd (stdio
|
|
323
488
|
only). So one shared HTTP server handles many worktrees: each client's own workspace drives
|
|
324
489
|
its calls. When a session exposes **several** roots (multiple worktrees), a tool with no
|
|
325
490
|
`repoPath` uses the first git-repo root; pass `repoPath` (an absolute path, or a worktree
|
|
@@ -333,12 +498,19 @@ round-trip (and working even when the client never advertised the `roots` capabi
|
|
|
333
498
|
Send a `file://` URI or absolute path (comma-separated for multiple; first git repo wins):
|
|
334
499
|
|
|
335
500
|
```
|
|
501
|
+
X-Repo-Root: /srv/myrepo
|
|
336
502
|
X-Mcp-Root: file:///srv/myrepo
|
|
337
503
|
X-Mcp-Roots: /srv/a, /srv/b
|
|
338
504
|
```
|
|
339
505
|
|
|
340
|
-
Accepted header names: `X-
|
|
341
|
-
is authoritative — it takes precedence over
|
|
506
|
+
Accepted header names, in precedence order: `X-Repo-Root`, `X-Mcp-Roots`, `X-Mcp-Root`,
|
|
507
|
+
`Mcp-Roots`, `Mcp-Root`. A header value is authoritative — it takes precedence over
|
|
508
|
+
`roots/list` and survives `list_changed`.
|
|
509
|
+
|
|
510
|
+
> **Protocol note:** MCP revision **2026-07-28** (SEP-2322/2575) forbids server-initiated
|
|
511
|
+
> JSON-RPC requests, so `roots/list` is unavailable on that revision — the server says so
|
|
512
|
+
> explicitly instead of hanging. On 2026-07-28 clients, a root **header** (or an explicit
|
|
513
|
+
> `repoPath` / `projectKey`+`repoSlug`) is the only way to give the server repo context.
|
|
342
514
|
|
|
343
515
|
Client config for an already-running HTTP server (Claude Code example):
|
|
344
516
|
|
|
@@ -370,8 +542,8 @@ pure-Go implementation shell out to external binaries:
|
|
|
370
542
|
- **`ffmpeg` + `ffprobe`** — video and animated-image frame sampling. The npm wrapper bundles
|
|
371
543
|
[`ffmpeg-static`](https://www.npmjs.com/package/ffmpeg-static) /
|
|
372
544
|
[`ffprobe-static`](https://www.npmjs.com/package/ffprobe-static) and injects their paths, so the
|
|
373
|
-
npx install path is zero-config. On
|
|
374
|
-
`ffprobe`) or set the env vars below.
|
|
545
|
+
npx install path is zero-config. On every Node-free path (`go install`, Nix, release binary,
|
|
546
|
+
`.mcpb` bundle), install `ffmpeg` (it provides `ffprobe`) or set the env vars below.
|
|
375
547
|
- **`pdftoppm` (poppler) or `mutool` (MuPDF)** — only needed to rasterize *scanned* PDFs that have no
|
|
376
548
|
extractable text. If neither is on `PATH`, such PDFs are saved to disk instead.
|
|
377
549
|
|
|
@@ -381,6 +553,8 @@ pure-Go implementation shell out to external binaries:
|
|
|
381
553
|
| --- | --- | --- |
|
|
382
554
|
| `ATLASSIAN_MCP_HTTP` | Run as a Streamable HTTP server instead of stdio. `1`/`true` → `127.0.0.1:7337`; or set an explicit `host:port`. Same as `--http`. | unset (stdio) |
|
|
383
555
|
| `ATLASSIAN_MCP_HTTP_TOKEN` | Bearer token for HTTP mode. Optional on loopback binds; **required** on non-loopback binds. | unset |
|
|
556
|
+
| `ATLASSIAN_MCP_REPO_ROOT` | Default workspace root(s) for the git/PR tools, comma-separated. `file://` URIs, absolute paths, `~/…` and Windows drive paths all work. Needed by clients that expose no MCP roots (desktop apps). Overridden by a `repoPath` argument or a root header. | unset |
|
|
557
|
+
| `ATLASSIAN_MCP_GIT_PATH` | Path to the `git` executable. Only needed when `git` is off the host app's `PATH`; the server already probes the usual install locations. | `git` on `PATH` |
|
|
384
558
|
| `ATLASSIAN_MCP_FFMPEG_PATH` | Path to `ffmpeg` binary. | npm: bundled `ffmpeg-static`; otherwise `ffmpeg` on `PATH` |
|
|
385
559
|
| `ATLASSIAN_MCP_FFPROBE_PATH` | Path to `ffprobe` binary. | npm: bundled `ffprobe-static`; otherwise `ffprobe` on `PATH` |
|
|
386
560
|
| `ATLASSIAN_MCP_TMP_TTL_DAYS` | Auto-saved attachments older than this are pruned. | `7` |
|
|
@@ -395,19 +569,25 @@ This package is published to npm as `@stubbedev/atlassian-mcp`.
|
|
|
395
569
|
Use semantic versioning for releases. Breaking tool-surface changes should bump the minor version while `<1.0.0` (for example `0.0.x` -> `0.1.0`).
|
|
396
570
|
|
|
397
571
|
On a pushed `v*` tag, `.github/workflows/publish.yml` cross-compiles the Go binary for 14
|
|
398
|
-
OS/arch targets,
|
|
399
|
-
|
|
572
|
+
OS/arch targets, packs six of them into `.mcpb` bundles for one-click desktop install
|
|
573
|
+
(`packaging/mcpb/pack.sh`, macOS/Windows/Linux × amd64/arm64), attaches everything to a
|
|
574
|
+
GitHub release, and publishes the npm wrapper (which downloads the matching binary on
|
|
575
|
+
install). `just bundle` builds a bundle for the host platform locally.
|
|
400
576
|
|
|
401
|
-
Release flow:
|
|
577
|
+
Release flow (`just` drives it; it refuses to run on a dirty tree):
|
|
402
578
|
|
|
403
579
|
```bash
|
|
404
|
-
#
|
|
405
|
-
|
|
406
|
-
git push origin HEAD --follow-tags
|
|
580
|
+
just release-preview # show the next patch/minor/major versions
|
|
581
|
+
just release-patch # or release-minor / release-major
|
|
407
582
|
```
|
|
408
583
|
|
|
409
|
-
`
|
|
410
|
-
|
|
584
|
+
`just release-<level>` bumps the version in `package.json`, re-syncs the Nix `vendorHash`
|
|
585
|
+
(`just sync-flake`), runs the gates (`just check`), commits `release: vX.Y.Z`, tags, and
|
|
586
|
+
pushes both the branch and the tag. The tag push triggers `publish.yml`.
|
|
587
|
+
|
|
588
|
+
`package.json` is the single source of truth for the version: the binary embeds it via
|
|
589
|
+
`go:embed` (no `-ldflags`) and `flake.nix` reads it, so one bump moves everything.
|
|
590
|
+
The equivalent npm scripts (`npm run release:patch` / `:minor` / `:major`) still work.
|
|
411
591
|
|
|
412
592
|
- The workflow is configured for npm Trusted Publisher (OIDC), so no `NPM_TOKEN` secret is required
|
|
413
593
|
|
|
@@ -457,20 +637,24 @@ Paste the token as the `token` value under `bitbucket` in your config file.
|
|
|
457
637
|
|
|
458
638
|
The server is a single Go module at the repo root (no `src/` tree).
|
|
459
639
|
|
|
640
|
+
Tasks live in the `justfile` and mirror the CI gates, so a green `just check` predicts
|
|
641
|
+
green CI:
|
|
642
|
+
|
|
460
643
|
```bash
|
|
461
|
-
#
|
|
462
|
-
|
|
644
|
+
just # list tasks
|
|
645
|
+
just check # vet + test + build (what ci.yml runs)
|
|
646
|
+
just fmt # gofmt -w .
|
|
647
|
+
just sync-flake # recompute the Nix vendorHash after a dependency change
|
|
463
648
|
|
|
464
|
-
#
|
|
649
|
+
# Or the raw commands
|
|
650
|
+
go build -o atlassian-mcp .
|
|
465
651
|
./atlassian-mcp --config /path/to/config.json
|
|
652
|
+
go vet ./... && go test ./...
|
|
466
653
|
|
|
467
|
-
#
|
|
468
|
-
go vet ./...
|
|
469
|
-
go test ./...
|
|
470
|
-
|
|
471
|
-
# Test the tool list
|
|
472
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ./atlassian-mcp
|
|
473
|
-
|
|
474
|
-
# Quick release smoke check (build + tools/list validation)
|
|
654
|
+
# Quick release smoke check (build + tools/list validation; CI also does a full stdio handshake)
|
|
475
655
|
npm run smoke
|
|
476
656
|
```
|
|
657
|
+
|
|
658
|
+
Tool schemas live in `tools.json` (embedded into the binary) and the MCP protocol layer is
|
|
659
|
+
the official [`modelcontextprotocol/go-sdk`](https://github.com/modelcontextprotocol/go-sdk);
|
|
660
|
+
the Go files at the repo root hold the tool logic.
|