@stubbedev/atlassian-mcp 0.5.20 → 0.5.23
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 +20 -26
- package/bin/cli.mjs +1 -25
- package/package.json +3 -7
package/README.md
CHANGED
|
@@ -249,9 +249,6 @@ has no workspace, so it advertises no MCP roots and there is no useful cwd to fa
|
|
|
249
249
|
Comma-separate several worktrees (first git repo wins); a per-call `repoPath` still
|
|
250
250
|
overrides it.
|
|
251
251
|
|
|
252
|
-
On Windows, Git is frequently absent from a GUI app's `PATH`. The server probes the usual
|
|
253
|
-
install locations before giving up; set `ATLASSIAN_MCP_GIT_PATH` if yours lives elsewhere.
|
|
254
|
-
|
|
255
252
|
Server stderr is logged to `~/Library/Logs/Claude/mcp-server-atlassian.log` (macOS) or
|
|
256
253
|
`%APPDATA%\Claude\logs\mcp-server-atlassian.log` (Windows) — read that first when a
|
|
257
254
|
connection fails.
|
|
@@ -453,18 +450,15 @@ attached to every [release](https://github.com/stubbedev/atlassian-mcp/releases/
|
|
|
453
450
|
|
|
454
451
|
```bash
|
|
455
452
|
# Go toolchain — installs to $GOBIN / $GOPATH/bin
|
|
456
|
-
go install github.com/stubbedev/atlassian-mcp@latest
|
|
453
|
+
go install -tags nodynamic github.com/stubbedev/atlassian-mcp@latest
|
|
457
454
|
|
|
458
455
|
# Nix flake
|
|
459
456
|
nix run github:stubbedev/atlassian-mcp -- --config ~/.atlassian-mcp.json
|
|
460
457
|
```
|
|
461
458
|
|
|
462
459
|
Then point your MCP client's `command` at the resulting `atlassian-mcp` binary
|
|
463
|
-
instead of `npx`.
|
|
464
|
-
|
|
465
|
-
animated-image attachments (or set `ATLASSIAN_MCP_FFMPEG_PATH` /
|
|
466
|
-
`ATLASSIAN_MCP_FFPROBE_PATH`); the npm wrapper bundles them automatically. Everything
|
|
467
|
-
else — still images, PDF text, JSON/text — is pure Go and needs nothing extra.
|
|
460
|
+
instead of `npx`. Every install path is the same single static binary: it needs no `git`,
|
|
461
|
+
`ffmpeg` or other program on the machine.
|
|
468
462
|
|
|
469
463
|
### Running as an HTTP server (shared / behind a proxy)
|
|
470
464
|
|
|
@@ -615,28 +609,31 @@ The `get_attachment` tool decodes binary attachments into model-readable content
|
|
|
615
609
|
|
|
616
610
|
| Input | What gets returned | How |
|
|
617
611
|
| --- | --- | --- |
|
|
618
|
-
| Static images (PNG/JPEG/WebP/BMP/TIFF/GIF/SVG…) | Resized image content blocks |
|
|
619
|
-
| Animated images (GIF/APNG/animated WebP) | N sampled frames as image content blocks |
|
|
620
|
-
| Video (
|
|
612
|
+
| Static images (PNG/JPEG/WebP/BMP/TIFF/GIF/SVG/AVIF/HEIC/JPEG XL…) | Resized image content blocks | `imaging`, long edge ≤ `maxDimension`, default 1568; EXIF auto-orient; PNG for alpha, else JPEG. AVIF/HEIC/JPEG XL via [`gen2brain`](https://github.com/gen2brain) decoders (libavif/libheif/libjxl compiled to WebAssembly) |
|
|
613
|
+
| Animated images (GIF/APNG/animated WebP) | N sampled frames as image content blocks | composited in Go, as a browser shows them (default 6 frames @ 768 px) |
|
|
614
|
+
| Video (MP4/MOV, MKV/WebM, AVI) | N sampled frames as image content blocks | H.264 via [`goh264`](https://github.com/thesyncim/goh264) (GOPs decoded in parallel), Motion JPEG, and VP8 keyframes only (`x/image/vp8` has no inter frames); MP4 demuxed by [`mp4ff`](https://github.com/Eyevinn/mp4ff), Matroska and AVI in-tree. Uniform or scene-change sampling (ffmpeg's scene metric), near-duplicate frames dropped. Re-call with `start`, `end`, `frames`, `mode`, `sceneThreshold` to zoom in. HEVC, VP9, AV1 and MPEG-4 Part 2 are reported as unsupported; pass `saveTo` to keep the original |
|
|
621
615
|
| Audio (mp3/wav/ogg/…) | MCP audio content block | passthrough |
|
|
622
|
-
| PDFs | Extracted text — or rasterized pages if text is empty (scanned PDFs) |
|
|
616
|
+
| PDFs | Extracted text — or rasterized pages if text is empty (scanned PDFs) | text via `ledongthuc/pdf`; pages rendered by PDFium compiled to WebAssembly ([`go-pdfium`](https://github.com/klippa-app/go-pdfium)) |
|
|
623
617
|
| Text-like (json/xml/yaml/…) | Text content block | passthrough |
|
|
624
618
|
| Everything else (or oversized) | Auto-saved to a temp file; path is returned | `os.TempDir()` with `atlmcp-` prefix |
|
|
625
619
|
|
|
626
620
|
Auto-saved files are periodically pruned by TTL and total-size quota — see *Environment overrides* below.
|
|
627
621
|
|
|
628
|
-
###
|
|
622
|
+
### No external tools
|
|
623
|
+
|
|
624
|
+
The binary is self-contained and built without cgo (release builds use `-tags nodynamic`, so the image decoders never look for system libraries). Git access goes through
|
|
625
|
+
[`go-git`](https://github.com/go-git/go-git) (status, log, diff, branch, checkout, fetch, push);
|
|
626
|
+
the C libraries some formats need (PDFium, libavif, libheif, libjxl) run as embedded
|
|
627
|
+
WebAssembly under [`wazero`](https://wazero.io).
|
|
629
628
|
|
|
630
|
-
|
|
631
|
-
|
|
629
|
+
Git credentials for fetch/push come from where git keeps them, minus anything that needs another
|
|
630
|
+
program: ssh-agent, `IdentityFile` entries in `~/.ssh/config` and unencrypted `~/.ssh/id_*`
|
|
631
|
+
keys (host keys checked against `~/.ssh/known_hosts`); for https, credentials in the URL,
|
|
632
|
+
`~/.git-credentials`, `~/.netrc`, and the Bitbucket token itself for the configured Bitbucket
|
|
633
|
+
host. Credential helpers, passphrase prompts, git hooks and Git LFS smudging do not run.
|
|
632
634
|
|
|
633
|
-
-
|
|
634
|
-
|
|
635
|
-
[`ffprobe-static`](https://www.npmjs.com/package/ffprobe-static) and injects their paths, so the
|
|
636
|
-
npx install path is zero-config. On every Node-free path (`go install`, Nix, release binary,
|
|
637
|
-
`.mcpb` bundle), install `ffmpeg` (it provides `ffprobe`) or set the env vars below.
|
|
638
|
-
- **`pdftoppm` (poppler) or `mutool` (MuPDF)** — only needed to rasterize *scanned* PDFs that have no
|
|
639
|
-
extractable text. If neither is on `PATH`, such PDFs are saved to disk instead.
|
|
635
|
+
`goh264` is LGPL-2.1; it is linked unmodified and the full source of this server is public, so
|
|
636
|
+
the binary can be rebuilt against a modified copy.
|
|
640
637
|
|
|
641
638
|
### Environment overrides
|
|
642
639
|
|
|
@@ -645,10 +642,7 @@ pure-Go implementation shell out to external binaries:
|
|
|
645
642
|
| `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) |
|
|
646
643
|
| `ATLASSIAN_MCP_HTTP_TOKEN` | Bearer token for HTTP mode. Optional on loopback binds; **required** on non-loopback binds. | unset |
|
|
647
644
|
| `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 |
|
|
648
|
-
| `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` |
|
|
649
645
|
| `ATLASSIAN_MCP_MARK_AI_TEXT` | Set `false` to stop appending the bold `[AI]` attribution line to Jira/Bitbucket text this server posts. | `true` |
|
|
650
|
-
| `ATLASSIAN_MCP_FFMPEG_PATH` | Path to `ffmpeg` binary. | npm: bundled `ffmpeg-static`; otherwise `ffmpeg` on `PATH` |
|
|
651
|
-
| `ATLASSIAN_MCP_FFPROBE_PATH` | Path to `ffprobe` binary. | npm: bundled `ffprobe-static`; otherwise `ffprobe` on `PATH` |
|
|
652
646
|
| `ATLASSIAN_MCP_TMP_TTL_DAYS` | Auto-saved attachments older than this are pruned. | `7` |
|
|
653
647
|
| `ATLASSIAN_MCP_TMP_MAX_BYTES` | Total-size quota for auto-saved attachments in `os.tmpdir()`. When exceeded, oldest are evicted. | `1073741824` (1 GB) |
|
|
654
648
|
|
package/bin/cli.mjs
CHANGED
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
// npm/npx launcher. Ensures the prebuilt Go binary for this platform is present
|
|
3
3
|
// (npx @latest guarantees the newest version), then hands stdio to it directly.
|
|
4
4
|
//
|
|
5
|
-
// It also injects the bundled ffmpeg-static / ffprobe-static binaries via env so
|
|
6
|
-
// video and animated-image attachments work with zero extra setup on the npm
|
|
7
|
-
// install path. Users who install the Go binary directly (go install / Nix)
|
|
8
|
-
// supply ffmpeg/ffprobe on PATH, or set ATLASSIAN_MCP_FFMPEG_PATH / _FFPROBE_PATH.
|
|
9
|
-
//
|
|
10
5
|
// Note on overhead: with stdio 'inherit' the Go binary reads/writes the real
|
|
11
6
|
// stdin/stdout, so this launcher adds ZERO per-message latency — it only relays
|
|
12
7
|
// signals and the exit code.
|
|
@@ -21,26 +16,7 @@ try {
|
|
|
21
16
|
process.exit(1);
|
|
22
17
|
}
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
// user already pinned a path. Best-effort: missing modules are non-fatal.
|
|
26
|
-
const env = { ...process.env };
|
|
27
|
-
async function resolveBundled(envKey, importer) {
|
|
28
|
-
if (env[envKey]) return;
|
|
29
|
-
try {
|
|
30
|
-
const p = await importer();
|
|
31
|
-
if (p) env[envKey] = p;
|
|
32
|
-
} catch { /* dependency absent — fall back to PATH lookup in the binary */ }
|
|
33
|
-
}
|
|
34
|
-
await resolveBundled('ATLASSIAN_MCP_FFMPEG_PATH', async () => {
|
|
35
|
-
const m = await import('ffmpeg-static');
|
|
36
|
-
return m.default ?? m;
|
|
37
|
-
});
|
|
38
|
-
await resolveBundled('ATLASSIAN_MCP_FFPROBE_PATH', async () => {
|
|
39
|
-
const m = await import('ffprobe-static');
|
|
40
|
-
return (m.default ?? m)?.path;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const child = spawn(bin, process.argv.slice(2), { stdio: 'inherit', env });
|
|
19
|
+
const child = spawn(bin, process.argv.slice(2), { stdio: 'inherit' });
|
|
44
20
|
|
|
45
21
|
// Forward termination signals so the Go binary shuts down cleanly with its host.
|
|
46
22
|
for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGQUIT']) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stubbedev/atlassian-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.23",
|
|
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",
|
|
@@ -16,18 +16,14 @@
|
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
18
|
"postinstall": "node scripts/postinstall.mjs",
|
|
19
|
-
"build": "go build -o atlassian-mcp .",
|
|
19
|
+
"build": "go build -tags nodynamic -o atlassian-mcp .",
|
|
20
20
|
"test": "go test ./...",
|
|
21
|
-
"smoke": "go build -o atlassian-mcp . && { printf '%s\\n' '{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{},\"clientInfo\":{\"name\":\"npm-smoke\",\"version\":\"0\"}}}' '{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}' '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'; sleep 3; } | ATLASSIAN_MCP_CONFIG=/nonexistent JIRA_URL=https://github.com JIRA_ACCESS_TOKEN=smoke BITBUCKET_URL=https://github.com BITBUCKET_ACCESS_TOKEN=smoke ./atlassian-mcp | node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const rs=d.trim().split('\\n').filter(Boolean).map(l=>JSON.parse(l));const err=rs.find(r=>r.error);if(err)throw new Error('server error: '+err.error.message);const t=rs.find(r=>r.id===1)?.result?.tools;if(!Array.isArray(t)||!t.length)throw new Error('no tools in response');const bad=t.filter(x=>!x.name||!x.inputSchema);if(bad.length)throw new Error('malformed tools: '+bad.map(x=>x.name??'(unnamed)').join(', '));console.log('smoke OK — '+t.length+' tool(s): '+t.map(x=>x.name).join(', '))}catch(e){console.error('smoke FAIL:',e.message);process.exit(1)}})\"",
|
|
21
|
+
"smoke": "go build -tags nodynamic -o atlassian-mcp . && { printf '%s\\n' '{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{},\"clientInfo\":{\"name\":\"npm-smoke\",\"version\":\"0\"}}}' '{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}' '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'; sleep 3; } | ATLASSIAN_MCP_CONFIG=/nonexistent JIRA_URL=https://github.com JIRA_ACCESS_TOKEN=smoke BITBUCKET_URL=https://github.com BITBUCKET_ACCESS_TOKEN=smoke ./atlassian-mcp | node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const rs=d.trim().split('\\n').filter(Boolean).map(l=>JSON.parse(l));const err=rs.find(r=>r.error);if(err)throw new Error('server error: '+err.error.message);const t=rs.find(r=>r.id===1)?.result?.tools;if(!Array.isArray(t)||!t.length)throw new Error('no tools in response');const bad=t.filter(x=>!x.name||!x.inputSchema);if(bad.length)throw new Error('malformed tools: '+bad.map(x=>x.name??'(unnamed)').join(', '));console.log('smoke OK — '+t.length+' tool(s): '+t.map(x=>x.name).join(', '))}catch(e){console.error('smoke FAIL:',e.message);process.exit(1)}})\"",
|
|
22
22
|
"preversion": "go vet ./... && npm run test && npm run smoke",
|
|
23
23
|
"release:patch": "npm version patch && git push origin HEAD --follow-tags",
|
|
24
24
|
"release:minor": "npm version minor && git push origin HEAD --follow-tags",
|
|
25
25
|
"release:major": "npm version major && git push origin HEAD --follow-tags"
|
|
26
26
|
},
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"ffmpeg-static": "^5.3.0",
|
|
29
|
-
"ffprobe-static": "^3.1.0"
|
|
30
|
-
},
|
|
31
27
|
"engines": {
|
|
32
28
|
"node": ">=18.0.0"
|
|
33
29
|
},
|