@stubbedev/atlassian-mcp 0.5.9 → 0.5.11
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 +94 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,15 +13,14 @@ 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:
|
|
17
|
-
| `complete_work` | Close out finished work: merges the open PR and transitions the Jira ticket to Done |
|
|
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
|
+
| `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
|
|
20
20
|
|
|
21
21
|
| Tool | Description |
|
|
22
22
|
|---|---|
|
|
23
|
-
| `git_get_context` | Branch, upstream state, remote URL, recent commits, working tree status, diff stat, and Jira keys in branch name |
|
|
24
|
-
| `git_get_diff` | Diff of uncommitted changes or between two refs; supports paging via `charOffset` |
|
|
23
|
+
| `git_get_context` | Branch, upstream state, remote URL, recent commits, working tree status, diff stat, and Jira keys in branch name. Pass `fromRef`/`toRef` for a diff between refs instead, paged via `charOffset` |
|
|
25
24
|
|
|
26
25
|
### Jira
|
|
27
26
|
|
|
@@ -29,23 +28,31 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
|
|
|
29
28
|
|---|---|
|
|
30
29
|
| `jira_search` | Discover resources: `issues`, `projects`, `issue_types`, `boards`, `sprints`, `board_overview`, `versions`, `components`, `fields`, or `users` via `resource` param |
|
|
31
30
|
| `jira_get` | Full details for one issue: summary, description, status, sprint, transitions, comments, and attachment list |
|
|
32
|
-
| `
|
|
33
|
-
| `jira_mutate` | Create, update, transition, comment, link, add to sprint, or log work — all in one call |
|
|
34
|
-
| `jira_comment` | Add, update, or delete a comment on an issue (`action`: `add` / `update` / `delete`) |
|
|
35
|
-
| `jira_version` | Manage fix versions/releases (`action`: `create` / `update` / `release` / `archive` / `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 |
|
|
36
32
|
|
|
37
33
|
### Bitbucket
|
|
38
34
|
|
|
39
35
|
| Tool | Description |
|
|
40
36
|
|---|---|
|
|
41
|
-
| `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` |
|
|
42
38
|
| `bitbucket_get_pr` | Full PR details: metadata, commits, comments, blockers, build status, optional diff, and any attachments referenced from the description or comments |
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `bitbucket_get_file` | Raw file content from Bitbucket at a branch, tag, or commit |
|
|
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. `pending=true` posts an unpublished draft-review comment |
|
|
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` |
|
|
47
42
|
| `bitbucket_pr_tasks` | Manage PR tasks (checklist items): `list`, `create`, `resolve`, `reopen`, `delete` |
|
|
48
43
|
|
|
44
|
+
### Shared
|
|
45
|
+
|
|
46
|
+
| Tool | Description |
|
|
47
|
+
|---|---|
|
|
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
|
+
|
|
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
|
+
|
|
49
56
|
### Natural language examples
|
|
50
57
|
|
|
51
58
|
- "what am I working on?" → `get_dev_context`
|
|
@@ -63,9 +70,9 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
|
|
|
63
70
|
- "what's in the current sprint?" → `jira_search` with `resource=board_overview`
|
|
64
71
|
- "move FOO-123 to In Progress" → `jira_mutate` with `transitionName="In Progress"`
|
|
65
72
|
- "log 2h on FOO-123" → `jira_mutate` with `worklog`
|
|
66
|
-
- "create version 9.1.0 in PAY" → `
|
|
73
|
+
- "create version 9.1.0 in PAY" → `jira_mutate` with `version.action=create`, `version.projectKey=PAY`, `version.name=9.1.0`
|
|
67
74
|
- "list releases for PAY" → `jira_search` with `resource=versions`, `project=PAY`
|
|
68
|
-
- "release version 12345" → `
|
|
75
|
+
- "release version 12345" → `jira_mutate` with `version.action=release`, `version.id=12345`
|
|
69
76
|
- "set fix version 9.1.0 on FOO-123" → `jira_mutate` with `update.fixVersion=9.1.0`
|
|
70
77
|
- "create a task under epic FOO-100" → `jira_mutate` with `create.issueType=Task`, `create.parent=FOO-100` (auto-detects Epic and sets Epic Link)
|
|
71
78
|
- "move FOO-123 under epic FOO-100" → `jira_mutate` with `update.epicLink=FOO-100`
|
|
@@ -75,6 +82,38 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
|
|
|
75
82
|
|
|
76
83
|
---
|
|
77
84
|
|
|
85
|
+
## What the server enforces
|
|
86
|
+
|
|
87
|
+
These are guarantees in the code, not advice in a tool description — a client
|
|
88
|
+
cannot get them wrong, and they need no prompting:
|
|
89
|
+
|
|
90
|
+
- **Arguments are validated before a call runs.** Enum values and required
|
|
91
|
+
fields are checked against each tool's schema, with case and `-`/`_`
|
|
92
|
+
differences normalised. An unknown `action`/`resource` is an error, never a
|
|
93
|
+
silent fallback to some default branch of the handler.
|
|
94
|
+
- **Names are resolved before anything is written.** Jira `assignee`/`reporter`,
|
|
95
|
+
components and fix versions, and Bitbucket reviewers are checked first; a bad
|
|
96
|
+
one comes back with the valid options instead of an opaque 400.
|
|
97
|
+
- **Markdown is converted to Jira wiki markup** on every Jira write (comments,
|
|
98
|
+
descriptions, worklogs). Text that is already wiki markup is left alone.
|
|
99
|
+
- **PR comment hygiene:** one reply per thread per author, no duplicate of a
|
|
100
|
+
comment you already posted, no new top-level comment on a PR you authored
|
|
101
|
+
(`asAuthor=true` to override), no tasks via `severity`, no emoji, and bare
|
|
102
|
+
`#123` references are rewritten as links to that comment.
|
|
103
|
+
- **Inline comments anchor to what was reviewed.** Reading a PR records the
|
|
104
|
+
commit pair for that session; inline comments bind to it and are remapped onto
|
|
105
|
+
current head when the branch has moved, so a comment never lands on unrelated
|
|
106
|
+
code.
|
|
107
|
+
- **Reviewers are never dropped by accident** — an update that would remove one
|
|
108
|
+
needs `update.replaceReviewers=true`.
|
|
109
|
+
- **`complete_work` will not merge** while reviewers have not approved or a build
|
|
110
|
+
on the PR head has failed, unless `force=true`.
|
|
111
|
+
- **Truncated output always says how to continue**, naming the argument that
|
|
112
|
+
fetches the rest. `bitbucket_get_file` also states the path and ref it read,
|
|
113
|
+
so reading the wrong branch is visible rather than silent.
|
|
114
|
+
- **Tool annotations** (`readOnlyHint`, `destructiveHint`, `idempotentHint`) are
|
|
115
|
+
published for every tool, so hosts can gate confirmation on metadata.
|
|
116
|
+
|
|
78
117
|
## Setup
|
|
79
118
|
|
|
80
119
|
### 1. Create a config file
|
|
@@ -104,7 +143,7 @@ The `$schema` field is optional but enables editor autocomplete and validation.
|
|
|
104
143
|
- Jira: `project` (alias of `projectKey`)
|
|
105
144
|
- Bitbucket: `project` and `repo` (aliases of `projectKey` and `repoSlug`)
|
|
106
145
|
- For Bitbucket tools, `projectKey` and `repoSlug` are usually auto-detected from your local `origin` remote.
|
|
107
|
-
- `
|
|
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.
|
|
108
147
|
- Jira project-scoped calls accept `projectKey` and work best when provided.
|
|
109
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.
|
|
110
149
|
|
|
@@ -274,15 +313,16 @@ ATLASSIAN_MCP_HTTP=1 atlassian-mcp # same, via env
|
|
|
274
313
|
`initialize` mints a session and returns an `Mcp-Session-Id` header, which the client
|
|
275
314
|
**must** echo on every subsequent request and on the SSE stream. Requests with a
|
|
276
315
|
missing/unknown/expired session id get **HTTP 404** so the client re-initializes
|
|
277
|
-
(standard MCP-client behaviour). Each connected client/worktree is an isolated session
|
|
316
|
+
(standard MCP-client behaviour). Each connected client/worktree is an isolated session;
|
|
317
|
+
per-session state (cached roots, PR review anchors) is dropped once the session ends.
|
|
278
318
|
- **Auth:** on a loopback bind no token is needed. Binding a non-loopback address
|
|
279
319
|
**requires** `ATLASSIAN_MCP_HTTP_TOKEN` (sent by clients as `Authorization: Bearer …`);
|
|
280
320
|
the server refuses to start otherwise. Terminate TLS at your proxy.
|
|
281
321
|
- **`GET /healthz`** is an unauthenticated liveness probe (returns `ok`) for proxies/load
|
|
282
|
-
balancers.
|
|
322
|
+
balancers.
|
|
283
323
|
|
|
284
324
|
**Repo context comes from the client, not the server's working directory.** Tools that
|
|
285
|
-
need a repo (
|
|
325
|
+
need a repo (`git_get_context`, `get_dev_context`, `start_work`, `complete_work`, and
|
|
286
326
|
Bitbucket project/repo auto-detection) resolve it in this order: an explicit `repoPath`
|
|
287
327
|
argument → a **root pinned via request header** (see below) → the client's **MCP workspace
|
|
288
328
|
roots** (the server asks via `roots/list`, caches per session, and refreshes on
|
|
@@ -300,12 +340,19 @@ round-trip (and working even when the client never advertised the `roots` capabi
|
|
|
300
340
|
Send a `file://` URI or absolute path (comma-separated for multiple; first git repo wins):
|
|
301
341
|
|
|
302
342
|
```
|
|
343
|
+
X-Repo-Root: /srv/myrepo
|
|
303
344
|
X-Mcp-Root: file:///srv/myrepo
|
|
304
345
|
X-Mcp-Roots: /srv/a, /srv/b
|
|
305
346
|
```
|
|
306
347
|
|
|
307
|
-
Accepted header names: `X-
|
|
308
|
-
is authoritative — it takes precedence over
|
|
348
|
+
Accepted header names, in precedence order: `X-Repo-Root`, `X-Mcp-Roots`, `X-Mcp-Root`,
|
|
349
|
+
`Mcp-Roots`, `Mcp-Root`. A header value is authoritative — it takes precedence over
|
|
350
|
+
`roots/list` and survives `list_changed`.
|
|
351
|
+
|
|
352
|
+
> **Protocol note:** MCP revision **2026-07-28** (SEP-2322/2575) forbids server-initiated
|
|
353
|
+
> JSON-RPC requests, so `roots/list` is unavailable on that revision — the server says so
|
|
354
|
+
> explicitly instead of hanging. On 2026-07-28 clients, a root **header** (or an explicit
|
|
355
|
+
> `repoPath` / `projectKey`+`repoSlug`) is the only way to give the server repo context.
|
|
309
356
|
|
|
310
357
|
Client config for an already-running HTTP server (Claude Code example):
|
|
311
358
|
|
|
@@ -315,7 +362,7 @@ claude mcp add --transport http atlassian http://127.0.0.1:7337/mcp
|
|
|
315
362
|
|
|
316
363
|
### Attachment decoding pipeline
|
|
317
364
|
|
|
318
|
-
The
|
|
365
|
+
The `get_attachment` tool decodes binary attachments into model-readable content before returning them:
|
|
319
366
|
|
|
320
367
|
| Input | What gets returned | How |
|
|
321
368
|
| --- | --- | --- |
|
|
@@ -365,16 +412,20 @@ On a pushed `v*` tag, `.github/workflows/publish.yml` cross-compiles the Go bina
|
|
|
365
412
|
OS/arch targets, attaches them to a GitHub release, and publishes the npm wrapper (which
|
|
366
413
|
downloads the matching binary on install).
|
|
367
414
|
|
|
368
|
-
Release flow:
|
|
415
|
+
Release flow (`just` drives it; it refuses to run on a dirty tree):
|
|
369
416
|
|
|
370
417
|
```bash
|
|
371
|
-
#
|
|
372
|
-
|
|
373
|
-
git push origin HEAD --follow-tags
|
|
418
|
+
just release-preview # show the next patch/minor/major versions
|
|
419
|
+
just release-patch # or release-minor / release-major
|
|
374
420
|
```
|
|
375
421
|
|
|
376
|
-
`
|
|
377
|
-
|
|
422
|
+
`just release-<level>` bumps the version in `package.json`, re-syncs the Nix `vendorHash`
|
|
423
|
+
(`just sync-flake`), runs the gates (`just check`), commits `release: vX.Y.Z`, tags, and
|
|
424
|
+
pushes both the branch and the tag. The tag push triggers `publish.yml`.
|
|
425
|
+
|
|
426
|
+
`package.json` is the single source of truth for the version: the binary embeds it via
|
|
427
|
+
`go:embed` (no `-ldflags`) and `flake.nix` reads it, so one bump moves everything.
|
|
428
|
+
The equivalent npm scripts (`npm run release:patch` / `:minor` / `:major`) still work.
|
|
378
429
|
|
|
379
430
|
- The workflow is configured for npm Trusted Publisher (OIDC), so no `NPM_TOKEN` secret is required
|
|
380
431
|
|
|
@@ -424,20 +475,24 @@ Paste the token as the `token` value under `bitbucket` in your config file.
|
|
|
424
475
|
|
|
425
476
|
The server is a single Go module at the repo root (no `src/` tree).
|
|
426
477
|
|
|
478
|
+
Tasks live in the `justfile` and mirror the CI gates, so a green `just check` predicts
|
|
479
|
+
green CI:
|
|
480
|
+
|
|
427
481
|
```bash
|
|
428
|
-
#
|
|
429
|
-
|
|
482
|
+
just # list tasks
|
|
483
|
+
just check # vet + test + build (what ci.yml runs)
|
|
484
|
+
just fmt # gofmt -w .
|
|
485
|
+
just sync-flake # recompute the Nix vendorHash after a dependency change
|
|
430
486
|
|
|
431
|
-
#
|
|
487
|
+
# Or the raw commands
|
|
488
|
+
go build -o atlassian-mcp .
|
|
432
489
|
./atlassian-mcp --config /path/to/config.json
|
|
490
|
+
go vet ./... && go test ./...
|
|
433
491
|
|
|
434
|
-
#
|
|
435
|
-
go vet ./...
|
|
436
|
-
go test ./...
|
|
437
|
-
|
|
438
|
-
# Test the tool list
|
|
439
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ./atlassian-mcp
|
|
440
|
-
|
|
441
|
-
# Quick release smoke check (build + tools/list validation)
|
|
492
|
+
# Quick release smoke check (build + tools/list validation; CI also does a full stdio handshake)
|
|
442
493
|
npm run smoke
|
|
443
494
|
```
|
|
495
|
+
|
|
496
|
+
Tool schemas live in `tools.json` (embedded into the binary) and the MCP protocol layer is
|
|
497
|
+
the official [`modelcontextprotocol/go-sdk`](https://github.com/modelcontextprotocol/go-sdk);
|
|
498
|
+
the Go files at the repo root hold the tool logic.
|