@sixtynine-digital/blitz-mcp 0.3.0 → 0.4.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/dist/{http-kEKXBhoW.mjs → http-DqMYQFKB.mjs} +2 -2
- package/dist/{http-kEKXBhoW.mjs.map → http-DqMYQFKB.mjs.map} +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{server-Y1bv_8dx.mjs → server-BIEP9XVB.mjs} +109 -11
- package/dist/server-BIEP9XVB.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/server-Y1bv_8dx.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as loadConfig, t as createServer$1 } from "./server-
|
|
2
|
+
import { n as loadConfig, t as createServer$1 } from "./server-BIEP9XVB.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { createServer } from "node:http";
|
|
5
5
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -138,4 +138,4 @@ function startHttpServer() {
|
|
|
138
138
|
|
|
139
139
|
//#endregion
|
|
140
140
|
export { startHttpServer };
|
|
141
|
-
//# sourceMappingURL=http-
|
|
141
|
+
//# sourceMappingURL=http-DqMYQFKB.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-
|
|
1
|
+
{"version":3,"file":"http-DqMYQFKB.mjs","names":["params: Record<string, string>","createHttpServer","body","createServer"],"sources":["../src/http.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createServer as createHttpServer } from \"node:http\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport { loadConfig } from \"./config.js\";\nimport { createServer } from \"./server.js\";\n\ninterface SessionEntry {\n transport: StreamableHTTPServerTransport;\n server: ReturnType<typeof createServer>;\n}\n\nconst sessions = new Map<string, SessionEntry>();\n\nfunction parseBody(req: import(\"node:http\").IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let data = \"\";\n req.on(\"data\", (chunk: Buffer) => (data += chunk.toString()));\n req.on(\"end\", () => {\n try {\n resolve(JSON.parse(data));\n } catch {\n reject(new Error(\"Invalid JSON\"));\n }\n });\n req.on(\"error\", reject);\n });\n}\n\nfunction jsonResponse(\n res: import(\"node:http\").ServerResponse,\n status: number,\n body: unknown\n) {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n}\n\nfunction parseQueryParams(url: string): Record<string, string> {\n const idx = url.indexOf(\"?\");\n if (idx === -1) return {};\n const params: Record<string, string> = {};\n const search = url.slice(idx + 1);\n for (const pair of search.split(\"&\")) {\n const [key, val] = pair.split(\"=\");\n if (key) params[decodeURIComponent(key)] = decodeURIComponent(val || \"\");\n }\n return params;\n}\n\nexport function startHttpServer() {\n const port = parseInt(process.env.BLITZ_MCP_PORT || \"3100\", 10);\n const apiUrl = process.env.BLITZ_API_URL;\n\n if (!apiUrl) {\n throw new Error(\"BLITZ_API_URL environment variable is required\");\n }\n\n const httpServer = createHttpServer(async (req, res) => {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, DELETE, OPTIONS\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type, mcp-session-id\"\n );\n res.setHeader(\"Access-Control-Expose-Headers\", \"mcp-session-id\");\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const urlPath = (req.url || \"\").split(\"?\")[0];\n\n if (urlPath !== \"/mcp\") {\n jsonResponse(res, 404, { error: \"Not found\" });\n return;\n }\n\n if (req.method === \"POST\") {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n if (sessionId && sessions.has(sessionId)) {\n const entry = sessions.get(sessionId)!;\n const body = await parseBody(req);\n await entry.transport.handleRequest(req, res, body);\n return;\n }\n\n const body = (await parseBody(req)) as Record<string, unknown>;\n\n if (!sessionId && isInitializeRequest(body)) {\n // Read per-user credentials from query params\n const query = parseQueryParams(req.url || \"\");\n const apiKey = query.api_key || process.env.BLITZ_API_KEY;\n const workspaceSlug = query.workspace || process.env.BLITZ_WORKSPACE_SLUG;\n\n if (!apiKey) {\n jsonResponse(res, 401, {\n error: \"API key required. Add ?api_key=plane_api_XXX to the URL\",\n });\n return;\n }\n\n if (!workspaceSlug) {\n jsonResponse(res, 400, {\n error:\n \"Workspace slug required. Add ?workspace=YOUR_SLUG to the URL\",\n });\n return;\n }\n\n const projectId = query.project_id || process.env.BLITZ_PROJECT_ID;\n\n const config = loadConfig({\n apiUrl,\n apiKey,\n workspaceSlug,\n projectId: projectId || undefined,\n });\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n sessions.set(id, { transport, server });\n },\n });\n\n transport.onclose = () => {\n if (transport.sessionId) {\n sessions.delete(transport.sessionId);\n }\n };\n\n const server = createServer(config);\n await server.connect(transport);\n await transport.handleRequest(req, res, body);\n return;\n }\n\n jsonResponse(res, 400, {\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Invalid session\" },\n id: null,\n });\n return;\n }\n\n if (req.method === \"GET\") {\n const sessionId = req.headers[\"mcp-session-id\"] as string;\n if (sessionId && sessions.has(sessionId)) {\n const entry = sessions.get(sessionId)!;\n await entry.transport.handleRequest(req, res);\n } else {\n jsonResponse(res, 400, { error: \"Invalid session\" });\n }\n return;\n }\n\n if (req.method === \"DELETE\") {\n const sessionId = req.headers[\"mcp-session-id\"] as string;\n if (sessionId && sessions.has(sessionId)) {\n const entry = sessions.get(sessionId)!;\n await entry.transport.handleRequest(req, res);\n } else {\n jsonResponse(res, 400, { error: \"Invalid session\" });\n }\n return;\n }\n\n jsonResponse(res, 405, { error: \"Method not allowed\" });\n });\n\n httpServer.listen(port, \"0.0.0.0\", () => {\n console.log(`Blitz MCP HTTP server running on port ${port}`);\n console.log(`Endpoint: http://0.0.0.0:${port}/mcp`);\n });\n\n process.on(\"SIGINT\", () => {\n httpServer.close();\n process.exit(0);\n });\n\n process.on(\"SIGTERM\", () => {\n httpServer.close();\n process.exit(0);\n });\n}\n"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as loadConfig, t as createServer } from "./server-
|
|
2
|
+
import { n as loadConfig, t as createServer } from "./server-BIEP9XVB.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/index.ts
|
|
5
5
|
if ((process.env.BLITZ_MCP_MODE || "stdio") === "http") {
|
|
6
|
-
const { startHttpServer } = await import("./http-
|
|
6
|
+
const { startHttpServer } = await import("./http-DqMYQFKB.mjs");
|
|
7
7
|
startHttpServer();
|
|
8
8
|
} else {
|
|
9
9
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
@@ -145,6 +145,84 @@ function registerSearchTools(server, client, config) {
|
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/tools/members.ts
|
|
150
|
+
var MemberCache = class {
|
|
151
|
+
cache = /* @__PURE__ */ new Map();
|
|
152
|
+
ttlMs;
|
|
153
|
+
constructor(ttlMs = 300 * 1e3) {
|
|
154
|
+
this.ttlMs = ttlMs;
|
|
155
|
+
}
|
|
156
|
+
get(key) {
|
|
157
|
+
const entry = this.cache.get(key);
|
|
158
|
+
if (!entry || Date.now() - entry.fetchedAt > this.ttlMs) {
|
|
159
|
+
if (entry) this.cache.delete(key);
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return entry.members;
|
|
163
|
+
}
|
|
164
|
+
set(key, members) {
|
|
165
|
+
this.cache.set(key, {
|
|
166
|
+
members,
|
|
167
|
+
fetchedAt: Date.now()
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const cache = new MemberCache();
|
|
172
|
+
async function fetchProjectMembers(client, workspaceSlug, projectId) {
|
|
173
|
+
const key = `project:${projectId}`;
|
|
174
|
+
const cached = cache.get(key);
|
|
175
|
+
if (cached) return cached;
|
|
176
|
+
const data = await client.get(`workspaces/${workspaceSlug}/projects/${projectId}/members/`);
|
|
177
|
+
cache.set(key, data);
|
|
178
|
+
return data;
|
|
179
|
+
}
|
|
180
|
+
async function fetchWorkspaceMembers(client, workspaceSlug) {
|
|
181
|
+
const key = `workspace:${workspaceSlug}`;
|
|
182
|
+
const cached = cache.get(key);
|
|
183
|
+
if (cached) return cached;
|
|
184
|
+
const data = await client.get(`workspaces/${workspaceSlug}/members/`);
|
|
185
|
+
cache.set(key, data);
|
|
186
|
+
return data;
|
|
187
|
+
}
|
|
188
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
189
|
+
async function resolveAssignees(values, client, workspaceSlug, projectId) {
|
|
190
|
+
if (values.every((v) => UUID_RE.test(v))) return values;
|
|
191
|
+
const members = await fetchProjectMembers(client, workspaceSlug, projectId);
|
|
192
|
+
return values.map((value) => {
|
|
193
|
+
if (UUID_RE.test(value)) return value;
|
|
194
|
+
const lower = value.toLowerCase();
|
|
195
|
+
const match = members.find((m) => m.display_name.toLowerCase() === lower || `${m.first_name} ${m.last_name}`.toLowerCase().trim() === lower || m.email.toLowerCase() === lower);
|
|
196
|
+
if (!match) throw new Error(`Could not resolve assignee "${value}". Use list-members to see available members.`);
|
|
197
|
+
return match.id;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function enrichAssigneeNames(item, members) {
|
|
201
|
+
const assigneeIds = item.assignees;
|
|
202
|
+
if (!Array.isArray(assigneeIds) || assigneeIds.length === 0) return item;
|
|
203
|
+
const memberMap = new Map(members.map((m) => [m.id, m.display_name]));
|
|
204
|
+
const assignees = assigneeIds.map((id) => ({
|
|
205
|
+
id,
|
|
206
|
+
display_name: memberMap.get(id) ?? "Unknown"
|
|
207
|
+
}));
|
|
208
|
+
return {
|
|
209
|
+
...item,
|
|
210
|
+
assignees
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function registerMemberTools(server, client, config) {
|
|
214
|
+
const { workspaceSlug } = config;
|
|
215
|
+
server.tool("list-members", "List members of a project or workspace. Use this to find user IDs and display names for assigning work items. You can also assign work items by display name directly.", { project_id: z.string().uuid().optional().describe("Project UUID - lists project members. Omit to list workspace members (requires admin).") }, async ({ project_id }) => {
|
|
216
|
+
let members;
|
|
217
|
+
if (project_id || config.projectId) members = await fetchProjectMembers(client, workspaceSlug, project_id || config.projectId);
|
|
218
|
+
else members = await fetchWorkspaceMembers(client, workspaceSlug);
|
|
219
|
+
return { content: [{
|
|
220
|
+
type: "text",
|
|
221
|
+
text: JSON.stringify(members, null, 2)
|
|
222
|
+
}] };
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
148
226
|
//#endregion
|
|
149
227
|
//#region src/tools/work-items.ts
|
|
150
228
|
const STATE_GROUPS = [
|
|
@@ -158,10 +236,10 @@ const SUMMARY_FIELDS = [
|
|
|
158
236
|
"id",
|
|
159
237
|
"sequence_id",
|
|
160
238
|
"name",
|
|
161
|
-
"
|
|
239
|
+
"state",
|
|
162
240
|
"priority",
|
|
163
|
-
"
|
|
164
|
-
"
|
|
241
|
+
"assignees",
|
|
242
|
+
"labels",
|
|
165
243
|
"start_date",
|
|
166
244
|
"target_date",
|
|
167
245
|
"created_at",
|
|
@@ -228,7 +306,10 @@ function registerWorkItemTools(server, client, config) {
|
|
|
228
306
|
}).toString();
|
|
229
307
|
const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : ""}`;
|
|
230
308
|
const data = await client.get(path);
|
|
231
|
-
if (data.results && Array.isArray(data.results))
|
|
309
|
+
if (data.results && Array.isArray(data.results)) {
|
|
310
|
+
const members = await fetchProjectMembers(client, workspaceSlug, pid);
|
|
311
|
+
data.results = data.results.map((item) => enrichAssigneeNames(stripHeavyFields(item), members));
|
|
312
|
+
}
|
|
232
313
|
return { content: [{
|
|
233
314
|
type: "text",
|
|
234
315
|
text: JSON.stringify(data, null, 2)
|
|
@@ -252,7 +333,10 @@ function registerWorkItemTools(server, client, config) {
|
|
|
252
333
|
}).toString();
|
|
253
334
|
const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : ""}`;
|
|
254
335
|
const data = await client.get(path);
|
|
255
|
-
if (data.results && Array.isArray(data.results))
|
|
336
|
+
if (data.results && Array.isArray(data.results)) {
|
|
337
|
+
const members = await fetchProjectMembers(client, workspaceSlug, pid);
|
|
338
|
+
data.results = data.results.map((item) => enrichAssigneeNames(pickSummaryFields(item), members));
|
|
339
|
+
}
|
|
256
340
|
return { content: [{
|
|
257
341
|
type: "text",
|
|
258
342
|
text: JSON.stringify(data, null, 2)
|
|
@@ -260,6 +344,14 @@ function registerWorkItemTools(server, client, config) {
|
|
|
260
344
|
});
|
|
261
345
|
server.tool("get-work-item", "Get a work item by its human-readable identifier (e.g. BLZ-42). Returns full details.", { identifier: z.string().min(1).describe("Work item identifier (e.g. PROJ-123)") }, async ({ identifier }) => {
|
|
262
346
|
const data = await client.get(`workspaces/${workspaceSlug}/work-items/${identifier}/`);
|
|
347
|
+
const projectId = data.project_id ?? data.project;
|
|
348
|
+
if (projectId && Array.isArray(data.assignees)) try {
|
|
349
|
+
const members = await fetchProjectMembers(client, workspaceSlug, projectId);
|
|
350
|
+
return { content: [{
|
|
351
|
+
type: "text",
|
|
352
|
+
text: JSON.stringify(enrichAssigneeNames(data, members), null, 2)
|
|
353
|
+
}] };
|
|
354
|
+
} catch {}
|
|
263
355
|
return { content: [{
|
|
264
356
|
type: "text",
|
|
265
357
|
text: JSON.stringify(data, null, 2)
|
|
@@ -271,9 +363,10 @@ function registerWorkItemTools(server, client, config) {
|
|
|
271
363
|
}, async ({ project_id, work_item_id }) => {
|
|
272
364
|
const pid = resolveProjectId(project_id, config);
|
|
273
365
|
const data = await client.get(`workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`);
|
|
366
|
+
const members = await fetchProjectMembers(client, workspaceSlug, pid);
|
|
274
367
|
return { content: [{
|
|
275
368
|
type: "text",
|
|
276
|
-
text: JSON.stringify(data, null, 2)
|
|
369
|
+
text: JSON.stringify(enrichAssigneeNames(data, members), null, 2)
|
|
277
370
|
}] };
|
|
278
371
|
});
|
|
279
372
|
server.tool("create-work-item", "Create a new work item (task/issue) in a project. Use list-projects to find project IDs, list-states for state IDs, and list-labels for label IDs.", {
|
|
@@ -288,14 +381,16 @@ function registerWorkItemTools(server, client, config) {
|
|
|
288
381
|
"none"
|
|
289
382
|
]).optional().describe("Priority level"),
|
|
290
383
|
state_id: z.string().uuid().optional().describe("State UUID (use list-states to find valid IDs)"),
|
|
291
|
-
assignees: z.array(z.string()
|
|
384
|
+
assignees: z.array(z.string()).optional().describe("Array of user UUIDs or display names to assign. Use list-members to find valid names."),
|
|
292
385
|
labels: z.array(z.string().uuid()).optional().describe("Array of label UUIDs"),
|
|
293
386
|
start_date: z.string().optional().describe("Start date (YYYY-MM-DD)"),
|
|
294
387
|
target_date: z.string().optional().describe("Target date (YYYY-MM-DD)"),
|
|
295
388
|
parent_id: z.string().uuid().optional().describe("Parent work item UUID for sub-issues")
|
|
296
389
|
}, async ({ project_id,...fields }) => {
|
|
297
390
|
const pid = resolveProjectId(project_id, config);
|
|
298
|
-
const
|
|
391
|
+
const resolvedFields = { ...fields };
|
|
392
|
+
if (fields.assignees?.length) resolvedFields.assignees = await resolveAssignees(fields.assignees, client, workspaceSlug, pid);
|
|
393
|
+
const body = mapBodyForApi(resolvedFields);
|
|
299
394
|
const data = await client.post(`workspaces/${workspaceSlug}/projects/${pid}/work-items/`, body);
|
|
300
395
|
return { content: [{
|
|
301
396
|
type: "text",
|
|
@@ -315,13 +410,15 @@ function registerWorkItemTools(server, client, config) {
|
|
|
315
410
|
"none"
|
|
316
411
|
]).optional().describe("New priority level"),
|
|
317
412
|
state_id: z.string().uuid().optional().describe("New state UUID (use list-states to find valid IDs)"),
|
|
318
|
-
assignees: z.array(z.string()
|
|
413
|
+
assignees: z.array(z.string()).optional().describe("New assignee UUIDs or display names (replaces existing). Use list-members to find valid names."),
|
|
319
414
|
labels: z.array(z.string().uuid()).optional().describe("New label UUIDs (replaces existing)"),
|
|
320
415
|
start_date: z.string().nullable().optional().describe("Start date (YYYY-MM-DD) or null to clear"),
|
|
321
416
|
target_date: z.string().nullable().optional().describe("Target date (YYYY-MM-DD) or null to clear")
|
|
322
417
|
}, async ({ project_id, work_item_id,...fields }) => {
|
|
323
418
|
const pid = resolveProjectId(project_id, config);
|
|
324
|
-
const
|
|
419
|
+
const resolvedFields = { ...fields };
|
|
420
|
+
if (fields.assignees?.length) resolvedFields.assignees = await resolveAssignees(fields.assignees, client, workspaceSlug, pid);
|
|
421
|
+
const body = mapBodyForApi(resolvedFields);
|
|
325
422
|
const data = await client.patch(`workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`, body);
|
|
326
423
|
return { content: [{
|
|
327
424
|
type: "text",
|
|
@@ -389,6 +486,7 @@ function registerAllTools(server, client, config) {
|
|
|
389
486
|
registerSearchTools(server, client, config);
|
|
390
487
|
registerWorkItemTools(server, client, config);
|
|
391
488
|
registerCommentTools(server, client, config);
|
|
489
|
+
registerMemberTools(server, client, config);
|
|
392
490
|
}
|
|
393
491
|
|
|
394
492
|
//#endregion
|
|
@@ -451,4 +549,4 @@ function createServer(config) {
|
|
|
451
549
|
|
|
452
550
|
//#endregion
|
|
453
551
|
export { loadConfig as n, createServer as t };
|
|
454
|
-
//# sourceMappingURL=server-
|
|
552
|
+
//# sourceMappingURL=server-BIEP9XVB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-BIEP9XVB.mjs","names":["missing: string[]","headers: Record<string, string>","members: Member[]","result: Record<string, unknown>"],"sources":["../src/config.ts","../src/client.ts","../src/tools/projects.ts","../src/tools/states.ts","../src/tools/labels.ts","../src/tools/search.ts","../src/tools/members.ts","../src/tools/work-items.ts","../src/tools/comments.ts","../src/tools/index.ts","../src/resources/projects.ts","../src/resources/index.ts","../src/server.ts"],"sourcesContent":["export interface BlitzConfig {\n apiUrl: string;\n apiKey: string;\n workspaceSlug: string;\n projectId?: string;\n}\n\nexport function loadConfig(overrides?: Partial<BlitzConfig>): BlitzConfig {\n const apiUrl = overrides?.apiUrl || process.env.BLITZ_API_URL;\n const apiKey = overrides?.apiKey || process.env.BLITZ_API_KEY;\n const workspaceSlug = overrides?.workspaceSlug || process.env.BLITZ_WORKSPACE_SLUG;\n const projectId = overrides?.projectId || process.env.BLITZ_PROJECT_ID;\n\n const missing: string[] = [];\n if (!apiUrl) missing.push(\"BLITZ_API_URL\");\n if (!apiKey) missing.push(\"BLITZ_API_KEY\");\n if (!workspaceSlug) missing.push(\"BLITZ_WORKSPACE_SLUG\");\n\n if (missing.length > 0) {\n throw new Error(\n `Missing required environment variables: ${missing.join(\", \")}\\n\\n` +\n \"Please set the following:\\n\" +\n \" BLITZ_API_URL - Blitz instance URL (e.g. http://localhost:8000)\\n\" +\n \" BLITZ_API_KEY - API key (format: plane_api_<hex>)\\n\" +\n \" BLITZ_WORKSPACE_SLUG - Workspace slug\\n\" +\n \" BLITZ_PROJECT_ID - (Optional) Default project UUID\"\n );\n }\n\n return {\n apiUrl: apiUrl!.replace(/\\/+$/, \"\"),\n apiKey: apiKey!,\n workspaceSlug: workspaceSlug!,\n projectId: projectId || undefined,\n };\n}\n\nexport function resolveProjectId(projectId: string | undefined, config: BlitzConfig): string {\n const id = projectId || config.projectId;\n if (!id) {\n throw new Error(\n \"project_id is required. Either pass it as a parameter or set BLITZ_PROJECT_ID environment variable.\"\n );\n }\n return id;\n}\n","import type { BlitzConfig } from \"./config.js\";\n\nexport class BlitzClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: BlitzConfig) {\n this.baseUrl = `${config.apiUrl}/api/v1`;\n this.apiKey = config.apiKey;\n }\n\n private async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}/${path.replace(/^\\/+/, \"\")}`;\n\n const headers: Record<string, string> = {\n \"X-Api-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n };\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n throw new Error(\n `Rate limit exceeded. ${retryAfter ? `Retry after ${retryAfter} seconds.` : \"Please wait before retrying.\"}`\n );\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const data = await response.json();\n\n if (!response.ok) {\n const message =\n typeof data === \"object\" && data !== null\n ? JSON.stringify(data, null, 2)\n : String(data);\n throw new Error(`API error (${response.status}): ${message}`);\n }\n\n return data as T;\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T = unknown>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async patch<T = unknown>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport function registerProjectTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-projects\",\n \"List all projects in the Blitz workspace. Returns project names, identifiers, and IDs.\",\n {},\n async () => {\n const data = await client.get(`workspaces/${config.workspaceSlug}/projects/`);\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nexport function registerStateTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-states\",\n \"List all workflow states for a project. Use this to find valid state IDs when creating or updating work items.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n },\n async ({ project_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/states/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nexport function registerLabelTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-labels\",\n \"List all labels for a project. Use this to find valid label IDs when creating or updating work items.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n },\n async ({ project_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/labels/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"create-label\",\n \"Create a new label in a project.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n name: z.string().min(1).max(255).describe(\"Label name\"),\n color: z.string().optional().describe(\"Hex color (e.g. #ff0000)\"),\n description: z.string().optional().describe(\"Label description\"),\n },\n async ({ project_id, ...body }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.post(\n `workspaces/${config.workspaceSlug}/projects/${pid}/labels/`,\n body\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport function registerSearchTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"search-work-items\",\n \"Search for work items (tasks/issues) across the workspace by text query. Searches in title and identifier.\",\n {\n query: z.string().min(1).describe(\"Search text\"),\n project_id: z.string().uuid().optional().describe(\"Optional project UUID to scope the search (defaults to BLITZ_PROJECT_ID if set)\"),\n },\n async ({ query, project_id }) => {\n const pid = project_id || config.projectId;\n let path = `workspaces/${config.workspaceSlug}/work-items/search/?search=${encodeURIComponent(query)}`;\n if (pid) {\n path += `&project_id=${pid}`;\n }\n const data = await client.get(path);\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport interface Member {\n id: string;\n first_name: string;\n last_name: string;\n email: string;\n display_name: string;\n avatar: string;\n avatar_url: string;\n}\n\n// ---- Cache ----\n\nclass MemberCache {\n private cache = new Map<string, { members: Member[]; fetchedAt: number }>();\n private ttlMs: number;\n\n constructor(ttlMs = 5 * 60 * 1000) {\n this.ttlMs = ttlMs;\n }\n\n get(key: string): Member[] | null {\n const entry = this.cache.get(key);\n if (!entry || Date.now() - entry.fetchedAt > this.ttlMs) {\n if (entry) this.cache.delete(key);\n return null;\n }\n return entry.members;\n }\n\n set(key: string, members: Member[]): void {\n this.cache.set(key, { members, fetchedAt: Date.now() });\n }\n}\n\nconst cache = new MemberCache();\n\n// ---- Fetch helpers ----\n\nexport async function fetchProjectMembers(\n client: BlitzClient,\n workspaceSlug: string,\n projectId: string,\n): Promise<Member[]> {\n const key = `project:${projectId}`;\n const cached = cache.get(key);\n if (cached) return cached;\n\n const data = await client.get<Member[]>(\n `workspaces/${workspaceSlug}/projects/${projectId}/members/`\n );\n cache.set(key, data);\n return data;\n}\n\nasync function fetchWorkspaceMembers(\n client: BlitzClient,\n workspaceSlug: string,\n): Promise<Member[]> {\n const key = `workspace:${workspaceSlug}`;\n const cached = cache.get(key);\n if (cached) return cached;\n\n const data = await client.get<Member[]>(\n `workspaces/${workspaceSlug}/members/`\n );\n cache.set(key, data);\n return data;\n}\n\n// ---- Name resolution ----\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport async function resolveAssignees(\n values: string[],\n client: BlitzClient,\n workspaceSlug: string,\n projectId: string,\n): Promise<string[]> {\n if (values.every(v => UUID_RE.test(v))) return values;\n\n const members = await fetchProjectMembers(client, workspaceSlug, projectId);\n\n return values.map(value => {\n if (UUID_RE.test(value)) return value;\n\n const lower = value.toLowerCase();\n const match = members.find(m =>\n m.display_name.toLowerCase() === lower ||\n `${m.first_name} ${m.last_name}`.toLowerCase().trim() === lower ||\n m.email.toLowerCase() === lower\n );\n if (!match) {\n throw new Error(\n `Could not resolve assignee \"${value}\". Use list-members to see available members.`\n );\n }\n return match.id;\n });\n}\n\n// ---- Enrichment helper ----\n\nexport function enrichAssigneeNames(\n item: Record<string, unknown>,\n members: Member[],\n): Record<string, unknown> {\n const assigneeIds = item.assignees;\n if (!Array.isArray(assigneeIds) || assigneeIds.length === 0) return item;\n\n const memberMap = new Map(members.map(m => [m.id, m.display_name]));\n const assignees = assigneeIds.map(id => ({\n id,\n display_name: memberMap.get(id as string) ?? \"Unknown\",\n }));\n\n return { ...item, assignees };\n}\n\n// ---- Tool registration ----\n\nexport function registerMemberTools(\n server: McpServer,\n client: BlitzClient,\n config: BlitzConfig,\n) {\n const { workspaceSlug } = config;\n\n server.tool(\n \"list-members\",\n \"List members of a project or workspace. Use this to find user IDs and display names for assigning work items. You can also assign work items by display name directly.\",\n {\n project_id: z.string().uuid().optional().describe(\n \"Project UUID - lists project members. Omit to list workspace members (requires admin).\"\n ),\n },\n async ({ project_id }) => {\n let members: Member[];\n if (project_id || config.projectId) {\n const pid = project_id || config.projectId!;\n members = await fetchProjectMembers(client, workspaceSlug, pid);\n } else {\n members = await fetchWorkspaceMembers(client, workspaceSlug);\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(members, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\nimport { fetchProjectMembers, enrichAssigneeNames, resolveAssignees } from \"./members.js\";\n\nconst STATE_GROUPS = [\"backlog\", \"unstarted\", \"started\", \"completed\", \"cancelled\"] as const;\n\nconst SUMMARY_FIELDS = [\n \"id\", \"sequence_id\", \"name\", \"state\", \"priority\",\n \"assignees\", \"labels\", \"start_date\", \"target_date\",\n \"created_at\", \"updated_at\", \"completed_at\",\n] as const;\n\nconst HEAVY_FIELDS = [\n \"description_html\", \"description_binary\", \"description_stripped\",\n \"description\", \"issue_reactions\", \"issue_attachments\", \"issue_link\",\n];\n\nfunction buildListParams(opts: {\n cursor?: string;\n per_page?: number;\n order_by?: string;\n state_group?: string[];\n state_id?: string[];\n}): URLSearchParams {\n const params = new URLSearchParams();\n if (opts.cursor) params.set(\"cursor\", opts.cursor);\n if (opts.per_page) params.set(\"per_page\", String(opts.per_page));\n if (opts.order_by) params.set(\"order_by\", opts.order_by);\n if (opts.state_group?.length) params.set(\"state_group\", opts.state_group.join(\",\"));\n if (opts.state_id?.length) params.set(\"state\", opts.state_id.join(\",\"));\n return params;\n}\n\nfunction stripHeavyFields(item: Record<string, unknown>): Record<string, unknown> {\n const result = { ...item };\n for (const field of HEAVY_FIELDS) {\n delete result[field];\n }\n return result;\n}\n\nfunction pickSummaryFields(item: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const field of SUMMARY_FIELDS) {\n if (field in item) result[field] = item[field];\n }\n return result;\n}\n\nfunction mapBodyForApi(body: Record<string, unknown>): Record<string, unknown> {\n const mapped = { ...body };\n // API serializer expects \"state\" not \"state_id\"\n if (\"state_id\" in mapped) {\n mapped.state = mapped.state_id;\n delete mapped.state_id;\n }\n // API serializer expects \"parent\" not \"parent_id\"\n if (\"parent_id\" in mapped) {\n mapped.parent = mapped.parent_id;\n delete mapped.parent_id;\n }\n return mapped;\n}\n\nexport function registerWorkItemTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n const { workspaceSlug } = config;\n\n server.tool(\n \"list-work-items\",\n \"List work items in a project with filtering, pagination and sorting. Returns all fields except heavy description content.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n cursor: z.string().optional().describe(\"Pagination cursor from previous response\"),\n per_page: z.number().min(1).max(100).optional().describe(\"Items per page (default 20)\"),\n order_by: z.string().optional().describe(\"Sort field (e.g. -created_at, priority, state)\"),\n state_group: z.array(z.enum(STATE_GROUPS)).optional().describe(\"Filter by state group: backlog, unstarted, started, completed, cancelled\"),\n state_id: z.array(z.string().uuid()).optional().describe(\"Filter by specific state UUIDs\"),\n },\n async ({ project_id, cursor, per_page, order_by, state_group, state_id }) => {\n const pid = resolveProjectId(project_id, config);\n const params = buildListParams({ cursor, per_page, order_by, state_group, state_id });\n const query = params.toString();\n const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : \"\"}`;\n const data = await client.get<Record<string, unknown>>(path);\n\n if (data.results && Array.isArray(data.results)) {\n const members = await fetchProjectMembers(client, workspaceSlug, pid);\n data.results = data.results.map((item: Record<string, unknown>) =>\n enrichAssigneeNames(stripHeavyFields(item), members)\n );\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"list-work-items-summary\",\n \"List work items with minimal fields only: name, state, priority, dates. Use this for overviews and large projects.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n cursor: z.string().optional().describe(\"Pagination cursor from previous response\"),\n per_page: z.number().min(1).max(100).optional().describe(\"Items per page (default 20)\"),\n order_by: z.string().optional().describe(\"Sort field (e.g. -created_at, priority, state)\"),\n state_group: z.array(z.enum(STATE_GROUPS)).optional().describe(\"Filter by state group: backlog, unstarted, started, completed, cancelled\"),\n state_id: z.array(z.string().uuid()).optional().describe(\"Filter by specific state UUIDs\"),\n },\n async ({ project_id, cursor, per_page, order_by, state_group, state_id }) => {\n const pid = resolveProjectId(project_id, config);\n const params = buildListParams({ cursor, per_page, order_by, state_group, state_id });\n const query = params.toString();\n const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : \"\"}`;\n const data = await client.get<Record<string, unknown>>(path);\n\n if (data.results && Array.isArray(data.results)) {\n const members = await fetchProjectMembers(client, workspaceSlug, pid);\n data.results = data.results.map((item: Record<string, unknown>) =>\n enrichAssigneeNames(pickSummaryFields(item), members)\n );\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"get-work-item\",\n \"Get a work item by its human-readable identifier (e.g. BLZ-42). Returns full details.\",\n {\n identifier: z.string().min(1).describe(\"Work item identifier (e.g. PROJ-123)\"),\n },\n async ({ identifier }) => {\n const data = await client.get<Record<string, unknown>>(\n `workspaces/${workspaceSlug}/work-items/${identifier}/`\n );\n const projectId = (data.project_id ?? data.project) as string | undefined;\n if (projectId && Array.isArray(data.assignees)) {\n try {\n const members = await fetchProjectMembers(client, workspaceSlug, projectId);\n return {\n content: [{ type: \"text\", text: JSON.stringify(enrichAssigneeNames(data, members), null, 2) }],\n };\n } catch {\n // If member fetch fails, return unenriched\n }\n }\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"get-work-item-by-id\",\n \"Get a work item by its project ID and work item UUID.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get<Record<string, unknown>>(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`\n );\n const members = await fetchProjectMembers(client, workspaceSlug, pid);\n return {\n content: [{ type: \"text\", text: JSON.stringify(enrichAssigneeNames(data, members), null, 2) }],\n };\n }\n );\n\n server.tool(\n \"create-work-item\",\n \"Create a new work item (task/issue) in a project. Use list-projects to find project IDs, list-states for state IDs, and list-labels for label IDs.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n name: z.string().min(1).max(255).describe(\"Work item title\"),\n description_html: z.string().optional().describe(\"HTML description content\"),\n priority: z\n .enum([\"urgent\", \"high\", \"medium\", \"low\", \"none\"])\n .optional()\n .describe(\"Priority level\"),\n state_id: z.string().uuid().optional().describe(\"State UUID (use list-states to find valid IDs)\"),\n assignees: z\n .array(z.string())\n .optional()\n .describe(\"Array of user UUIDs or display names to assign. Use list-members to find valid names.\"),\n labels: z\n .array(z.string().uuid())\n .optional()\n .describe(\"Array of label UUIDs\"),\n start_date: z.string().optional().describe(\"Start date (YYYY-MM-DD)\"),\n target_date: z.string().optional().describe(\"Target date (YYYY-MM-DD)\"),\n parent_id: z.string().uuid().optional().describe(\"Parent work item UUID for sub-issues\"),\n },\n async ({ project_id, ...fields }) => {\n const pid = resolveProjectId(project_id, config);\n const resolvedFields = { ...fields } as Record<string, unknown>;\n if (fields.assignees?.length) {\n resolvedFields.assignees = await resolveAssignees(\n fields.assignees, client, workspaceSlug, pid\n );\n }\n const body = mapBodyForApi(resolvedFields);\n const data = await client.post(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/`,\n body\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"update-work-item\",\n \"Update an existing work item. Only provide fields you want to change.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n name: z.string().min(1).max(255).optional().describe(\"New title\"),\n description_html: z.string().optional().describe(\"New HTML description\"),\n priority: z\n .enum([\"urgent\", \"high\", \"medium\", \"low\", \"none\"])\n .optional()\n .describe(\"New priority level\"),\n state_id: z.string().uuid().optional().describe(\"New state UUID (use list-states to find valid IDs)\"),\n assignees: z\n .array(z.string())\n .optional()\n .describe(\"New assignee UUIDs or display names (replaces existing). Use list-members to find valid names.\"),\n labels: z\n .array(z.string().uuid())\n .optional()\n .describe(\"New label UUIDs (replaces existing)\"),\n start_date: z.string().nullable().optional().describe(\"Start date (YYYY-MM-DD) or null to clear\"),\n target_date: z.string().nullable().optional().describe(\"Target date (YYYY-MM-DD) or null to clear\"),\n },\n async ({ project_id, work_item_id, ...fields }) => {\n const pid = resolveProjectId(project_id, config);\n const resolvedFields = { ...fields } as Record<string, unknown>;\n if (fields.assignees?.length) {\n resolvedFields.assignees = await resolveAssignees(\n fields.assignees, client, workspaceSlug, pid\n );\n }\n const body = mapBodyForApi(resolvedFields);\n const data = await client.patch(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`,\n body\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"delete-work-item\",\n \"Delete a work item. This action cannot be undone.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n await client.delete(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`\n );\n return {\n content: [{ type: \"text\", text: \"Work item deleted successfully.\" }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nexport function registerCommentTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-comments\",\n \"List all comments on a work item.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/comments/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"add-comment\",\n \"Add a comment to a work item.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n comment_html: z.string().min(1).describe(\"Comment content in HTML format\"),\n },\n async ({ project_id, work_item_id, comment_html }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.post(\n `workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/comments/`,\n { comment_html }\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"list-activities\",\n \"View the activity history (changelog) of a work item. Shows what changed, when, and by whom.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/activities/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { registerProjectTools } from \"./projects.js\";\nimport { registerStateTools } from \"./states.js\";\nimport { registerLabelTools } from \"./labels.js\";\nimport { registerSearchTools } from \"./search.js\";\nimport { registerWorkItemTools } from \"./work-items.js\";\nimport { registerCommentTools } from \"./comments.js\";\nimport { registerMemberTools } from \"./members.js\";\n\nexport function registerAllTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n registerProjectTools(server, client, config);\n registerStateTools(server, client, config);\n registerLabelTools(server, client, config);\n registerSearchTools(server, client, config);\n registerWorkItemTools(server, client, config);\n registerCommentTools(server, client, config);\n registerMemberTools(server, client, config);\n}\n","import { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport function registerProjectResources(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n const { workspaceSlug } = config;\n\n server.registerResource(\n \"projects\",\n \"blitz://projects\",\n {\n description: \"List of all projects in the Blitz workspace with their identifiers, names, and IDs.\",\n mimeType: \"application/json\",\n },\n async (uri) => {\n const data = await client.get(`workspaces/${workspaceSlug}/projects/`);\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n \"project-states\",\n new ResourceTemplate(\"blitz://projects/{project_id}/states\", { list: undefined }),\n {\n description: \"Workflow states for a specific project.\",\n mimeType: \"application/json\",\n },\n async (uri, { project_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/states/`\n );\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n \"project-labels\",\n new ResourceTemplate(\"blitz://projects/{project_id}/labels\", { list: undefined }),\n {\n description: \"Labels for a specific project.\",\n mimeType: \"application/json\",\n },\n async (uri, { project_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/labels/`\n );\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { registerProjectResources } from \"./projects.js\";\n\nexport function registerAllResources(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n registerProjectResources(server, client, config);\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { BlitzClient } from \"./client.js\";\nimport { registerAllTools } from \"./tools/index.js\";\nimport { registerAllResources } from \"./resources/index.js\";\nimport type { BlitzConfig } from \"./config.js\";\n\nexport function createServer(config: BlitzConfig) {\n const client = new BlitzClient(config);\n\n const server = new McpServer({\n name: \"blitz-mcp\",\n version: \"0.3.0\",\n });\n\n registerAllTools(server, client, config);\n registerAllResources(server, client, config);\n\n return server;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server-Y1bv_8dx.mjs","names":["missing: string[]","headers: Record<string, string>","result: Record<string, unknown>"],"sources":["../src/config.ts","../src/client.ts","../src/tools/projects.ts","../src/tools/states.ts","../src/tools/labels.ts","../src/tools/search.ts","../src/tools/work-items.ts","../src/tools/comments.ts","../src/tools/index.ts","../src/resources/projects.ts","../src/resources/index.ts","../src/server.ts"],"sourcesContent":["export interface BlitzConfig {\n apiUrl: string;\n apiKey: string;\n workspaceSlug: string;\n projectId?: string;\n}\n\nexport function loadConfig(overrides?: Partial<BlitzConfig>): BlitzConfig {\n const apiUrl = overrides?.apiUrl || process.env.BLITZ_API_URL;\n const apiKey = overrides?.apiKey || process.env.BLITZ_API_KEY;\n const workspaceSlug = overrides?.workspaceSlug || process.env.BLITZ_WORKSPACE_SLUG;\n const projectId = overrides?.projectId || process.env.BLITZ_PROJECT_ID;\n\n const missing: string[] = [];\n if (!apiUrl) missing.push(\"BLITZ_API_URL\");\n if (!apiKey) missing.push(\"BLITZ_API_KEY\");\n if (!workspaceSlug) missing.push(\"BLITZ_WORKSPACE_SLUG\");\n\n if (missing.length > 0) {\n throw new Error(\n `Missing required environment variables: ${missing.join(\", \")}\\n\\n` +\n \"Please set the following:\\n\" +\n \" BLITZ_API_URL - Blitz instance URL (e.g. http://localhost:8000)\\n\" +\n \" BLITZ_API_KEY - API key (format: plane_api_<hex>)\\n\" +\n \" BLITZ_WORKSPACE_SLUG - Workspace slug\\n\" +\n \" BLITZ_PROJECT_ID - (Optional) Default project UUID\"\n );\n }\n\n return {\n apiUrl: apiUrl!.replace(/\\/+$/, \"\"),\n apiKey: apiKey!,\n workspaceSlug: workspaceSlug!,\n projectId: projectId || undefined,\n };\n}\n\nexport function resolveProjectId(projectId: string | undefined, config: BlitzConfig): string {\n const id = projectId || config.projectId;\n if (!id) {\n throw new Error(\n \"project_id is required. Either pass it as a parameter or set BLITZ_PROJECT_ID environment variable.\"\n );\n }\n return id;\n}\n","import type { BlitzConfig } from \"./config.js\";\n\nexport class BlitzClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: BlitzConfig) {\n this.baseUrl = `${config.apiUrl}/api/v1`;\n this.apiKey = config.apiKey;\n }\n\n private async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}/${path.replace(/^\\/+/, \"\")}`;\n\n const headers: Record<string, string> = {\n \"X-Api-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n };\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n throw new Error(\n `Rate limit exceeded. ${retryAfter ? `Retry after ${retryAfter} seconds.` : \"Please wait before retrying.\"}`\n );\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const data = await response.json();\n\n if (!response.ok) {\n const message =\n typeof data === \"object\" && data !== null\n ? JSON.stringify(data, null, 2)\n : String(data);\n throw new Error(`API error (${response.status}): ${message}`);\n }\n\n return data as T;\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T = unknown>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async patch<T = unknown>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport function registerProjectTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-projects\",\n \"List all projects in the Blitz workspace. Returns project names, identifiers, and IDs.\",\n {},\n async () => {\n const data = await client.get(`workspaces/${config.workspaceSlug}/projects/`);\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nexport function registerStateTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-states\",\n \"List all workflow states for a project. Use this to find valid state IDs when creating or updating work items.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n },\n async ({ project_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/states/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nexport function registerLabelTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-labels\",\n \"List all labels for a project. Use this to find valid label IDs when creating or updating work items.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n },\n async ({ project_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/labels/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"create-label\",\n \"Create a new label in a project.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n name: z.string().min(1).max(255).describe(\"Label name\"),\n color: z.string().optional().describe(\"Hex color (e.g. #ff0000)\"),\n description: z.string().optional().describe(\"Label description\"),\n },\n async ({ project_id, ...body }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.post(\n `workspaces/${config.workspaceSlug}/projects/${pid}/labels/`,\n body\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport function registerSearchTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"search-work-items\",\n \"Search for work items (tasks/issues) across the workspace by text query. Searches in title and identifier.\",\n {\n query: z.string().min(1).describe(\"Search text\"),\n project_id: z.string().uuid().optional().describe(\"Optional project UUID to scope the search (defaults to BLITZ_PROJECT_ID if set)\"),\n },\n async ({ query, project_id }) => {\n const pid = project_id || config.projectId;\n let path = `workspaces/${config.workspaceSlug}/work-items/search/?search=${encodeURIComponent(query)}`;\n if (pid) {\n path += `&project_id=${pid}`;\n }\n const data = await client.get(path);\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nconst STATE_GROUPS = [\"backlog\", \"unstarted\", \"started\", \"completed\", \"cancelled\"] as const;\n\nconst SUMMARY_FIELDS = [\n \"id\", \"sequence_id\", \"name\", \"state_id\", \"priority\",\n \"assignee_ids\", \"label_ids\", \"start_date\", \"target_date\",\n \"created_at\", \"updated_at\", \"completed_at\",\n] as const;\n\nconst HEAVY_FIELDS = [\n \"description_html\", \"description_binary\", \"description_stripped\",\n \"description\", \"issue_reactions\", \"issue_attachments\", \"issue_link\",\n];\n\nfunction buildListParams(opts: {\n cursor?: string;\n per_page?: number;\n order_by?: string;\n state_group?: string[];\n state_id?: string[];\n}): URLSearchParams {\n const params = new URLSearchParams();\n if (opts.cursor) params.set(\"cursor\", opts.cursor);\n if (opts.per_page) params.set(\"per_page\", String(opts.per_page));\n if (opts.order_by) params.set(\"order_by\", opts.order_by);\n if (opts.state_group?.length) params.set(\"state_group\", opts.state_group.join(\",\"));\n if (opts.state_id?.length) params.set(\"state\", opts.state_id.join(\",\"));\n return params;\n}\n\nfunction stripHeavyFields(item: Record<string, unknown>): Record<string, unknown> {\n const result = { ...item };\n for (const field of HEAVY_FIELDS) {\n delete result[field];\n }\n return result;\n}\n\nfunction pickSummaryFields(item: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const field of SUMMARY_FIELDS) {\n if (field in item) result[field] = item[field];\n }\n return result;\n}\n\nfunction mapBodyForApi(body: Record<string, unknown>): Record<string, unknown> {\n const mapped = { ...body };\n // API serializer expects \"state\" not \"state_id\"\n if (\"state_id\" in mapped) {\n mapped.state = mapped.state_id;\n delete mapped.state_id;\n }\n // API serializer expects \"parent\" not \"parent_id\"\n if (\"parent_id\" in mapped) {\n mapped.parent = mapped.parent_id;\n delete mapped.parent_id;\n }\n return mapped;\n}\n\nexport function registerWorkItemTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n const { workspaceSlug } = config;\n\n server.tool(\n \"list-work-items\",\n \"List work items in a project with filtering, pagination and sorting. Returns all fields except heavy description content.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n cursor: z.string().optional().describe(\"Pagination cursor from previous response\"),\n per_page: z.number().min(1).max(100).optional().describe(\"Items per page (default 20)\"),\n order_by: z.string().optional().describe(\"Sort field (e.g. -created_at, priority, state)\"),\n state_group: z.array(z.enum(STATE_GROUPS)).optional().describe(\"Filter by state group: backlog, unstarted, started, completed, cancelled\"),\n state_id: z.array(z.string().uuid()).optional().describe(\"Filter by specific state UUIDs\"),\n },\n async ({ project_id, cursor, per_page, order_by, state_group, state_id }) => {\n const pid = resolveProjectId(project_id, config);\n const params = buildListParams({ cursor, per_page, order_by, state_group, state_id });\n const query = params.toString();\n const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : \"\"}`;\n const data = await client.get<Record<string, unknown>>(path);\n\n if (data.results && Array.isArray(data.results)) {\n data.results = data.results.map((item: Record<string, unknown>) => stripHeavyFields(item));\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"list-work-items-summary\",\n \"List work items with minimal fields only: name, state, priority, dates. Use this for overviews and large projects.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n cursor: z.string().optional().describe(\"Pagination cursor from previous response\"),\n per_page: z.number().min(1).max(100).optional().describe(\"Items per page (default 20)\"),\n order_by: z.string().optional().describe(\"Sort field (e.g. -created_at, priority, state)\"),\n state_group: z.array(z.enum(STATE_GROUPS)).optional().describe(\"Filter by state group: backlog, unstarted, started, completed, cancelled\"),\n state_id: z.array(z.string().uuid()).optional().describe(\"Filter by specific state UUIDs\"),\n },\n async ({ project_id, cursor, per_page, order_by, state_group, state_id }) => {\n const pid = resolveProjectId(project_id, config);\n const params = buildListParams({ cursor, per_page, order_by, state_group, state_id });\n const query = params.toString();\n const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : \"\"}`;\n const data = await client.get<Record<string, unknown>>(path);\n\n if (data.results && Array.isArray(data.results)) {\n data.results = data.results.map((item: Record<string, unknown>) => pickSummaryFields(item));\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"get-work-item\",\n \"Get a work item by its human-readable identifier (e.g. BLZ-42). Returns full details.\",\n {\n identifier: z.string().min(1).describe(\"Work item identifier (e.g. PROJ-123)\"),\n },\n async ({ identifier }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/work-items/${identifier}/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"get-work-item-by-id\",\n \"Get a work item by its project ID and work item UUID.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"create-work-item\",\n \"Create a new work item (task/issue) in a project. Use list-projects to find project IDs, list-states for state IDs, and list-labels for label IDs.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n name: z.string().min(1).max(255).describe(\"Work item title\"),\n description_html: z.string().optional().describe(\"HTML description content\"),\n priority: z\n .enum([\"urgent\", \"high\", \"medium\", \"low\", \"none\"])\n .optional()\n .describe(\"Priority level\"),\n state_id: z.string().uuid().optional().describe(\"State UUID (use list-states to find valid IDs)\"),\n assignees: z\n .array(z.string().uuid())\n .optional()\n .describe(\"Array of user UUIDs to assign\"),\n labels: z\n .array(z.string().uuid())\n .optional()\n .describe(\"Array of label UUIDs\"),\n start_date: z.string().optional().describe(\"Start date (YYYY-MM-DD)\"),\n target_date: z.string().optional().describe(\"Target date (YYYY-MM-DD)\"),\n parent_id: z.string().uuid().optional().describe(\"Parent work item UUID for sub-issues\"),\n },\n async ({ project_id, ...fields }) => {\n const pid = resolveProjectId(project_id, config);\n const body = mapBodyForApi(fields as Record<string, unknown>);\n const data = await client.post(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/`,\n body\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"update-work-item\",\n \"Update an existing work item. Only provide fields you want to change.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n name: z.string().min(1).max(255).optional().describe(\"New title\"),\n description_html: z.string().optional().describe(\"New HTML description\"),\n priority: z\n .enum([\"urgent\", \"high\", \"medium\", \"low\", \"none\"])\n .optional()\n .describe(\"New priority level\"),\n state_id: z.string().uuid().optional().describe(\"New state UUID (use list-states to find valid IDs)\"),\n assignees: z\n .array(z.string().uuid())\n .optional()\n .describe(\"New assignee UUIDs (replaces existing)\"),\n labels: z\n .array(z.string().uuid())\n .optional()\n .describe(\"New label UUIDs (replaces existing)\"),\n start_date: z.string().nullable().optional().describe(\"Start date (YYYY-MM-DD) or null to clear\"),\n target_date: z.string().nullable().optional().describe(\"Target date (YYYY-MM-DD) or null to clear\"),\n },\n async ({ project_id, work_item_id, ...fields }) => {\n const pid = resolveProjectId(project_id, config);\n const body = mapBodyForApi(fields as Record<string, unknown>);\n const data = await client.patch(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`,\n body\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"delete-work-item\",\n \"Delete a work item. This action cannot be undone.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n await client.delete(\n `workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`\n );\n return {\n content: [{ type: \"text\", text: \"Work item deleted successfully.\" }],\n };\n }\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { resolveProjectId } from \"../config.js\";\n\nexport function registerCommentTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n server.tool(\n \"list-comments\",\n \"List all comments on a work item.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/comments/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"add-comment\",\n \"Add a comment to a work item.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n comment_html: z.string().min(1).describe(\"Comment content in HTML format\"),\n },\n async ({ project_id, work_item_id, comment_html }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.post(\n `workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/comments/`,\n { comment_html }\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n\n server.tool(\n \"list-activities\",\n \"View the activity history (changelog) of a work item. Shows what changed, when, and by whom.\",\n {\n project_id: z.string().uuid().optional().describe(\"Project UUID (optional if BLITZ_PROJECT_ID is set)\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const pid = resolveProjectId(project_id, config);\n const data = await client.get(\n `workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/activities/`\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n }\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { registerProjectTools } from \"./projects.js\";\nimport { registerStateTools } from \"./states.js\";\nimport { registerLabelTools } from \"./labels.js\";\nimport { registerSearchTools } from \"./search.js\";\nimport { registerWorkItemTools } from \"./work-items.js\";\nimport { registerCommentTools } from \"./comments.js\";\n\nexport function registerAllTools(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n registerProjectTools(server, client, config);\n registerStateTools(server, client, config);\n registerLabelTools(server, client, config);\n registerSearchTools(server, client, config);\n registerWorkItemTools(server, client, config);\n registerCommentTools(server, client, config);\n}\n","import { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\n\nexport function registerProjectResources(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n const { workspaceSlug } = config;\n\n server.registerResource(\n \"projects\",\n \"blitz://projects\",\n {\n description: \"List of all projects in the Blitz workspace with their identifiers, names, and IDs.\",\n mimeType: \"application/json\",\n },\n async (uri) => {\n const data = await client.get(`workspaces/${workspaceSlug}/projects/`);\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n \"project-states\",\n new ResourceTemplate(\"blitz://projects/{project_id}/states\", { list: undefined }),\n {\n description: \"Workflow states for a specific project.\",\n mimeType: \"application/json\",\n },\n async (uri, { project_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/states/`\n );\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n \"project-labels\",\n new ResourceTemplate(\"blitz://projects/{project_id}/labels\", { list: undefined }),\n {\n description: \"Labels for a specific project.\",\n mimeType: \"application/json\",\n },\n async (uri, { project_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/labels/`\n );\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\nimport type { BlitzConfig } from \"../config.js\";\nimport { registerProjectResources } from \"./projects.js\";\n\nexport function registerAllResources(server: McpServer, client: BlitzClient, config: BlitzConfig) {\n registerProjectResources(server, client, config);\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { BlitzClient } from \"./client.js\";\nimport { registerAllTools } from \"./tools/index.js\";\nimport { registerAllResources } from \"./resources/index.js\";\nimport type { BlitzConfig } from \"./config.js\";\n\nexport function createServer(config: BlitzConfig) {\n const client = new BlitzClient(config);\n\n const server = new McpServer({\n name: \"blitz-mcp\",\n version: \"0.3.0\",\n });\n\n registerAllTools(server, client, config);\n registerAllResources(server, client, config);\n\n return server;\n}\n"],"mappings":"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"}
|