@stubbedev/atlassian-mcp 0.5.8 → 0.5.10

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 (2) hide show
  1. package/README.md +51 -17
  2. 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: fetches it, creates a local branch (`feature/FOO-123-slug`), and optionally transitions the 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: fetches it, creates a local branch (`feature/FOO-123-slug`) off the repository default branch, 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,10 +28,7 @@ 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
- | `jira_get_attachment` | Fetch a Jira attachment by ID. Images, videos, animated images (GIF/APNG/animated WebP), audio, and PDFs are all 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 |
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`), attach, link, add to sprint, log work, 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
 
@@ -40,12 +36,17 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
40
36
  |---|---|
41
37
  | `bitbucket_search` | Discover resources: `pull_requests` (default), `repos`, `branches`, or `users` via `resource` param; `mine=true` for your inbox |
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
- | `bitbucket_get_attachment` | Fetch a repo attachment by ID. Same decoding pipeline as `jira_get_attachment` (images, videos, animated images, audio, PDFs). Oversized or non-renderable attachments are auto-saved to a temp file and the path is returned; `saveTo` streams the original to disk |
44
- | `bitbucket_mutate` | Create/update a PR, or perform lifecycle actions: `approve`, `unapprove`, `needs_work`, `merge`, `decline` |
45
- | `bitbucket_comment` | Add, update, or delete a PR comment; for code changes use `suggestion` so Bitbucket shows Apply suggestion (no trailing text after a suggestion block) |
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 |
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
+
49
50
  ### Natural language examples
50
51
 
51
52
  - "what am I working on?" → `get_dev_context`
@@ -63,17 +64,50 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for **s
63
64
  - "what's in the current sprint?" → `jira_search` with `resource=board_overview`
64
65
  - "move FOO-123 to In Progress" → `jira_mutate` with `transitionName="In Progress"`
65
66
  - "log 2h on FOO-123" → `jira_mutate` with `worklog`
66
- - "create version 9.1.0 in PAY" → `jira_version` with `action=create`, `projectKey=PAY`, `name=9.1.0`
67
+ - "create version 9.1.0 in PAY" → `jira_mutate` with `version.action=create`, `version.projectKey=PAY`, `version.name=9.1.0`
67
68
  - "list releases for PAY" → `jira_search` with `resource=versions`, `project=PAY`
68
- - "release version 12345" → `jira_version` with `action=release`, `id=12345`
69
+ - "release version 12345" → `jira_mutate` with `version.action=release`, `version.id=12345`
69
70
  - "set fix version 9.1.0 on FOO-123" → `jira_mutate` with `update.fixVersion=9.1.0`
70
71
  - "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
72
  - "move FOO-123 under epic FOO-100" → `jira_mutate` with `update.epicLink=FOO-100`
72
73
  - "create an epic" → `jira_mutate` with `create.issueType=Epic` (Epic Name defaults to the summary)
73
- - "set story points to 5" → `jira_mutate` with `update.customFields={"Story Points": 5}`; list the fields with `jira_search resource=fields`
74
+ - "set story points to 5" → `jira_mutate` with `update.customFields={"Story Points": 5}` values are plain (option label, username, date, array of labels); the server wraps them per the field schema
75
+ - "what can I set on this ticket / on an Epic?" → `jira_search resource=fields` with `issueKey=FOO-123` (edit screen) or `project=FOO`+`issueType=Epic` (create screen): required and optional fields, value shapes, allowed values
74
76
 
75
77
  ---
76
78
 
79
+ ## What the server enforces
80
+
81
+ These are guarantees in the code, not advice in a tool description — a client
82
+ cannot get them wrong, and they need no prompting:
83
+
84
+ - **Arguments are validated before a call runs.** Enum values and required
85
+ fields are checked against each tool's schema, with case and `-`/`_`
86
+ differences normalised. An unknown `action`/`resource` is an error, never a
87
+ silent fallback to some default branch of the handler.
88
+ - **Names are resolved before anything is written.** Jira `assignee`/`reporter`,
89
+ components and fix versions, and Bitbucket reviewers are checked first; a bad
90
+ one comes back with the valid options instead of an opaque 400.
91
+ - **Markdown is converted to Jira wiki markup** on every Jira write (comments,
92
+ descriptions, worklogs). Text that is already wiki markup is left alone.
93
+ - **PR comment hygiene:** one reply per thread per author, no duplicate of a
94
+ comment you already posted, no new top-level comment on a PR you authored
95
+ (`asAuthor=true` to override), no tasks via `severity`, no emoji, and bare
96
+ `#123` references are rewritten as links to that comment.
97
+ - **Inline comments anchor to what was reviewed.** Reading a PR records the
98
+ commit pair for that session; inline comments bind to it and are remapped onto
99
+ current head when the branch has moved, so a comment never lands on unrelated
100
+ code.
101
+ - **Reviewers are never dropped by accident** — an update that would remove one
102
+ needs `update.replaceReviewers=true`.
103
+ - **`complete_work` will not merge** while reviewers have not approved or a build
104
+ on the PR head has failed, unless `force=true`.
105
+ - **Truncated output always says how to continue**, naming the argument that
106
+ fetches the rest. `bitbucket_get_file` also states the path and ref it read,
107
+ so reading the wrong branch is visible rather than silent.
108
+ - **Tool annotations** (`readOnlyHint`, `destructiveHint`, `idempotentHint`) are
109
+ published for every tool, so hosts can gate confirmation on metadata.
110
+
77
111
  ## Setup
78
112
 
79
113
  ### 1. Create a config file
@@ -281,7 +315,7 @@ ATLASSIAN_MCP_HTTP=1 atlassian-mcp # same, via env
281
315
  balancers. Idle sessions are evicted after 1h.
282
316
 
283
317
  **Repo context comes from the client, not the server's working directory.** Tools that
284
- need a repo (the `git_*` tools, `get_dev_context`, `start_work`, `complete_work`, and
318
+ need a repo (`git_get_context`, `get_dev_context`, `start_work`, `complete_work`, and
285
319
  Bitbucket project/repo auto-detection) resolve it in this order: an explicit `repoPath`
286
320
  argument → a **root pinned via request header** (see below) → the client's **MCP workspace
287
321
  roots** (the server asks via `roots/list`, caches per session, and refreshes on
@@ -314,7 +348,7 @@ claude mcp add --transport http atlassian http://127.0.0.1:7337/mcp
314
348
 
315
349
  ### Attachment decoding pipeline
316
350
 
317
- The attachment tools (`jira_get_attachment`, `bitbucket_get_attachment`) decode binary attachments into model-readable content before returning them:
351
+ The `get_attachment` tool decodes binary attachments into model-readable content before returning them:
318
352
 
319
353
  | Input | What gets returned | How |
320
354
  | --- | --- | --- |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stubbedev/atlassian-mcp",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "description": "MCP server for self-hosted Jira and Bitbucket (Go, distributed as a prebuilt binary)",
5
5
  "license": "MIT",
6
6
  "type": "module",