backlog-mcp-server 0.15.0 → 0.16.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.ja.md +20 -10
- package/README.md +20 -10
- package/build/auth/backlogAuthContext.d.ts +2 -0
- package/build/auth/backlogOAuthClient.d.ts +10 -0
- package/build/auth/backlogOAuthConfig.d.ts +9 -0
- package/build/auth/bearerAuthMiddleware.d.ts +4 -0
- package/build/auth/oauthRoutes.d.ts +4 -0
- package/build/auth/tokenStore.d.ts +62 -0
- package/build/backlog/backlogErrorHandler.d.ts +2 -0
- package/build/backlog/customFields.d.ts +29 -0
- package/build/backlog/parseBacklogAPIError.d.ts +8 -0
- package/build/createBacklogMcpServer.d.ts +29 -0
- package/build/createBacklogMcpServer.js +9 -4
- package/build/createDescriptionHelper.d.ts +18 -0
- package/build/createDescriptionHelper.js +24 -0
- package/build/handlers/builders/composeToolHandler.d.ts +31 -0
- package/build/handlers/builders/composeToolHandler.js +21 -9
- package/build/handlers/transformers/wrapWithErrorHandling.d.ts +2 -0
- package/build/handlers/transformers/wrapWithFieldPicking.d.ts +4 -0
- package/build/handlers/transformers/wrapWithOrganizationContext.d.ts +3 -0
- package/build/handlers/transformers/wrapWithTokenLimit.d.ts +2 -0
- package/build/handlers/transformers/wrapWithToolResult.d.ts +6 -0
- package/build/httpMcpServer.d.ts +22 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +29 -11
- package/build/lib.d.ts +25 -0
- package/build/lib.js +20 -0
- package/build/loadDescriptionOverrides.d.ts +17 -0
- package/build/loadDescriptionOverrides.js +24 -0
- package/build/registerTools.d.ts +5 -0
- package/build/registerTools.js +7 -6
- package/build/tools/addDocument.d.ts +15 -0
- package/build/tools/addIssue.d.ts +30 -0
- package/build/tools/addIssueComment.d.ts +14 -0
- package/build/tools/addProject.d.ts +18 -0
- package/build/tools/addPullRequest.d.ts +20 -0
- package/build/tools/addPullRequestComment.d.ts +16 -0
- package/build/tools/addRelatedIssue.d.ts +12 -0
- package/build/tools/addVersionMilestone.d.ts +15 -0
- package/build/tools/addWatching.d.ts +11 -0
- package/build/tools/addWiki.d.ts +13 -0
- package/build/tools/countIssues.d.ts +48 -0
- package/build/tools/deleteIssue.d.ts +11 -0
- package/build/tools/deleteProject.d.ts +11 -0
- package/build/tools/deleteVersion.d.ts +12 -0
- package/build/tools/deleteWatching.d.ts +10 -0
- package/build/tools/dynamicTools/organizations.d.ts +6 -0
- package/build/tools/dynamicTools/toolsets.d.ts +15 -0
- package/build/tools/getCategories.d.ts +11 -0
- package/build/tools/getCustomFields.d.ts +12 -0
- package/build/tools/getDocument.d.ts +10 -0
- package/build/tools/getDocumentTree.d.ts +10 -0
- package/build/tools/getDocuments.d.ts +11 -0
- package/build/tools/getGitRepositories.d.ts +11 -0
- package/build/tools/getGitRepository.d.ts +13 -0
- package/build/tools/getIssue.d.ts +11 -0
- package/build/tools/getIssueComments.d.ts +18 -0
- package/build/tools/getIssueTypes.d.ts +11 -0
- package/build/tools/getIssues.d.ts +75 -0
- package/build/tools/getMyself.d.ts +7 -0
- package/build/tools/getNotifications.d.ts +16 -0
- package/build/tools/getNotificationsCount.d.ts +11 -0
- package/build/tools/getPriorities.d.ts +7 -0
- package/build/tools/getProject.d.ts +11 -0
- package/build/tools/getProjectList.d.ts +11 -0
- package/build/tools/getProjectUsers.d.ts +11 -0
- package/build/tools/getPullRequest.d.ts +14 -0
- package/build/tools/getPullRequestComments.d.ts +21 -0
- package/build/tools/getPullRequests.d.ts +19 -0
- package/build/tools/getPullRequestsCount.d.ts +17 -0
- package/build/tools/getRelatedIssues.d.ts +11 -0
- package/build/tools/getResolutions.d.ts +7 -0
- package/build/tools/getSpace.d.ts +7 -0
- package/build/tools/getSpaceActivities.d.ts +45 -0
- package/build/tools/getUserRecentUpdates.d.ts +46 -0
- package/build/tools/getUserStarsCount.d.ts +12 -0
- package/build/tools/getUsers.d.ts +7 -0
- package/build/tools/getVersionMilestoneList.d.ts +11 -0
- package/build/tools/getWatchingListCount.d.ts +10 -0
- package/build/tools/getWatchingListItems.d.ts +10 -0
- package/build/tools/getWiki.d.ts +10 -0
- package/build/tools/getWikiPages.d.ts +12 -0
- package/build/tools/getWikisCount.d.ts +11 -0
- package/build/tools/markNotificationAsRead.d.ts +13 -0
- package/build/tools/markWatchingAsRead.d.ts +13 -0
- package/build/tools/removeRelatedIssue.d.ts +12 -0
- package/build/tools/resetUnreadNotificationCount.d.ts +7 -0
- package/build/tools/shared/customFieldFiltersSchema.d.ts +21 -0
- package/build/tools/tools.d.ts +4 -0
- package/build/tools/updateIssue.d.ts +34 -0
- package/build/tools/updateIssueComment.d.ts +13 -0
- package/build/tools/updateProject.d.ts +21 -0
- package/build/tools/updatePullRequest.d.ts +20 -0
- package/build/tools/updatePullRequestComment.d.ts +16 -0
- package/build/tools/updateVersionMilestone.d.ts +17 -0
- package/build/tools/updateWatching.d.ts +11 -0
- package/build/tools/updateWiki.d.ts +13 -0
- package/build/types/mcp.d.ts +10 -0
- package/build/types/result.d.ts +10 -0
- package/build/types/tool.d.ts +24 -0
- package/build/types/toolsets.d.ts +16 -0
- package/build/types/zod/backlogOutputDefinition.d.ts +3334 -0
- package/build/types/zod/backlogOutputDefinition.js +0 -16
- package/build/utils/backlogClientRegistry.d.ts +28 -0
- package/build/utils/backlogClientRegistry.js +4 -0
- package/build/utils/backlogOrganizationContext.d.ts +2 -0
- package/build/utils/generateFieldsDescription.d.ts +5 -0
- package/build/utils/logger.d.ts +2 -0
- package/build/utils/logger.js +27 -14
- package/build/utils/resolveIdOrKey.d.ts +18 -0
- package/build/utils/runToolSafely.d.ts +6 -0
- package/build/utils/tokenCounter.d.ts +1 -0
- package/build/utils/toolRegistrar.d.ts +5 -0
- package/build/utils/toolsetUtils.d.ts +6 -0
- package/build/utils/toolsetUtils.js +0 -20
- package/build/utils/wrapServerWithToolRegistry.d.ts +6 -0
- package/package.json +12 -3
- package/build/createTranslationHelper.js +0 -28
|
@@ -84,7 +84,6 @@ export const CustomFieldTypeSchema = z.nativeEnum({
|
|
|
84
84
|
CheckBox: 7,
|
|
85
85
|
Radio: 8,
|
|
86
86
|
});
|
|
87
|
-
export const WebhookActivityIdSchema = z.number();
|
|
88
87
|
export const UserSchema = z.object({
|
|
89
88
|
id: z.number(),
|
|
90
89
|
userId: z.string(),
|
|
@@ -434,21 +433,6 @@ export const WikiListItemSchema = z.object({
|
|
|
434
433
|
export const WikiCountSchema = z.object({
|
|
435
434
|
count: z.number(),
|
|
436
435
|
});
|
|
437
|
-
export const DocumentSchema = z.object({
|
|
438
|
-
id: z.number(),
|
|
439
|
-
projectId: z.number(),
|
|
440
|
-
name: z.string(),
|
|
441
|
-
content: z.string(),
|
|
442
|
-
createdUser: UserSchema,
|
|
443
|
-
created: z.string(),
|
|
444
|
-
updatedUser: UserSchema,
|
|
445
|
-
updated: z.string(),
|
|
446
|
-
});
|
|
447
|
-
export const DocumentAttachmentSchema = z.object({
|
|
448
|
-
filename: z.string(),
|
|
449
|
-
body: z.any(),
|
|
450
|
-
url: z.string(),
|
|
451
|
-
});
|
|
452
436
|
export const DocumentTagSchema = z.object({
|
|
453
437
|
id: z.number(),
|
|
454
438
|
name: z.string(),
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Backlog } from 'backlog-js';
|
|
2
|
+
export type BacklogOrganizationInfo = {
|
|
3
|
+
name: string;
|
|
4
|
+
domain: string;
|
|
5
|
+
isDefault: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type BacklogClientResolver = (organization?: string) => Backlog;
|
|
8
|
+
export type BacklogClientRegistry = {
|
|
9
|
+
resolveClient: BacklogClientResolver;
|
|
10
|
+
createScopedClient: () => Backlog;
|
|
11
|
+
listOrganizations: () => BacklogOrganizationInfo[];
|
|
12
|
+
getDefaultOrganization: () => string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Whether more than one Backlog space can be addressed. Only then is it worth
|
|
15
|
+
* spending an `organization` parameter on every tool and publishing
|
|
16
|
+
* `list_organizations` — with a single space there is nothing to choose.
|
|
17
|
+
* Keyed on the configured mode, not the organization count, so a multi-org
|
|
18
|
+
* setup that happens to declare one space still exposes the parameter.
|
|
19
|
+
*/
|
|
20
|
+
isMultiOrganization: boolean;
|
|
21
|
+
};
|
|
22
|
+
type Environment = Record<string, string | undefined>;
|
|
23
|
+
type RegistryInput = {
|
|
24
|
+
env?: Environment;
|
|
25
|
+
};
|
|
26
|
+
export declare function createBacklogClientRegistry(input?: RegistryInput): BacklogClientRegistry;
|
|
27
|
+
export declare function createOAuthBacklogClientRegistry(domain: string): BacklogClientRegistry;
|
|
28
|
+
export {};
|
|
@@ -39,6 +39,7 @@ export function createBacklogClientRegistry(input = {}) {
|
|
|
39
39
|
}),
|
|
40
40
|
listOrganizations: () => [info],
|
|
41
41
|
getDefaultOrganization: () => defaultName,
|
|
42
|
+
isMultiOrganization: false,
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
function createMultiOrganizationRegistryFromEnv(env) {
|
|
@@ -115,6 +116,7 @@ function createMultiOrganizationRegistryFromEnv(env) {
|
|
|
115
116
|
}),
|
|
116
117
|
listOrganizations: () => organizationInfo,
|
|
117
118
|
getDefaultOrganization: () => defaultOrganization,
|
|
119
|
+
isMultiOrganization: true,
|
|
118
120
|
};
|
|
119
121
|
}
|
|
120
122
|
function resolveKnownClient(clients, organization) {
|
|
@@ -147,6 +149,8 @@ export function createOAuthBacklogClientRegistry(domain) {
|
|
|
147
149
|
createScopedClient: () => createBacklogClientProxy(resolveOAuthClient),
|
|
148
150
|
listOrganizations: () => [info],
|
|
149
151
|
getDefaultOrganization: () => defaultName,
|
|
152
|
+
// OAuth authorises against one Backlog domain per server.
|
|
153
|
+
isMultiOrganization: false,
|
|
150
154
|
};
|
|
151
155
|
}
|
|
152
156
|
function createBacklogClientProxy(resolveClient) {
|
package/build/utils/logger.js
CHANGED
|
@@ -3,18 +3,31 @@ if (!process.env.NODE_ENV) {
|
|
|
3
3
|
process.env.NODE_ENV = 'production';
|
|
4
4
|
}
|
|
5
5
|
const isProd = process.env.NODE_ENV === 'production';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
// Plain JSON on stderr. stdout carries the JSON-RPC stream on the stdio
|
|
7
|
+
// transport, so a log line landing there would corrupt the protocol.
|
|
8
|
+
const plainLogger = () => pino({ level: isProd ? 'error' : 'debug' }, pino.destination({ dest: 2, sync: false }));
|
|
9
|
+
// `pino-pretty` is a development-only dependency, so an installed copy of this
|
|
10
|
+
// package does not have it. pino resolves a transport target eagerly and throws
|
|
11
|
+
// synchronously when it cannot, so asking is cheaper than probing the module
|
|
12
|
+
// graph — and a dev-mode run without pino-pretty still gets its logs.
|
|
13
|
+
const prettyLogger = () => {
|
|
14
|
+
try {
|
|
15
|
+
return pino({
|
|
16
|
+
level: 'debug',
|
|
17
|
+
transport: {
|
|
18
|
+
target: 'pino-pretty',
|
|
19
|
+
options: {
|
|
20
|
+
destination: 2,
|
|
21
|
+
colorize: true,
|
|
22
|
+
translateTime: 'SYS:yyyy-mm-dd HH:MM:ss.l',
|
|
23
|
+
ignore: 'pid,hostname',
|
|
24
|
+
singleLine: true,
|
|
25
|
+
},
|
|
18
26
|
},
|
|
19
|
-
}
|
|
20
|
-
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return plainLogger();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export const logger = isProd ? plainLogger() : prettyLogger();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DescriptionHelper } from '../createDescriptionHelper.js';
|
|
2
|
+
export type EntityName = 'issue' | 'project' | 'repository';
|
|
3
|
+
type ResolveResult = {
|
|
4
|
+
ok: true;
|
|
5
|
+
value: string | number;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: Error;
|
|
9
|
+
};
|
|
10
|
+
export declare const resolveIdOrKey: <E extends EntityName>(entity: E, values: {
|
|
11
|
+
id?: number;
|
|
12
|
+
key?: string;
|
|
13
|
+
}, t: DescriptionHelper["t"]) => ResolveResult;
|
|
14
|
+
export declare const resolveIdOrName: <E extends EntityName>(entity: E, values: {
|
|
15
|
+
id?: number;
|
|
16
|
+
name?: string;
|
|
17
|
+
}, t: DescriptionHelper["t"]) => ResolveResult;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ErrorLike, SafeResult } from '../types/result.js';
|
|
2
|
+
/**
|
|
3
|
+
* Runs a tool handler safely, catching any errors and converting to SafeResult.
|
|
4
|
+
* The `onError` handler defines how to turn unknown errors into ErrorLike objects.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runToolSafely<I, O>(fn: (input: I) => Promise<O>, onError?: (err: unknown) => ErrorLike): (input: I) => Promise<SafeResult<O>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function countTokens(text: string): number;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { MCPOptions } from '../types/mcp.js';
|
|
2
|
+
import { ToolRegistrar } from '../types/tool.js';
|
|
3
|
+
import { ToolsetGroup } from '../types/toolsets.js';
|
|
4
|
+
import { BacklogMCPServer } from './wrapServerWithToolRegistry.js';
|
|
5
|
+
export declare function createToolRegistrar(server: BacklogMCPServer, toolsetGroup: ToolsetGroup, options: MCPOptions): ToolRegistrar;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Backlog } from 'backlog-js';
|
|
2
|
+
import { ToolsetGroup, Toolset } from '../types/toolsets.js';
|
|
3
|
+
import { DescriptionHelper } from '../createDescriptionHelper.js';
|
|
4
|
+
export declare function getToolset(group: ToolsetGroup, name: string): Toolset | undefined;
|
|
5
|
+
export declare function enableToolset(group: ToolsetGroup, name: string): string;
|
|
6
|
+
export declare const buildToolsetGroup: (backlog: Backlog, helper: DescriptionHelper, enabledToolsets: string[]) => ToolsetGroup;
|
|
@@ -11,26 +11,6 @@ export function enableToolset(group, name) {
|
|
|
11
11
|
ts.enabled = true;
|
|
12
12
|
return `Toolset ${name} enabled`;
|
|
13
13
|
}
|
|
14
|
-
export function getEnabledTools(group) {
|
|
15
|
-
return group.toolsets.filter((ts) => ts.enabled).flatMap((ts) => ts.tools);
|
|
16
|
-
}
|
|
17
|
-
export function listAvailableToolsets(group) {
|
|
18
|
-
return group.toolsets.map((ts) => ({
|
|
19
|
-
name: ts.name,
|
|
20
|
-
description: ts.description,
|
|
21
|
-
currentlyEnabled: ts.enabled,
|
|
22
|
-
canEnable: true,
|
|
23
|
-
}));
|
|
24
|
-
}
|
|
25
|
-
export function listToolsetTools(group, name) {
|
|
26
|
-
const ts = getToolset(group, name);
|
|
27
|
-
return (ts?.tools.map((tool) => ({
|
|
28
|
-
name: tool.name,
|
|
29
|
-
description: tool.description,
|
|
30
|
-
toolset: name,
|
|
31
|
-
canEnable: true,
|
|
32
|
-
})) ?? []);
|
|
33
|
-
}
|
|
34
14
|
export const buildToolsetGroup = (backlog, helper, enabledToolsets) => {
|
|
35
15
|
const toolsetGroup = allTools(backlog, helper);
|
|
36
16
|
const knownNames = toolsetGroup.toolsets.map((ts) => ts.name);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { McpServer, StandardSchemaWithJSON, ToolCallback } from '@modelcontextprotocol/server';
|
|
2
|
+
export interface BacklogMCPServer extends McpServer {
|
|
3
|
+
__registeredToolNames?: Set<string>;
|
|
4
|
+
registerOnce: (name: string, description: string, schema: StandardSchemaWithJSON, handler: ToolCallback<StandardSchemaWithJSON>) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function wrapServerWithToolRegistry(server: McpServer): BacklogMCPServer;
|
package/package.json
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backlog-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"backlog-mcp-server": "./build/index.js"
|
|
7
7
|
},
|
|
8
|
+
"main": "./build/lib.js",
|
|
9
|
+
"types": "./build/lib.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./build/lib.d.ts",
|
|
13
|
+
"import": "./build/lib.js"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
8
17
|
"engines": {
|
|
9
18
|
"node": ">=22"
|
|
10
19
|
},
|
|
@@ -31,9 +40,8 @@
|
|
|
31
40
|
"cosmiconfig": "^9.0.1",
|
|
32
41
|
"env-var": "^7.5.0",
|
|
33
42
|
"graphql": "^16.14.1",
|
|
34
|
-
"hono": "^4.12.
|
|
43
|
+
"hono": "^4.12.34",
|
|
35
44
|
"pino": "^10.3.1",
|
|
36
|
-
"pino-pretty": "^13.1.3",
|
|
37
45
|
"yargs": "^18.0.0",
|
|
38
46
|
"zod": "^4.4.3"
|
|
39
47
|
},
|
|
@@ -48,6 +56,7 @@
|
|
|
48
56
|
"eslint": "^10.4.1",
|
|
49
57
|
"eslint-config-prettier": "^10.1.8",
|
|
50
58
|
"eslint-plugin-prettier": "^5.5.6",
|
|
59
|
+
"pino-pretty": "^13.1.3",
|
|
51
60
|
"prettier": "^3.8.3",
|
|
52
61
|
"tsx": "^4.22.4",
|
|
53
62
|
"typescript": "^6.0.3",
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { cosmiconfigSync } from 'cosmiconfig';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
export function createTranslationHelper(options) {
|
|
4
|
-
const usedKeys = {};
|
|
5
|
-
const configName = options?.configName ?? 'backlog-mcp-server';
|
|
6
|
-
// Load config file
|
|
7
|
-
const explorer = cosmiconfigSync(configName);
|
|
8
|
-
const searchPath = options?.searchDir ?? os.homedir();
|
|
9
|
-
const configResult = explorer.search(searchPath);
|
|
10
|
-
const config = configResult?.config || {};
|
|
11
|
-
function toEnvKey(key) {
|
|
12
|
-
return `BACKLOG_MCP_${key}`;
|
|
13
|
-
}
|
|
14
|
-
function t(key, fallback) {
|
|
15
|
-
const upperKey = key.toUpperCase();
|
|
16
|
-
if (usedKeys[upperKey]) {
|
|
17
|
-
return usedKeys[upperKey];
|
|
18
|
-
}
|
|
19
|
-
// Priority:ENV → config → fallback
|
|
20
|
-
const value = process.env[toEnvKey(upperKey)] || config[upperKey] || fallback;
|
|
21
|
-
usedKeys[upperKey] = value;
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
function dump() {
|
|
25
|
-
return { ...usedKeys };
|
|
26
|
-
}
|
|
27
|
-
return { t, dump };
|
|
28
|
-
}
|