@abdelrahmanhsn/jira-mcp 1.5.0 → 1.6.0
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 +55 -5
- package/package.json +1 -1
- package/server.js +76 -3
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @abdelrahmanhsn/jira-mcp
|
|
2
2
|
|
|
3
|
-
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that connects your AI IDE to Jira. Query
|
|
3
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that connects your AI IDE to Jira. Query tickets, manage sprints, and let AI autonomously implement, test, and ship Jira tickets — all without leaving your editor.
|
|
4
|
+
|
|
5
|
+
Works with GitHub Copilot, Cursor, Claude Desktop, and any MCP-compatible client.
|
|
4
6
|
|
|
5
7
|
## Tools
|
|
6
8
|
|
|
@@ -14,13 +16,32 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that co
|
|
|
14
16
|
| `get_sprint_summary` | Get all sprint tickets grouped by status (Todo / In Progress / Done) |
|
|
15
17
|
| `search_tickets` | Search tickets with plain English or raw JQL |
|
|
16
18
|
| `get_context_for_pr` | Extract Jira ticket from a branch name and return a ready-to-use PR description block |
|
|
17
|
-
| `start_ticket` |
|
|
19
|
+
| `start_ticket` | **🤖 Autonomous mode** — assigns ticket, moves to In Progress, creates git branch, then drives AI to implement, test, commit, push, open PR, and comment on Jira — non-stop |
|
|
18
20
|
|
|
19
21
|
## Prerequisites
|
|
20
22
|
|
|
21
23
|
- Node.js 18 or later
|
|
22
24
|
- A Jira Cloud account
|
|
23
25
|
- A Jira API token ([generate one here](https://id.atlassian.com/manage-profile/security/api-tokens))
|
|
26
|
+
- **GitHub CLI** — required for `start_ticket` to create PRs automatically
|
|
27
|
+
|
|
28
|
+
### Install GitHub CLI
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# macOS
|
|
32
|
+
brew install gh
|
|
33
|
+
gh auth login
|
|
34
|
+
|
|
35
|
+
# Windows
|
|
36
|
+
winget install --id GitHub.cli
|
|
37
|
+
gh auth login
|
|
38
|
+
|
|
39
|
+
# Linux
|
|
40
|
+
# See https://github.com/cli/cli/blob/trunk/docs/install_linux.md
|
|
41
|
+
gh auth login
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> If `gh` is not installed or not authenticated, `start_ticket` will return clear instructions instead of silently failing.
|
|
24
45
|
|
|
25
46
|
## Setup
|
|
26
47
|
|
|
@@ -116,18 +137,47 @@ Open `~/Library/Application Support/Claude/claude_desktop_config.json` and add:
|
|
|
116
137
|
|
|
117
138
|
## Usage Examples
|
|
118
139
|
|
|
119
|
-
|
|
140
|
+
### Everyday queries
|
|
120
141
|
|
|
121
142
|
- *"Show me my current Jira tickets"*
|
|
122
143
|
- *"What's in my active sprint?"*
|
|
123
144
|
- *"Get me the details for PROJ-1234"*
|
|
124
|
-
- *"Summarize the description of PROJ-5678"*
|
|
125
145
|
- *"Add a comment to PROJ-123 saying the fix is deployed to staging"*
|
|
126
146
|
- *"Give me my standup for today"*
|
|
127
147
|
- *"Summarize the active sprint — how many tickets are done vs in progress?"*
|
|
128
148
|
- *"Search for open bugs related to login"*
|
|
149
|
+
|
|
150
|
+
### PR workflow
|
|
151
|
+
|
|
129
152
|
- *"Get PR context for branch STUD-17891-add-email-icon"*
|
|
130
|
-
|
|
153
|
+
→ Extracts the ticket key from the branch, fetches description + comments, returns a formatted PR description block ready to paste or expand.
|
|
154
|
+
|
|
155
|
+
### Autonomous mode — `start_ticket`
|
|
156
|
+
|
|
157
|
+
The most powerful tool. One prompt and AI does everything:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
"Start working on STUD-17931"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**What happens automatically, with no stops:**
|
|
164
|
+
1. ✅ Self-assigns the Jira ticket to you
|
|
165
|
+
2. ✅ Moves it to **In Progress**
|
|
166
|
+
3. ✅ Creates and switches to a git branch (e.g. `stud-17931-content-preview-bug`)
|
|
167
|
+
4. ✅ AI reads description, acceptance criteria, and comments
|
|
168
|
+
5. ✅ Implements the feature/fix
|
|
169
|
+
6. ✅ Runs the test suite — fixes failures automatically
|
|
170
|
+
7. ✅ Commits and pushes the branch
|
|
171
|
+
8. ✅ Opens a PR via `gh pr create`
|
|
172
|
+
9. ✅ Posts the PR link as a comment on the Jira ticket
|
|
173
|
+
|
|
174
|
+
You can optionally pass the repo path:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
"Start working on STUD-17931 in /Users/you/code/my-project"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
If omitted, the tool auto-detects the git repo from the current working directory.
|
|
131
181
|
|
|
132
182
|
## Security
|
|
133
183
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abdelrahmanhsn/jira-mcp",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.6.0",
|
|
5
5
|
"description": "MCP server for Jira — query your tickets, active sprints, and issue details from any AI IDE (GitHub Copilot, Cursor, Claude Desktop)",
|
|
6
6
|
"main": "server.js",
|
|
7
7
|
"bin": {
|
package/server.js
CHANGED
|
@@ -273,14 +273,70 @@ server.tool(
|
|
|
273
273
|
// Tool: start_ticket
|
|
274
274
|
server.tool(
|
|
275
275
|
"start_ticket",
|
|
276
|
-
"Fully start a Jira ticket: self-assigns
|
|
276
|
+
"Fully start a Jira ticket in AUTONOMOUS mode: self-assigns, moves to In Progress, creates the git branch, then returns agent instructions that drive non-stop autonomous implementation, testing, commit, push, PR creation, and Jira comment — no confirmation needed",
|
|
277
277
|
{
|
|
278
278
|
issueKey: z.string().describe("The Jira issue key, e.g. STUD-17891"),
|
|
279
|
-
workingDir: z.string().describe("Absolute path to the git repo
|
|
279
|
+
workingDir: z.string().optional().describe("Absolute path to the git repo. If omitted, the tool auto-detects from the current working directory."),
|
|
280
280
|
},
|
|
281
281
|
async ({ issueKey, workingDir }) => {
|
|
282
282
|
const actions = [];
|
|
283
283
|
|
|
284
|
+
// ── Auto-detect workingDir if not provided ────────────────────────────────
|
|
285
|
+
if (!workingDir) {
|
|
286
|
+
try {
|
|
287
|
+
workingDir = execSync("git rev-parse --show-toplevel", { stdio: "pipe" }).toString().trim();
|
|
288
|
+
actions.push(`✅ Auto-detected repo: ${workingDir}`);
|
|
289
|
+
} catch {
|
|
290
|
+
return {
|
|
291
|
+
content: [{
|
|
292
|
+
type: "text",
|
|
293
|
+
text: JSON.stringify({
|
|
294
|
+
error: "Could not auto-detect the git repository.",
|
|
295
|
+
fix: "Re-run start_ticket and pass the workingDir parameter explicitly, e.g. /Users/you/code/my-project",
|
|
296
|
+
hint: "The AI should look at the currently open workspace/files in the editor to determine the correct path and retry.",
|
|
297
|
+
}, null, 2),
|
|
298
|
+
}],
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// ── 0. Preflight: verify gh CLI is installed and authenticated ───────────
|
|
304
|
+
try {
|
|
305
|
+
execSync("gh --version", { stdio: "pipe" });
|
|
306
|
+
} catch {
|
|
307
|
+
return {
|
|
308
|
+
content: [{
|
|
309
|
+
type: "text",
|
|
310
|
+
text: JSON.stringify({
|
|
311
|
+
error: "GitHub CLI (gh) is not installed.",
|
|
312
|
+
fix: "Install it first, then re-run start_ticket.",
|
|
313
|
+
install_steps: {
|
|
314
|
+
macOS: "brew install gh",
|
|
315
|
+
windows: "winget install --id GitHub.cli",
|
|
316
|
+
linux: "https://github.com/cli/cli/blob/trunk/docs/install_linux.md",
|
|
317
|
+
},
|
|
318
|
+
after_install: "Run `gh auth login` to authenticate, then retry.",
|
|
319
|
+
}, null, 2),
|
|
320
|
+
}],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
try {
|
|
325
|
+
execSync("gh auth status", { stdio: "pipe" });
|
|
326
|
+
} catch {
|
|
327
|
+
return {
|
|
328
|
+
content: [{
|
|
329
|
+
type: "text",
|
|
330
|
+
text: JSON.stringify({
|
|
331
|
+
error: "GitHub CLI is installed but not authenticated.",
|
|
332
|
+
fix: "Run `gh auth login` in your terminal, complete the browser flow, then retry start_ticket.",
|
|
333
|
+
}, null, 2),
|
|
334
|
+
}],
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
actions.push("✅ GitHub CLI (gh) is installed and authenticated");
|
|
339
|
+
|
|
284
340
|
// ── 1. Fetch ticket + comments + current user in parallel ────────────────
|
|
285
341
|
const [issueRes, commentsRes, myselfRes, transitionsRes] = await Promise.all([
|
|
286
342
|
jiraClient.get(`/issue/${issueKey}`, {
|
|
@@ -376,8 +432,24 @@ server.tool(
|
|
|
376
432
|
|
|
377
433
|
const ticketUrl = `https://${JIRA_DOMAIN}/browse/${issueKey}`;
|
|
378
434
|
|
|
435
|
+
const agentInstructions = [
|
|
436
|
+
`You are now in AUTONOMOUS CODING MODE for ${issueKey}.`,
|
|
437
|
+
``,
|
|
438
|
+
`RULES — follow these exactly, do NOT stop or ask for confirmation at any point:`,
|
|
439
|
+
`1. You are already on branch \`${branchName}\` in \`${workingDir}\` — start coding immediately.`,
|
|
440
|
+
`2. Read the description and acceptance criteria below — implement everything required.`,
|
|
441
|
+
`3. After implementing, run the test suite automatically. Fix any failures before moving on.`,
|
|
442
|
+
`4. If you encounter an ambiguity, make the most reasonable assumption and document it in a code comment — do NOT pause to ask.`,
|
|
443
|
+
`5. After all tests pass, run: \`git -C "${workingDir}" add -A && git -C "${workingDir}" commit -m "${issueKey}: ${f.summary}" && git -C "${workingDir}" push -u origin ${branchName}\``,
|
|
444
|
+
`6. Create the PR by running: \`gh pr create --repo $(git -C "${workingDir}" remote get-url origin) --title "${issueKey}: ${f.summary}" --body "Resolves ${ticketUrl}" --head ${branchName}\``,
|
|
445
|
+
`7. Capture the PR URL from the gh output and call the add_comment tool to post it on ${issueKey}.`,
|
|
446
|
+
`8. Only stop when the PR is open and the Jira ticket has been commented. That is the definition of done.`,
|
|
447
|
+
].join("\n");
|
|
448
|
+
|
|
379
449
|
const brief = [
|
|
380
|
-
`#
|
|
450
|
+
`# 🤖 AUTONOMOUS MODE — ${issueKey}: ${f.summary}`,
|
|
451
|
+
``,
|
|
452
|
+
agentInstructions,
|
|
381
453
|
``,
|
|
382
454
|
`**Type:** ${f.issuetype?.name} | **Priority:** ${f.priority?.name}`,
|
|
383
455
|
`**Assignee:** ${me.displayName} | **Reporter:** ${f.reporter?.displayName}`,
|
|
@@ -433,6 +505,7 @@ server.tool(
|
|
|
433
505
|
branch_name: branchName,
|
|
434
506
|
ticket_url: ticketUrl,
|
|
435
507
|
actions_taken: actions,
|
|
508
|
+
agent_instructions: agentInstructions,
|
|
436
509
|
description,
|
|
437
510
|
acceptance_criteria: acceptanceCriteria || null,
|
|
438
511
|
subtasks,
|