mcp-jira-stdio 1.5.1 → 1.5.2
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/dist/index.js +149 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -439,7 +439,7 @@ var require_package2 = __commonJS({
|
|
|
439
439
|
"package.json"(exports, module) {
|
|
440
440
|
module.exports = {
|
|
441
441
|
name: "mcp-jira-stdio",
|
|
442
|
-
version: "1.5.
|
|
442
|
+
version: "1.5.2",
|
|
443
443
|
description: "Model Context Protocol (MCP) server for Jira API integration",
|
|
444
444
|
author: "graslt",
|
|
445
445
|
license: "MIT",
|
|
@@ -824,6 +824,7 @@ var GetCustomFieldsInputSchema = z.object({
|
|
|
824
824
|
});
|
|
825
825
|
|
|
826
826
|
// src/utils/api-helpers.ts
|
|
827
|
+
var log2 = createLogger("api-helpers");
|
|
827
828
|
function ensureAdfDescription(desc) {
|
|
828
829
|
if (!desc) return desc;
|
|
829
830
|
if (typeof desc === "object") return desc;
|
|
@@ -938,20 +939,32 @@ function ensureAdfDescription(desc) {
|
|
|
938
939
|
return { type: "doc", version: 1, content };
|
|
939
940
|
}
|
|
940
941
|
async function getVisibleProjects(options = {}) {
|
|
941
|
-
const
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
942
|
+
const allProjects = [];
|
|
943
|
+
let startAt = 0;
|
|
944
|
+
let isLast = false;
|
|
945
|
+
while (!isLast) {
|
|
946
|
+
const params = {
|
|
947
|
+
startAt,
|
|
948
|
+
maxResults: 50
|
|
949
|
+
// Jira default, fetch 50 projects per page
|
|
950
|
+
};
|
|
951
|
+
if (options.expand) {
|
|
952
|
+
params.expand = options.expand.join(",");
|
|
953
|
+
}
|
|
954
|
+
if (options.recent) {
|
|
955
|
+
params.recent = options.recent;
|
|
956
|
+
}
|
|
957
|
+
const config = {
|
|
958
|
+
method: "GET",
|
|
959
|
+
url: "/project/search",
|
|
960
|
+
params
|
|
961
|
+
};
|
|
962
|
+
const response = await makeJiraRequest(config);
|
|
963
|
+
allProjects.push(...response.values);
|
|
964
|
+
isLast = response.isLast;
|
|
965
|
+
startAt += response.maxResults;
|
|
947
966
|
}
|
|
948
|
-
|
|
949
|
-
method: "GET",
|
|
950
|
-
url: "/project/search",
|
|
951
|
-
params
|
|
952
|
-
};
|
|
953
|
-
const response = await makeJiraRequest(config);
|
|
954
|
-
return response.values;
|
|
967
|
+
return allProjects;
|
|
955
968
|
}
|
|
956
969
|
async function getIssue(issueKey, options = {}) {
|
|
957
970
|
const params = {};
|
|
@@ -1198,6 +1211,56 @@ async function createSubtask(parentIssueKey, subtaskData) {
|
|
|
1198
1211
|
return await getIssue(response.key);
|
|
1199
1212
|
}
|
|
1200
1213
|
async function getCreateMeta(options = {}) {
|
|
1214
|
+
if (options.projectKeys && options.projectKeys.length === 1) {
|
|
1215
|
+
const projectKey = options.projectKeys[0];
|
|
1216
|
+
const allIssueTypes = await getIssueTypes(projectKey);
|
|
1217
|
+
let issueTypesToFetch = allIssueTypes;
|
|
1218
|
+
if (options.issueTypeNames && options.issueTypeNames.length > 0) {
|
|
1219
|
+
issueTypesToFetch = allIssueTypes.filter(
|
|
1220
|
+
(type) => options.issueTypeNames?.includes(type.name)
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
const issueTypesWithFields = [];
|
|
1224
|
+
for (const issueType of issueTypesToFetch) {
|
|
1225
|
+
try {
|
|
1226
|
+
const config2 = {
|
|
1227
|
+
method: "GET",
|
|
1228
|
+
url: `/issue/createmeta/${projectKey}/issuetypes/${issueType.id}`
|
|
1229
|
+
};
|
|
1230
|
+
const issueTypeMetadata = await makeJiraRequest(config2);
|
|
1231
|
+
const fieldsMap = {};
|
|
1232
|
+
if (issueTypeMetadata.values && Array.isArray(issueTypeMetadata.values)) {
|
|
1233
|
+
for (const field of issueTypeMetadata.values) {
|
|
1234
|
+
const fieldKey = field.key || field.fieldId || field.name;
|
|
1235
|
+
if (fieldKey) {
|
|
1236
|
+
fieldsMap[fieldKey] = field;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
issueTypesWithFields.push({
|
|
1241
|
+
id: issueType.id,
|
|
1242
|
+
name: issueType.name,
|
|
1243
|
+
description: issueType.description,
|
|
1244
|
+
iconUrl: issueType.iconUrl,
|
|
1245
|
+
subtask: issueType.subtask,
|
|
1246
|
+
fields: fieldsMap
|
|
1247
|
+
});
|
|
1248
|
+
} catch (error) {
|
|
1249
|
+
log2.error(`Failed to get metadata for issue type ${issueType.name}:`, error);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
const projectDetails = await getProjectDetails(projectKey);
|
|
1253
|
+
return {
|
|
1254
|
+
projects: [
|
|
1255
|
+
{
|
|
1256
|
+
id: projectDetails.id,
|
|
1257
|
+
key: projectDetails.key,
|
|
1258
|
+
name: projectDetails.name,
|
|
1259
|
+
issuetypes: issueTypesWithFields
|
|
1260
|
+
}
|
|
1261
|
+
]
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1201
1264
|
const params = {};
|
|
1202
1265
|
if (options.projectKeys && options.projectKeys.length > 0) {
|
|
1203
1266
|
params.projectKeys = options.projectKeys.join(",");
|
|
@@ -1665,7 +1728,7 @@ ${fieldsList}`
|
|
|
1665
1728
|
}
|
|
1666
1729
|
|
|
1667
1730
|
// src/utils/error-handler.ts
|
|
1668
|
-
var
|
|
1731
|
+
var log3 = createLogger("error-handler");
|
|
1669
1732
|
var JiraApiError = class extends Error {
|
|
1670
1733
|
constructor(message, statusCode, jiraErrors, originalError) {
|
|
1671
1734
|
super(message);
|
|
@@ -1676,7 +1739,7 @@ var JiraApiError = class extends Error {
|
|
|
1676
1739
|
}
|
|
1677
1740
|
};
|
|
1678
1741
|
function handleError(error) {
|
|
1679
|
-
|
|
1742
|
+
log3.error("Tool error:", error);
|
|
1680
1743
|
if (typeof error === "string") {
|
|
1681
1744
|
return formatErrorResponse(error);
|
|
1682
1745
|
}
|
|
@@ -1713,7 +1776,7 @@ function handleError(error) {
|
|
|
1713
1776
|
}
|
|
1714
1777
|
|
|
1715
1778
|
// src/tools/get-visible-projects.ts
|
|
1716
|
-
var
|
|
1779
|
+
var log4 = createLogger("tool:get-visible-projects");
|
|
1717
1780
|
var getVisibleProjectsTool = {
|
|
1718
1781
|
name: TOOL_NAMES.GET_VISIBLE_PROJECTS,
|
|
1719
1782
|
description: "Retrieves all projects accessible to the authenticated user. Returns project keys, names, descriptions, and basic metadata.",
|
|
@@ -1739,21 +1802,21 @@ var getVisibleProjectsTool = {
|
|
|
1739
1802
|
async function handleGetVisibleProjects(input) {
|
|
1740
1803
|
try {
|
|
1741
1804
|
const validated = validateInput(GetVisibleProjectsInputSchema, input);
|
|
1742
|
-
|
|
1805
|
+
log4.info("Getting visible projects...");
|
|
1743
1806
|
const getParams = {};
|
|
1744
1807
|
if (validated.expand !== void 0) getParams.expand = validated.expand;
|
|
1745
1808
|
if (validated.recent !== void 0) getParams.recent = validated.recent;
|
|
1746
1809
|
const projects = await getVisibleProjects(getParams);
|
|
1747
|
-
|
|
1810
|
+
log4.info(`Found ${projects.length} project(s)`);
|
|
1748
1811
|
return formatProjectsResponse(projects);
|
|
1749
1812
|
} catch (error) {
|
|
1750
|
-
|
|
1813
|
+
log4.error("Error in handleGetVisibleProjects:", error);
|
|
1751
1814
|
return handleError(error);
|
|
1752
1815
|
}
|
|
1753
1816
|
}
|
|
1754
1817
|
|
|
1755
1818
|
// src/tools/get-issue.ts
|
|
1756
|
-
var
|
|
1819
|
+
var log5 = createLogger("tool:get-issue");
|
|
1757
1820
|
var getIssueTool = {
|
|
1758
1821
|
name: TOOL_NAMES.GET_ISSUE,
|
|
1759
1822
|
description: 'Retrieve details for a specific Jira issue by key or URL. Use this when the user mentions an issue like "PAYWALL-943" or pastes a Jira link (e.g., https://your.atlassian.net/browse/PAYWALL-943). Returns status, assignee, priority, project, type, labels, components, timestamps, and description.',
|
|
@@ -1784,21 +1847,21 @@ async function handleGetIssue(input) {
|
|
|
1784
1847
|
const validated = validateInput(GetIssueInputSchema, input);
|
|
1785
1848
|
const trimmedInput = (validated.issueKey || "").trim();
|
|
1786
1849
|
const key = extractIssueKey(trimmedInput) || trimmedInput;
|
|
1787
|
-
|
|
1850
|
+
log5.info(`Getting issue ${key}...`);
|
|
1788
1851
|
const getParams = {};
|
|
1789
1852
|
if (validated.expand !== void 0) getParams.expand = validated.expand;
|
|
1790
1853
|
if (validated.fields !== void 0) getParams.fields = validated.fields;
|
|
1791
1854
|
const issue = await getIssue(key, getParams);
|
|
1792
|
-
|
|
1855
|
+
log5.info(`Retrieved issue ${issue.key}`);
|
|
1793
1856
|
return formatIssueResponse(issue);
|
|
1794
1857
|
} catch (error) {
|
|
1795
|
-
|
|
1858
|
+
log5.error("Error in handleGetIssue:", error);
|
|
1796
1859
|
return handleError(error);
|
|
1797
1860
|
}
|
|
1798
1861
|
}
|
|
1799
1862
|
|
|
1800
1863
|
// src/tools/search-issues.ts
|
|
1801
|
-
var
|
|
1864
|
+
var log6 = createLogger("tool:search-issues");
|
|
1802
1865
|
var searchIssuesTool = {
|
|
1803
1866
|
name: TOOL_NAMES.SEARCH_ISSUES,
|
|
1804
1867
|
description: 'Search for Jira issues using JQL. Supports complex queries with pagination and field selection. Examples: "project = PROJECT AND status = Open", "assignee = currentUser()". For pagination, use nextPageToken from previous response.',
|
|
@@ -1838,7 +1901,7 @@ var searchIssuesTool = {
|
|
|
1838
1901
|
async function handleSearchIssues(input) {
|
|
1839
1902
|
try {
|
|
1840
1903
|
const validated = validateInput(SearchIssuesInputSchema, input);
|
|
1841
|
-
|
|
1904
|
+
log6.info(`Searching issues with JQL: "${validated.jql}"...`);
|
|
1842
1905
|
const searchParams = {
|
|
1843
1906
|
jql: validated.jql
|
|
1844
1907
|
};
|
|
@@ -1847,16 +1910,16 @@ async function handleSearchIssues(input) {
|
|
|
1847
1910
|
if (validated.fields !== void 0) searchParams.fields = validated.fields;
|
|
1848
1911
|
if (validated.expand !== void 0) searchParams.expand = validated.expand;
|
|
1849
1912
|
const result = await searchIssues(searchParams);
|
|
1850
|
-
|
|
1913
|
+
log6.info(`Found ${result.total} issue(s), showing ${result.issues.length}`);
|
|
1851
1914
|
return formatSearchResultsResponse(result);
|
|
1852
1915
|
} catch (error) {
|
|
1853
|
-
|
|
1916
|
+
log6.error("Error in handleSearchIssues:", error);
|
|
1854
1917
|
return handleError(error);
|
|
1855
1918
|
}
|
|
1856
1919
|
}
|
|
1857
1920
|
|
|
1858
1921
|
// src/tools/get-my-issues.ts
|
|
1859
|
-
var
|
|
1922
|
+
var log7 = createLogger("tool:get-my-issues");
|
|
1860
1923
|
var getMyIssuesTool = {
|
|
1861
1924
|
name: TOOL_NAMES.GET_MY_ISSUES,
|
|
1862
1925
|
description: "Retrieves issues assigned to current user, sorted by most recently updated first. Supports pagination and field selection. For pagination, use nextPageToken from previous response.",
|
|
@@ -1892,23 +1955,23 @@ var getMyIssuesTool = {
|
|
|
1892
1955
|
async function handleGetMyIssues(input) {
|
|
1893
1956
|
try {
|
|
1894
1957
|
const validated = validateInput(GetMyIssuesInputSchema, input);
|
|
1895
|
-
|
|
1958
|
+
log7.info("Getting issues assigned to current user...");
|
|
1896
1959
|
const getParams = {};
|
|
1897
1960
|
if (validated.nextPageToken !== void 0) getParams.nextPageToken = validated.nextPageToken;
|
|
1898
1961
|
if (validated.maxResults !== void 0) getParams.maxResults = validated.maxResults;
|
|
1899
1962
|
if (validated.fields !== void 0) getParams.fields = validated.fields;
|
|
1900
1963
|
if (validated.expand !== void 0) getParams.expand = validated.expand;
|
|
1901
1964
|
const result = await getMyIssues(getParams);
|
|
1902
|
-
|
|
1965
|
+
log7.info(`Found ${result.total} issue(s) assigned to you, showing ${result.issues.length}`);
|
|
1903
1966
|
return formatSearchResultsResponse(result);
|
|
1904
1967
|
} catch (error) {
|
|
1905
|
-
|
|
1968
|
+
log7.error("Error in handleGetMyIssues:", error);
|
|
1906
1969
|
return handleError(error);
|
|
1907
1970
|
}
|
|
1908
1971
|
}
|
|
1909
1972
|
|
|
1910
1973
|
// src/tools/get-issue-types.ts
|
|
1911
|
-
var
|
|
1974
|
+
var log8 = createLogger("tool:get-issue-types");
|
|
1912
1975
|
var getIssueTypesTool = {
|
|
1913
1976
|
name: TOOL_NAMES.GET_ISSUE_TYPES,
|
|
1914
1977
|
description: "Retrieves available issue types. Can get global issue types or project-specific issue types including regular issues and subtasks (Bug, Story, Task, Epic, etc.).",
|
|
@@ -1927,21 +1990,21 @@ async function handleGetIssueTypes(input) {
|
|
|
1927
1990
|
try {
|
|
1928
1991
|
const validated = validateInput(GetIssueTypesInputSchema, input);
|
|
1929
1992
|
if (validated.projectKey) {
|
|
1930
|
-
|
|
1993
|
+
log8.info(`Getting issue types for project ${validated.projectKey}...`);
|
|
1931
1994
|
} else {
|
|
1932
|
-
|
|
1995
|
+
log8.info("Getting global issue types...");
|
|
1933
1996
|
}
|
|
1934
1997
|
const issueTypes = await getIssueTypes(validated.projectKey);
|
|
1935
|
-
|
|
1998
|
+
log8.info(`Found ${issueTypes.length} issue type(s)`);
|
|
1936
1999
|
return formatIssueTypesResponse(issueTypes);
|
|
1937
2000
|
} catch (error) {
|
|
1938
|
-
|
|
2001
|
+
log8.error("Error in handleGetIssueTypes:", error);
|
|
1939
2002
|
return handleError(error);
|
|
1940
2003
|
}
|
|
1941
2004
|
}
|
|
1942
2005
|
|
|
1943
2006
|
// src/tools/get-users.ts
|
|
1944
|
-
var
|
|
2007
|
+
var log9 = createLogger("tool:get-users");
|
|
1945
2008
|
var getUsersTool = {
|
|
1946
2009
|
name: TOOL_NAMES.GET_USERS,
|
|
1947
2010
|
description: "Search for users by name, email, username, or account ID. Returns display name, email, account status, and account type. Supports pagination.",
|
|
@@ -1981,13 +2044,13 @@ async function handleGetUsers(input) {
|
|
|
1981
2044
|
try {
|
|
1982
2045
|
const validated = validateInput(GetUsersInputSchema, input);
|
|
1983
2046
|
if (validated.query) {
|
|
1984
|
-
|
|
2047
|
+
log9.info(`Searching users with query: "${validated.query}"...`);
|
|
1985
2048
|
} else if (validated.username) {
|
|
1986
|
-
|
|
2049
|
+
log9.info(`Searching for username: "${validated.username}"...`);
|
|
1987
2050
|
} else if (validated.accountId) {
|
|
1988
|
-
|
|
2051
|
+
log9.info(`Searching for account ID: "${validated.accountId}"...`);
|
|
1989
2052
|
} else {
|
|
1990
|
-
|
|
2053
|
+
log9.info("Getting all users...");
|
|
1991
2054
|
}
|
|
1992
2055
|
const getParams = {};
|
|
1993
2056
|
if (validated.query !== void 0) getParams.query = validated.query;
|
|
@@ -1996,16 +2059,16 @@ async function handleGetUsers(input) {
|
|
|
1996
2059
|
if (validated.startAt !== void 0) getParams.startAt = validated.startAt;
|
|
1997
2060
|
if (validated.maxResults !== void 0) getParams.maxResults = validated.maxResults;
|
|
1998
2061
|
const users = await getUsers(getParams);
|
|
1999
|
-
|
|
2062
|
+
log9.info(`Found ${users.length} user(s)`);
|
|
2000
2063
|
return formatUsersResponse(users);
|
|
2001
2064
|
} catch (error) {
|
|
2002
|
-
|
|
2065
|
+
log9.error("Error in handleGetUsers:", error);
|
|
2003
2066
|
return handleError(error);
|
|
2004
2067
|
}
|
|
2005
2068
|
}
|
|
2006
2069
|
|
|
2007
2070
|
// src/tools/get-priorities.ts
|
|
2008
|
-
var
|
|
2071
|
+
var log10 = createLogger("tool:get-priorities");
|
|
2009
2072
|
var getPrioritiesTool = {
|
|
2010
2073
|
name: TOOL_NAMES.GET_PRIORITIES,
|
|
2011
2074
|
description: "Retrieves available priorities (e.g., Highest, High, Medium, Low, Lowest). Returns IDs, names, and descriptions.",
|
|
@@ -2018,18 +2081,18 @@ var getPrioritiesTool = {
|
|
|
2018
2081
|
async function handleGetPriorities(input) {
|
|
2019
2082
|
try {
|
|
2020
2083
|
validateInput(GetPrioritiesInputSchema, input);
|
|
2021
|
-
|
|
2084
|
+
log10.info("Getting all priority levels...");
|
|
2022
2085
|
const priorities = await getPriorities();
|
|
2023
|
-
|
|
2086
|
+
log10.info(`Found ${priorities.length} priority level(s)`);
|
|
2024
2087
|
return formatPrioritiesResponse(priorities);
|
|
2025
2088
|
} catch (error) {
|
|
2026
|
-
|
|
2089
|
+
log10.error("Error in handleGetPriorities:", error);
|
|
2027
2090
|
return handleError(error);
|
|
2028
2091
|
}
|
|
2029
2092
|
}
|
|
2030
2093
|
|
|
2031
2094
|
// src/tools/get-statuses.ts
|
|
2032
|
-
var
|
|
2095
|
+
var log11 = createLogger("tool:get-statuses");
|
|
2033
2096
|
var getStatusesTool = {
|
|
2034
2097
|
name: TOOL_NAMES.GET_STATUSES,
|
|
2035
2098
|
description: "Retrieves available statuses (global or project-specific, e.g., To Do, In Progress, Done). Returns status categories and workflow information.",
|
|
@@ -2052,28 +2115,28 @@ async function handleGetStatuses(input) {
|
|
|
2052
2115
|
try {
|
|
2053
2116
|
const validated = validateInput(GetStatusesInputSchema, input);
|
|
2054
2117
|
if (validated.projectKey && validated.issueTypeId) {
|
|
2055
|
-
|
|
2118
|
+
log11.info(
|
|
2056
2119
|
`Getting statuses for project ${validated.projectKey} and issue type ${validated.issueTypeId}...`
|
|
2057
2120
|
);
|
|
2058
2121
|
} else if (validated.projectKey) {
|
|
2059
|
-
|
|
2122
|
+
log11.info(`Getting statuses for project ${validated.projectKey}...`);
|
|
2060
2123
|
} else {
|
|
2061
|
-
|
|
2124
|
+
log11.info("Getting global statuses...");
|
|
2062
2125
|
}
|
|
2063
2126
|
const getParams = {};
|
|
2064
2127
|
if (validated.projectKey !== void 0) getParams.projectKey = validated.projectKey;
|
|
2065
2128
|
if (validated.issueTypeId !== void 0) getParams.issueTypeId = validated.issueTypeId;
|
|
2066
2129
|
const statuses = await getStatuses(getParams);
|
|
2067
|
-
|
|
2130
|
+
log11.info(`Found ${statuses.length} status(es)`);
|
|
2068
2131
|
return formatStatusesResponse(statuses);
|
|
2069
2132
|
} catch (error) {
|
|
2070
|
-
|
|
2133
|
+
log11.error("Error in handleGetStatuses:", error);
|
|
2071
2134
|
return handleError(error);
|
|
2072
2135
|
}
|
|
2073
2136
|
}
|
|
2074
2137
|
|
|
2075
2138
|
// src/tools/create-issue.ts
|
|
2076
|
-
var
|
|
2139
|
+
var log12 = createLogger("tool:create-issue");
|
|
2077
2140
|
var createIssueTool = {
|
|
2078
2141
|
name: TOOL_NAMES.CREATE_ISSUE,
|
|
2079
2142
|
description: 'Creates a new Jira issue in the specified project. Supports setting issue type, priority, assignee, labels, components, and custom fields. Description accepts plain text and is auto-formatted to ADF: lines ending with ":" become headings, numbered lines create ordered lists, and URLs are linkified. For required custom fields, supply them via customFields (e.g., { "customfield_12345": { id: "..." } }). Returns the created issue with all details.',
|
|
@@ -2134,7 +2197,7 @@ var createIssueTool = {
|
|
|
2134
2197
|
async function handleCreateIssue(input) {
|
|
2135
2198
|
try {
|
|
2136
2199
|
const validated = validateInput(CreateIssueInputSchema, input);
|
|
2137
|
-
|
|
2200
|
+
log12.info(`Creating issue in project ${validated.projectKey}...`);
|
|
2138
2201
|
const createParams = {
|
|
2139
2202
|
projectKey: validated.projectKey,
|
|
2140
2203
|
summary: validated.summary,
|
|
@@ -2154,20 +2217,20 @@ async function handleCreateIssue(input) {
|
|
|
2154
2217
|
}
|
|
2155
2218
|
if (validated.returnIssue === false) {
|
|
2156
2219
|
const key = typeof issueOrKey === "string" ? issueOrKey : issueOrKey.key;
|
|
2157
|
-
|
|
2220
|
+
log12.info(`Created issue ${key}`);
|
|
2158
2221
|
return formatSuccessResponse(`Issue created: ${key}`);
|
|
2159
2222
|
}
|
|
2160
2223
|
const issue = issueOrKey;
|
|
2161
|
-
|
|
2224
|
+
log12.info(`Created issue ${issue.key}`);
|
|
2162
2225
|
return formatIssueResponse(issue);
|
|
2163
2226
|
} catch (error) {
|
|
2164
|
-
|
|
2227
|
+
log12.error("Error in handleCreateIssue:", error);
|
|
2165
2228
|
return handleError(error);
|
|
2166
2229
|
}
|
|
2167
2230
|
}
|
|
2168
2231
|
|
|
2169
2232
|
// src/tools/update-issue.ts
|
|
2170
|
-
var
|
|
2233
|
+
var log13 = createLogger("tool:update-issue");
|
|
2171
2234
|
var updateIssueTool = {
|
|
2172
2235
|
name: TOOL_NAMES.UPDATE_ISSUE,
|
|
2173
2236
|
description: 'Updates an existing Jira issue by its key. Supports updating summary, description, priority, assignee, labels, and components. Description accepts plain text and is auto-formatted to ADF: headings (lines ending with ":"), numbered/bullet lists, and links. Only specified fields will be updated.',
|
|
@@ -2216,7 +2279,7 @@ var updateIssueTool = {
|
|
|
2216
2279
|
async function handleUpdateIssue(input) {
|
|
2217
2280
|
try {
|
|
2218
2281
|
const validated = validateInput(UpdateIssueInputSchema, input);
|
|
2219
|
-
|
|
2282
|
+
log13.info(`Updating issue ${validated.issueKey}...`);
|
|
2220
2283
|
const updateParams = {};
|
|
2221
2284
|
if (validated.summary !== void 0) updateParams.summary = validated.summary;
|
|
2222
2285
|
if (validated.description !== void 0) updateParams.description = validated.description;
|
|
@@ -2226,20 +2289,20 @@ async function handleUpdateIssue(input) {
|
|
|
2226
2289
|
if (validated.components !== void 0) updateParams.components = validated.components;
|
|
2227
2290
|
await updateIssue(validated.issueKey, updateParams);
|
|
2228
2291
|
if (validated.returnIssue === false) {
|
|
2229
|
-
|
|
2292
|
+
log13.info(`Updated issue ${validated.issueKey}`);
|
|
2230
2293
|
return formatSuccessResponse(`Issue ${validated.issueKey} updated successfully`);
|
|
2231
2294
|
}
|
|
2232
2295
|
const updatedIssue = await getIssue(validated.issueKey);
|
|
2233
|
-
|
|
2296
|
+
log13.info(`Updated issue ${updatedIssue.key}`);
|
|
2234
2297
|
return formatIssueResponse(updatedIssue);
|
|
2235
2298
|
} catch (error) {
|
|
2236
|
-
|
|
2299
|
+
log13.error("Error in handleUpdateIssue:", error);
|
|
2237
2300
|
return handleError(error);
|
|
2238
2301
|
}
|
|
2239
2302
|
}
|
|
2240
2303
|
|
|
2241
2304
|
// src/tools/add-comment.ts
|
|
2242
|
-
var
|
|
2305
|
+
var log14 = createLogger("tool:add-comment");
|
|
2243
2306
|
var addCommentTool = {
|
|
2244
2307
|
name: TOOL_NAMES.ADD_COMMENT,
|
|
2245
2308
|
description: "Adds a comment to an issue. Supports visibility restrictions for groups or roles. Returns the created comment with author details and timestamp.",
|
|
@@ -2278,18 +2341,18 @@ var addCommentTool = {
|
|
|
2278
2341
|
async function handleAddComment(input) {
|
|
2279
2342
|
try {
|
|
2280
2343
|
const validated = validateInput(AddCommentInputSchema, input);
|
|
2281
|
-
|
|
2344
|
+
log14.info(`Adding comment to issue ${validated.issueKey}...`);
|
|
2282
2345
|
const comment = await addComment(validated.issueKey, validated.body, validated.visibility);
|
|
2283
|
-
|
|
2346
|
+
log14.info(`Added comment to ${validated.issueKey}`);
|
|
2284
2347
|
return formatCommentResponse(comment);
|
|
2285
2348
|
} catch (error) {
|
|
2286
|
-
|
|
2349
|
+
log14.error("Error in handleAddComment:", error);
|
|
2287
2350
|
return handleError(error);
|
|
2288
2351
|
}
|
|
2289
2352
|
}
|
|
2290
2353
|
|
|
2291
2354
|
// src/tools/get-project-info.ts
|
|
2292
|
-
var
|
|
2355
|
+
var log15 = createLogger("tool:get-project-info");
|
|
2293
2356
|
var getProjectInfoTool = {
|
|
2294
2357
|
name: TOOL_NAMES.GET_PROJECT_INFO,
|
|
2295
2358
|
description: "Retrieves detailed information about a project (components, versions, issue types, roles, insights). More comprehensive than the basic project list.",
|
|
@@ -2313,18 +2376,18 @@ var getProjectInfoTool = {
|
|
|
2313
2376
|
async function handleGetProjectInfo(input) {
|
|
2314
2377
|
try {
|
|
2315
2378
|
const validated = validateInput(GetProjectInfoInputSchema, input);
|
|
2316
|
-
|
|
2379
|
+
log15.info(`Getting detailed project information for ${validated.projectKey}...`);
|
|
2317
2380
|
const project = await getProjectDetails(validated.projectKey, validated.expand);
|
|
2318
|
-
|
|
2381
|
+
log15.info(`Retrieved project details for ${project.key}`);
|
|
2319
2382
|
return formatProjectDetailsResponse(project);
|
|
2320
2383
|
} catch (error) {
|
|
2321
|
-
|
|
2384
|
+
log15.error("Error in handleGetProjectInfo:", error);
|
|
2322
2385
|
return handleError(error);
|
|
2323
2386
|
}
|
|
2324
2387
|
}
|
|
2325
2388
|
|
|
2326
2389
|
// src/tools/create-subtask.ts
|
|
2327
|
-
var
|
|
2390
|
+
var log16 = createLogger("tool:create-subtask");
|
|
2328
2391
|
var createSubtaskTool = {
|
|
2329
2392
|
name: TOOL_NAMES.CREATE_SUBTASK,
|
|
2330
2393
|
description: "Creates a subtask under an existing parent issue. Automatically determines the correct project and subtask issue type. Supports setting priority, assignee, labels, and components.",
|
|
@@ -2371,7 +2434,7 @@ var createSubtaskTool = {
|
|
|
2371
2434
|
async function handleCreateSubtask(input) {
|
|
2372
2435
|
try {
|
|
2373
2436
|
const validated = validateInput(CreateSubtaskInputSchema, input);
|
|
2374
|
-
|
|
2437
|
+
log16.info(`Creating subtask under parent issue ${validated.parentIssueKey}...`);
|
|
2375
2438
|
const subtaskParams = {
|
|
2376
2439
|
summary: validated.summary
|
|
2377
2440
|
};
|
|
@@ -2381,16 +2444,16 @@ async function handleCreateSubtask(input) {
|
|
|
2381
2444
|
if (validated.labels !== void 0) subtaskParams.labels = validated.labels;
|
|
2382
2445
|
if (validated.components !== void 0) subtaskParams.components = validated.components;
|
|
2383
2446
|
const subtask = await createSubtask(validated.parentIssueKey, subtaskParams);
|
|
2384
|
-
|
|
2447
|
+
log16.info(`Created subtask ${subtask.key}`);
|
|
2385
2448
|
return formatIssueResponse(subtask);
|
|
2386
2449
|
} catch (error) {
|
|
2387
|
-
|
|
2450
|
+
log16.error("Error in handleCreateSubtask:", error);
|
|
2388
2451
|
return handleError(error);
|
|
2389
2452
|
}
|
|
2390
2453
|
}
|
|
2391
2454
|
|
|
2392
2455
|
// src/tools/get-create-meta.ts
|
|
2393
|
-
var
|
|
2456
|
+
var log17 = createLogger("tool:get-create-meta");
|
|
2394
2457
|
var getCreateMetaTool = {
|
|
2395
2458
|
name: TOOL_NAMES.GET_CREATE_META,
|
|
2396
2459
|
description: "Retrieves create metadata for a project, showing all available fields (including custom fields) for creating issues. Shows required vs optional fields, field types, and allowed values. Use this before creating issues to discover what fields are needed.",
|
|
@@ -2412,7 +2475,7 @@ var getCreateMetaTool = {
|
|
|
2412
2475
|
async function handleGetCreateMeta(input) {
|
|
2413
2476
|
try {
|
|
2414
2477
|
const validated = validateInput(GetCreateMetaInputSchema, input);
|
|
2415
|
-
|
|
2478
|
+
log17.info(`Getting create metadata for project ${validated.projectKey}...`);
|
|
2416
2479
|
const options = {
|
|
2417
2480
|
projectKeys: [validated.projectKey],
|
|
2418
2481
|
expand: "projects.issuetypes.fields"
|
|
@@ -2421,16 +2484,16 @@ async function handleGetCreateMeta(input) {
|
|
|
2421
2484
|
options.issueTypeNames = [validated.issueTypeName];
|
|
2422
2485
|
}
|
|
2423
2486
|
const meta = await getCreateMeta(options);
|
|
2424
|
-
|
|
2487
|
+
log17.info(`Retrieved create metadata for ${validated.projectKey}`);
|
|
2425
2488
|
return formatCreateMetaResponse(meta);
|
|
2426
2489
|
} catch (error) {
|
|
2427
|
-
|
|
2490
|
+
log17.error("Error in handleGetCreateMeta:", error);
|
|
2428
2491
|
return handleError(error);
|
|
2429
2492
|
}
|
|
2430
2493
|
}
|
|
2431
2494
|
|
|
2432
2495
|
// src/tools/get-custom-fields.ts
|
|
2433
|
-
var
|
|
2496
|
+
var log18 = createLogger("tool:get-custom-fields");
|
|
2434
2497
|
var getCustomFieldsTool = {
|
|
2435
2498
|
name: TOOL_NAMES.GET_CUSTOM_FIELDS,
|
|
2436
2499
|
description: "Retrieves all custom fields available in Jira. Shows custom field names, IDs (e.g., customfield_10071), and types. Useful for discovering what custom fields exist and their identifiers.",
|
|
@@ -2449,12 +2512,12 @@ async function handleGetCustomFields(input) {
|
|
|
2449
2512
|
try {
|
|
2450
2513
|
const validated = validateInput(GetCustomFieldsInputSchema, input);
|
|
2451
2514
|
const projectMsg = validated.projectKey ? ` for project ${validated.projectKey}` : "";
|
|
2452
|
-
|
|
2515
|
+
log18.info(`Getting custom fields${projectMsg}...`);
|
|
2453
2516
|
const fields = await getFields();
|
|
2454
|
-
|
|
2517
|
+
log18.info(`Retrieved ${fields.filter((f) => f.custom).length} custom fields`);
|
|
2455
2518
|
return formatCustomFieldsResponse(fields, validated.projectKey);
|
|
2456
2519
|
} catch (error) {
|
|
2457
|
-
|
|
2520
|
+
log18.error("Error in handleGetCustomFields:", error);
|
|
2458
2521
|
return handleError(error);
|
|
2459
2522
|
}
|
|
2460
2523
|
}
|
|
@@ -2467,7 +2530,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
2467
2530
|
} catch {
|
|
2468
2531
|
}
|
|
2469
2532
|
}
|
|
2470
|
-
var
|
|
2533
|
+
var log19 = createLogger("server");
|
|
2471
2534
|
var toolHandlers = /* @__PURE__ */ new Map([
|
|
2472
2535
|
[TOOL_NAMES.GET_VISIBLE_PROJECTS, handleGetVisibleProjects],
|
|
2473
2536
|
[TOOL_NAMES.GET_ISSUE, handleGetIssue],
|
|
@@ -2571,7 +2634,7 @@ async function main() {
|
|
|
2571
2634
|
console.error("\u{1F680} Jira MCP server running on stdio");
|
|
2572
2635
|
}
|
|
2573
2636
|
main().catch((error) => {
|
|
2574
|
-
|
|
2637
|
+
log19.error("Fatal error:", error);
|
|
2575
2638
|
process.exit(1);
|
|
2576
2639
|
});
|
|
2577
2640
|
//# sourceMappingURL=index.js.map
|