@thammarongg/jira-mcp 0.4.0 → 0.5.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.
@@ -0,0 +1,140 @@
1
+ import { AGENTS, hasAgentEntry, removeAgentConfig, resolveAgents } from "./agents.js";
2
+ import { makePrompter } from "./prompt.js";
3
+ function parseFlags(argv) {
4
+ const flags = {};
5
+ for (let i = 0; i < argv.length; i++) {
6
+ const arg = argv[i];
7
+ if (arg === "--agents") {
8
+ const value = argv[++i];
9
+ if (value === undefined)
10
+ throw new Error("Missing value for --agents");
11
+ flags.agents = value;
12
+ }
13
+ else if (arg === "--yes") {
14
+ flags.yes = true;
15
+ }
16
+ else if (arg === "--help" || arg === "-h") {
17
+ flags.help = true;
18
+ }
19
+ else {
20
+ throw new Error(`Unknown option: ${arg} (see --help)`);
21
+ }
22
+ }
23
+ return flags;
24
+ }
25
+ function printUsage() {
26
+ console.log(`jira-mcp uninstall — remove jira MCP entries
27
+
28
+ Usage:
29
+ npx -y @thammarongg/jira-mcp uninstall
30
+ npx -y @thammarongg/jira-mcp uninstall --agents all --yes
31
+
32
+ Options:
33
+ --agents <list> Comma-separated agent ids or 'all'
34
+ --yes Skip the confirmation prompt
35
+ -h, --help Show this help
36
+ `);
37
+ }
38
+ function configuredAgents() {
39
+ return AGENTS.filter((agent) => hasAgentEntry(agent));
40
+ }
41
+ function resolveConfigured(spec, configured) {
42
+ const norm = spec.trim().toLowerCase();
43
+ if (norm === "all" || norm === "a")
44
+ return [...configured];
45
+ const ids = norm.split(/[,\s]+/).filter(Boolean);
46
+ const selected = [];
47
+ for (const id of ids) {
48
+ const agent = /^\d+$/.test(id)
49
+ ? configured[Number(id) - 1]
50
+ : configured.find((candidate) => candidate.id === id);
51
+ if (!agent) {
52
+ throw new Error(`Unknown configured agent '${id}'. Valid: ${configured.map((candidate, index) => `${index + 1}/${candidate.id}`).join(", ")} or all`);
53
+ }
54
+ if (!selected.includes(agent))
55
+ selected.push(agent);
56
+ }
57
+ if (selected.length === 0)
58
+ throw new Error("No agents selected");
59
+ return selected;
60
+ }
61
+ async function promptSelection(p, configured) {
62
+ console.log("\njira-mcp uninstall — select agents to remove:\n");
63
+ console.log(" a) Select All");
64
+ configured.forEach((agent, index) => {
65
+ console.log(` ${index + 1}) ${agent.label.padEnd(15)} ${agent.path}`);
66
+ });
67
+ for (;;) {
68
+ const answer = (await p.ask("\nChoice (e.g. 1,3 or a): ")).trim().toLowerCase();
69
+ if (answer === "" && p.closed)
70
+ throw new Error("No input received (stdin closed)");
71
+ try {
72
+ return resolveConfigured(answer, configured);
73
+ }
74
+ catch (err) {
75
+ if (p.closed)
76
+ throw err;
77
+ console.log(` ${err instanceof Error ? err.message : String(err)}`);
78
+ }
79
+ }
80
+ }
81
+ export async function runUninstall(argv) {
82
+ const flags = parseFlags(argv);
83
+ if (flags.help) {
84
+ printUsage();
85
+ return;
86
+ }
87
+ const configured = configuredAgents();
88
+ if (configured.length === 0) {
89
+ console.error("No jira MCP entries found. Run install to configure an agent first.");
90
+ process.exitCode = 1;
91
+ return;
92
+ }
93
+ const p = !flags.yes ? makePrompter() : undefined;
94
+ try {
95
+ const selected = flags.agents
96
+ ? resolveAgents(flags.agents)
97
+ : flags.yes
98
+ ? [...configured]
99
+ : await promptSelection(p, configured);
100
+ console.log("\nWill remove the jira MCP server from:");
101
+ for (const agent of selected) {
102
+ if (hasAgentEntry(agent))
103
+ console.log(` - ${agent.label.padEnd(15)} ${agent.path}`);
104
+ else
105
+ console.log(` skip ${agent.label.padEnd(15)} ${agent.path} (no jira entry)`);
106
+ }
107
+ if (!flags.yes) {
108
+ const answer = (await p.ask("\nProceed? [y/N] ")).trim().toLowerCase();
109
+ if (answer !== "y" && answer !== "yes") {
110
+ console.log("Aborted.");
111
+ return;
112
+ }
113
+ }
114
+ let removed = 0;
115
+ let failed = false;
116
+ for (const agent of selected) {
117
+ try {
118
+ const result = removeAgentConfig(agent);
119
+ if (result === "removed") {
120
+ removed++;
121
+ console.log(` ok ${agent.label.padEnd(15)} ${agent.path} (removed)`);
122
+ }
123
+ else {
124
+ console.log(` skip ${agent.label.padEnd(15)} ${agent.path} (no jira entry)`);
125
+ }
126
+ }
127
+ catch (err) {
128
+ failed = true;
129
+ console.error(` ERR ${agent.label.padEnd(15)} ${agent.path}: ${err instanceof Error ? err.message : String(err)}`);
130
+ }
131
+ }
132
+ if (removed === 0 || failed)
133
+ process.exitCode = 1;
134
+ if (removed > 0)
135
+ console.log("\nDone. Restart each agent to pick up the change.");
136
+ }
137
+ finally {
138
+ p?.close();
139
+ }
140
+ }
package/dist/update.js ADDED
@@ -0,0 +1,71 @@
1
+ import { AGENTS, hasAgentEntry, readAgentEnv, resolveAgents, writeAgentConfig } from "./agents.js";
2
+ function parseFlags(argv) {
3
+ const flags = {};
4
+ for (let i = 0; i < argv.length; i++) {
5
+ const arg = argv[i];
6
+ if (arg === "--agents") {
7
+ const value = argv[++i];
8
+ if (value === undefined)
9
+ throw new Error("Missing value for --agents");
10
+ flags.agents = value;
11
+ }
12
+ else if (arg === "--yes") {
13
+ // Accepted for scripts that use the same non-interactive convention as install/uninstall.
14
+ }
15
+ else if (arg === "--help" || arg === "-h") {
16
+ flags.help = true;
17
+ }
18
+ else {
19
+ throw new Error(`Unknown option: ${arg} (see --help)`);
20
+ }
21
+ }
22
+ return flags;
23
+ }
24
+ function printUsage() {
25
+ console.log(`jira-mcp update — refresh existing jira MCP entries
26
+
27
+ Usage:
28
+ npx -y @thammarongg/jira-mcp update [--agents <list>]
29
+
30
+ Options:
31
+ --agents <list> Comma-separated agent ids or 'all'
32
+ -h, --help Show this help
33
+ `);
34
+ }
35
+ export async function runUpdate(argv) {
36
+ const flags = parseFlags(argv);
37
+ if (flags.help) {
38
+ printUsage();
39
+ return;
40
+ }
41
+ const selected = flags.agents ? resolveAgents(flags.agents) : [...AGENTS];
42
+ let found = 0;
43
+ let failed = false;
44
+ for (const agent of selected) {
45
+ const env = readAgentEnv(agent);
46
+ if (!env) {
47
+ const reason = hasAgentEntry(agent) ? "no readable jira credentials" : "no jira entry";
48
+ console.log(` skip ${agent.label.padEnd(15)} ${agent.path} (${reason})`);
49
+ continue;
50
+ }
51
+ found++;
52
+ try {
53
+ const result = writeAgentConfig(agent, env);
54
+ if (result === "skipped")
55
+ console.log(` skip ${agent.label.padEnd(15)} ${agent.path}`);
56
+ else
57
+ console.log(` ok ${agent.label.padEnd(15)} ${agent.path} (${result})`);
58
+ }
59
+ catch (err) {
60
+ failed = true;
61
+ console.error(` ERR ${agent.label.padEnd(15)} ${agent.path}: ${err instanceof Error ? err.message : String(err)}`);
62
+ }
63
+ }
64
+ if (found === 0) {
65
+ console.error("No jira MCP entries with credentials were found. Run install to configure an agent first.");
66
+ process.exitCode = 1;
67
+ }
68
+ else if (failed) {
69
+ process.exitCode = 1;
70
+ }
71
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thammarongg/jira-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "MCP server exposing the Jira REST API (boards, sprints, issues, JQL, and a generic passthrough) for Jira Cloud and Data Center",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/SKILL.md CHANGED
@@ -33,6 +33,29 @@ Or non-interactive: `npx -y @thammarongg/jira-mcp install --agents all
33
33
  Security → API tokens)
34
34
  - DC: `JIRA_USERNAME` + `JIRA_API_TOKEN` (PAT) or `JIRA_PASSWORD` (app password)
35
35
 
36
+ When a selected agent already has a `jira` entry, the interactive installer
37
+ offers to reuse its base URL and account; `--yes` with no credential flags
38
+ reuses those credentials without prompting.
39
+
40
+ The CLI also supports these maintenance commands:
41
+
42
+ ```bash
43
+ npx -y @thammarongg/jira-mcp update # refresh configured entries
44
+ npx -y @thammarongg/jira-mcp update --agents codex
45
+ npx -y @thammarongg/jira-mcp uninstall # choose entries to remove
46
+ npx -y @thammarongg/jira-mcp uninstall --agents all --yes
47
+ npx -y @thammarongg/jira-mcp --version
48
+ npx -y @thammarongg/jira-mcp --help
49
+ ```
50
+
51
+ `update` is non-interactive and skips agents without a `jira` entry.
52
+ `uninstall` preserves every other config key and confirms before removing the
53
+ selected entries unless `--yes` is supplied. Running the command with no
54
+ arguments in a terminal shows a status card; MCP clients use piped stdio, so
55
+ the same command starts the server and expects `JIRA_*` environment variables.
56
+ Without those variables, a bare server start reports a missing
57
+ `JIRA_BASE_URL`.
58
+
36
59
  Claude Code one-liner:
37
60
 
38
61
  ```bash