@sixtynine-digital/blitz-mcp 0.2.0 → 0.3.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.
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { n as loadConfig, t as createServer$1 } from "./server-vVsHZuAO.mjs";
2
+ import { n as loadConfig, t as createServer$1 } from "./server-Y1bv_8dx.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";
6
6
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
7
7
 
8
8
  //#region src/http.ts
9
- const transports = /* @__PURE__ */ new Map();
9
+ const sessions = /* @__PURE__ */ new Map();
10
10
  function parseBody(req) {
11
11
  return new Promise((resolve, reject) => {
12
12
  let data = "";
@@ -25,9 +25,21 @@ function jsonResponse(res, status, body) {
25
25
  res.writeHead(status, { "Content-Type": "application/json" });
26
26
  res.end(JSON.stringify(body));
27
27
  }
28
+ function parseQueryParams(url) {
29
+ const idx = url.indexOf("?");
30
+ if (idx === -1) return {};
31
+ const params = {};
32
+ const search = url.slice(idx + 1);
33
+ for (const pair of search.split("&")) {
34
+ const [key, val] = pair.split("=");
35
+ if (key) params[decodeURIComponent(key)] = decodeURIComponent(val || "");
36
+ }
37
+ return params;
38
+ }
28
39
  function startHttpServer() {
29
- const config = loadConfig();
30
40
  const port = parseInt(process.env.BLITZ_MCP_PORT || "3100", 10);
41
+ const apiUrl = process.env.BLITZ_API_URL;
42
+ if (!apiUrl) throw new Error("BLITZ_API_URL environment variable is required");
31
43
  const httpServer = createServer(async (req, res) => {
32
44
  res.setHeader("Access-Control-Allow-Origin", "*");
33
45
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
@@ -38,30 +50,51 @@ function startHttpServer() {
38
50
  res.end();
39
51
  return;
40
52
  }
41
- if (req.url !== "/mcp") {
53
+ if ((req.url || "").split("?")[0] !== "/mcp") {
42
54
  jsonResponse(res, 404, { error: "Not found" });
43
55
  return;
44
56
  }
45
57
  if (req.method === "POST") {
46
58
  const sessionId = req.headers["mcp-session-id"];
47
- if (sessionId && transports.has(sessionId)) {
48
- const transport = transports.get(sessionId);
59
+ if (sessionId && sessions.has(sessionId)) {
60
+ const entry = sessions.get(sessionId);
49
61
  const body$1 = await parseBody(req);
50
- await transport.handleRequest(req, res, body$1);
62
+ await entry.transport.handleRequest(req, res, body$1);
51
63
  return;
52
64
  }
53
65
  const body = await parseBody(req);
54
66
  if (!sessionId && isInitializeRequest(body)) {
67
+ const query = parseQueryParams(req.url || "");
68
+ const apiKey = query.api_key || process.env.BLITZ_API_KEY;
69
+ const workspaceSlug = query.workspace || process.env.BLITZ_WORKSPACE_SLUG;
70
+ if (!apiKey) {
71
+ jsonResponse(res, 401, { error: "API key required. Add ?api_key=plane_api_XXX to the URL" });
72
+ return;
73
+ }
74
+ if (!workspaceSlug) {
75
+ jsonResponse(res, 400, { error: "Workspace slug required. Add ?workspace=YOUR_SLUG to the URL" });
76
+ return;
77
+ }
78
+ const config = loadConfig({
79
+ apiUrl,
80
+ apiKey,
81
+ workspaceSlug,
82
+ projectId: query.project_id || process.env.BLITZ_PROJECT_ID || void 0
83
+ });
55
84
  const transport = new StreamableHTTPServerTransport({
56
85
  sessionIdGenerator: () => randomUUID(),
57
86
  onsessioninitialized: (id) => {
58
- transports.set(id, transport);
87
+ sessions.set(id, {
88
+ transport,
89
+ server
90
+ });
59
91
  }
60
92
  });
61
93
  transport.onclose = () => {
62
- if (transport.sessionId) transports.delete(transport.sessionId);
94
+ if (transport.sessionId) sessions.delete(transport.sessionId);
63
95
  };
64
- await createServer$1(config).connect(transport);
96
+ const server = createServer$1(config);
97
+ await server.connect(transport);
65
98
  await transport.handleRequest(req, res, body);
66
99
  return;
67
100
  }
@@ -77,13 +110,13 @@ function startHttpServer() {
77
110
  }
78
111
  if (req.method === "GET") {
79
112
  const sessionId = req.headers["mcp-session-id"];
80
- if (sessionId && transports.has(sessionId)) await transports.get(sessionId).handleRequest(req, res);
113
+ if (sessionId && sessions.has(sessionId)) await sessions.get(sessionId).transport.handleRequest(req, res);
81
114
  else jsonResponse(res, 400, { error: "Invalid session" });
82
115
  return;
83
116
  }
84
117
  if (req.method === "DELETE") {
85
118
  const sessionId = req.headers["mcp-session-id"];
86
- if (sessionId && transports.has(sessionId)) await transports.get(sessionId).handleRequest(req, res);
119
+ if (sessionId && sessions.has(sessionId)) await sessions.get(sessionId).transport.handleRequest(req, res);
87
120
  else jsonResponse(res, 400, { error: "Invalid session" });
88
121
  return;
89
122
  }
@@ -105,4 +138,4 @@ function startHttpServer() {
105
138
 
106
139
  //#endregion
107
140
  export { startHttpServer };
108
- //# sourceMappingURL=http-Dw-3pEjA.mjs.map
141
+ //# sourceMappingURL=http-kEKXBhoW.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-kEKXBhoW.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-vVsHZuAO.mjs";
2
+ import { n as loadConfig, t as createServer } from "./server-Y1bv_8dx.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-Dw-3pEjA.mjs");
6
+ const { startHttpServer } = await import("./http-kEKXBhoW.mjs");
7
7
  startHttpServer();
8
8
  } else {
9
9
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
@@ -3,24 +3,32 @@ import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mc
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/config.ts
6
- function loadConfig() {
7
- const apiUrl = process.env.BLITZ_API_URL;
8
- const apiKey = process.env.BLITZ_API_KEY;
9
- const workspaceSlug = process.env.BLITZ_WORKSPACE_SLUG;
6
+ function loadConfig(overrides) {
7
+ const apiUrl = overrides?.apiUrl || process.env.BLITZ_API_URL;
8
+ const apiKey = overrides?.apiKey || process.env.BLITZ_API_KEY;
9
+ const workspaceSlug = overrides?.workspaceSlug || process.env.BLITZ_WORKSPACE_SLUG;
10
+ const projectId = overrides?.projectId || process.env.BLITZ_PROJECT_ID;
10
11
  const missing = [];
11
12
  if (!apiUrl) missing.push("BLITZ_API_URL");
12
13
  if (!apiKey) missing.push("BLITZ_API_KEY");
13
14
  if (!workspaceSlug) missing.push("BLITZ_WORKSPACE_SLUG");
14
15
  if (missing.length > 0) throw new Error(`Missing required environment variables: ${missing.join(", ")}\n\nPlease set the following:
15
- BLITZ_API_URL - Blitz instance URL (e.g. http://localhost:8000)
16
- BLITZ_API_KEY - API key (format: plane_api_<hex>)
17
- BLITZ_WORKSPACE_SLUG - Workspace slug`);
16
+ BLITZ_API_URL - Blitz instance URL (e.g. http://localhost:8000)
17
+ BLITZ_API_KEY - API key (format: plane_api_<hex>)
18
+ BLITZ_WORKSPACE_SLUG - Workspace slug
19
+ BLITZ_PROJECT_ID - (Optional) Default project UUID`);
18
20
  return {
19
21
  apiUrl: apiUrl.replace(/\/+$/, ""),
20
22
  apiKey,
21
- workspaceSlug
23
+ workspaceSlug,
24
+ projectId: projectId || void 0
22
25
  };
23
26
  }
27
+ function resolveProjectId(projectId, config) {
28
+ const id = projectId || config.projectId;
29
+ if (!id) throw new Error("project_id is required. Either pass it as a parameter or set BLITZ_PROJECT_ID environment variable.");
30
+ return id;
31
+ }
24
32
 
25
33
  //#endregion
26
34
  //#region src/client.ts
@@ -70,9 +78,9 @@ var BlitzClient = class {
70
78
 
71
79
  //#endregion
72
80
  //#region src/tools/projects.ts
73
- function registerProjectTools(server, client, workspaceSlug) {
81
+ function registerProjectTools(server, client, config) {
74
82
  server.tool("list-projects", "List all projects in the Blitz workspace. Returns project names, identifiers, and IDs.", {}, async () => {
75
- const data = await client.get(`workspaces/${workspaceSlug}/projects/`);
83
+ const data = await client.get(`workspaces/${config.workspaceSlug}/projects/`);
76
84
  return { content: [{
77
85
  type: "text",
78
86
  text: JSON.stringify(data, null, 2)
@@ -82,9 +90,10 @@ function registerProjectTools(server, client, workspaceSlug) {
82
90
 
83
91
  //#endregion
84
92
  //#region src/tools/states.ts
85
- function registerStateTools(server, client, workspaceSlug) {
86
- server.tool("list-states", "List all workflow states for a project. Use this to find valid state IDs when creating or updating work items.", { project_id: z.string().uuid().describe("Project UUID") }, async ({ project_id }) => {
87
- const data = await client.get(`workspaces/${workspaceSlug}/projects/${project_id}/states/`);
93
+ function registerStateTools(server, client, config) {
94
+ server.tool("list-states", "List all workflow states for a project. Use this to find valid state IDs when creating or updating work items.", { project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)") }, async ({ project_id }) => {
95
+ const pid = resolveProjectId(project_id, config);
96
+ const data = await client.get(`workspaces/${config.workspaceSlug}/projects/${pid}/states/`);
88
97
  return { content: [{
89
98
  type: "text",
90
99
  text: JSON.stringify(data, null, 2)
@@ -94,21 +103,23 @@ function registerStateTools(server, client, workspaceSlug) {
94
103
 
95
104
  //#endregion
96
105
  //#region src/tools/labels.ts
97
- function registerLabelTools(server, client, workspaceSlug) {
98
- server.tool("list-labels", "List all labels for a project. Use this to find valid label IDs when creating or updating work items.", { project_id: z.string().uuid().describe("Project UUID") }, async ({ project_id }) => {
99
- const data = await client.get(`workspaces/${workspaceSlug}/projects/${project_id}/labels/`);
106
+ function registerLabelTools(server, client, config) {
107
+ server.tool("list-labels", "List all labels for a project. Use this to find valid label IDs when creating or updating work items.", { project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)") }, async ({ project_id }) => {
108
+ const pid = resolveProjectId(project_id, config);
109
+ const data = await client.get(`workspaces/${config.workspaceSlug}/projects/${pid}/labels/`);
100
110
  return { content: [{
101
111
  type: "text",
102
112
  text: JSON.stringify(data, null, 2)
103
113
  }] };
104
114
  });
105
115
  server.tool("create-label", "Create a new label in a project.", {
106
- project_id: z.string().uuid().describe("Project UUID"),
116
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
107
117
  name: z.string().min(1).max(255).describe("Label name"),
108
118
  color: z.string().optional().describe("Hex color (e.g. #ff0000)"),
109
119
  description: z.string().optional().describe("Label description")
110
120
  }, async ({ project_id,...body }) => {
111
- const data = await client.post(`workspaces/${workspaceSlug}/projects/${project_id}/labels/`, body);
121
+ const pid = resolveProjectId(project_id, config);
122
+ const data = await client.post(`workspaces/${config.workspaceSlug}/projects/${pid}/labels/`, body);
112
123
  return { content: [{
113
124
  type: "text",
114
125
  text: JSON.stringify(data, null, 2)
@@ -118,13 +129,14 @@ function registerLabelTools(server, client, workspaceSlug) {
118
129
 
119
130
  //#endregion
120
131
  //#region src/tools/search.ts
121
- function registerSearchTools(server, client, workspaceSlug) {
132
+ function registerSearchTools(server, client, config) {
122
133
  server.tool("search-work-items", "Search for work items (tasks/issues) across the workspace by text query. Searches in title and identifier.", {
123
134
  query: z.string().min(1).describe("Search text"),
124
- project_id: z.string().uuid().optional().describe("Optional project UUID to scope the search")
135
+ project_id: z.string().uuid().optional().describe("Optional project UUID to scope the search (defaults to BLITZ_PROJECT_ID if set)")
125
136
  }, async ({ query, project_id }) => {
126
- let path = `workspaces/${workspaceSlug}/work-items/search/?search=${encodeURIComponent(query)}`;
127
- if (project_id) path += `&project_id=${project_id}`;
137
+ const pid = project_id || config.projectId;
138
+ let path = `workspaces/${config.workspaceSlug}/work-items/search/?search=${encodeURIComponent(query)}`;
139
+ if (pid) path += `&project_id=${pid}`;
128
140
  const data = await client.get(path);
129
141
  return { content: [{
130
142
  type: "text",
@@ -135,20 +147,112 @@ function registerSearchTools(server, client, workspaceSlug) {
135
147
 
136
148
  //#endregion
137
149
  //#region src/tools/work-items.ts
138
- function registerWorkItemTools(server, client, workspaceSlug) {
139
- server.tool("list-work-items", "List work items (tasks/issues) in a project with pagination and sorting.", {
140
- project_id: z.string().uuid().describe("Project UUID"),
150
+ const STATE_GROUPS = [
151
+ "backlog",
152
+ "unstarted",
153
+ "started",
154
+ "completed",
155
+ "cancelled"
156
+ ];
157
+ const SUMMARY_FIELDS = [
158
+ "id",
159
+ "sequence_id",
160
+ "name",
161
+ "state_id",
162
+ "priority",
163
+ "assignee_ids",
164
+ "label_ids",
165
+ "start_date",
166
+ "target_date",
167
+ "created_at",
168
+ "updated_at",
169
+ "completed_at"
170
+ ];
171
+ const HEAVY_FIELDS = [
172
+ "description_html",
173
+ "description_binary",
174
+ "description_stripped",
175
+ "description",
176
+ "issue_reactions",
177
+ "issue_attachments",
178
+ "issue_link"
179
+ ];
180
+ function buildListParams(opts) {
181
+ const params = new URLSearchParams();
182
+ if (opts.cursor) params.set("cursor", opts.cursor);
183
+ if (opts.per_page) params.set("per_page", String(opts.per_page));
184
+ if (opts.order_by) params.set("order_by", opts.order_by);
185
+ if (opts.state_group?.length) params.set("state_group", opts.state_group.join(","));
186
+ if (opts.state_id?.length) params.set("state", opts.state_id.join(","));
187
+ return params;
188
+ }
189
+ function stripHeavyFields(item) {
190
+ const result = { ...item };
191
+ for (const field of HEAVY_FIELDS) delete result[field];
192
+ return result;
193
+ }
194
+ function pickSummaryFields(item) {
195
+ const result = {};
196
+ for (const field of SUMMARY_FIELDS) if (field in item) result[field] = item[field];
197
+ return result;
198
+ }
199
+ function mapBodyForApi(body) {
200
+ const mapped = { ...body };
201
+ if ("state_id" in mapped) {
202
+ mapped.state = mapped.state_id;
203
+ delete mapped.state_id;
204
+ }
205
+ if ("parent_id" in mapped) {
206
+ mapped.parent = mapped.parent_id;
207
+ delete mapped.parent_id;
208
+ }
209
+ return mapped;
210
+ }
211
+ function registerWorkItemTools(server, client, config) {
212
+ const { workspaceSlug } = config;
213
+ server.tool("list-work-items", "List work items in a project with filtering, pagination and sorting. Returns all fields except heavy description content.", {
214
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
141
215
  cursor: z.string().optional().describe("Pagination cursor from previous response"),
142
216
  per_page: z.number().min(1).max(100).optional().describe("Items per page (default 20)"),
143
- order_by: z.string().optional().describe("Sort field (e.g. -created_at, priority, state)")
144
- }, async ({ project_id, cursor, per_page, order_by }) => {
145
- const params = new URLSearchParams();
146
- if (cursor) params.set("cursor", cursor);
147
- if (per_page) params.set("per_page", String(per_page));
148
- if (order_by) params.set("order_by", order_by);
149
- const query = params.toString();
150
- const path = `workspaces/${workspaceSlug}/projects/${project_id}/work-items/${query ? `?${query}` : ""}`;
217
+ order_by: z.string().optional().describe("Sort field (e.g. -created_at, priority, state)"),
218
+ state_group: z.array(z.enum(STATE_GROUPS)).optional().describe("Filter by state group: backlog, unstarted, started, completed, cancelled"),
219
+ state_id: z.array(z.string().uuid()).optional().describe("Filter by specific state UUIDs")
220
+ }, async ({ project_id, cursor, per_page, order_by, state_group, state_id }) => {
221
+ const pid = resolveProjectId(project_id, config);
222
+ const query = buildListParams({
223
+ cursor,
224
+ per_page,
225
+ order_by,
226
+ state_group,
227
+ state_id
228
+ }).toString();
229
+ const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : ""}`;
151
230
  const data = await client.get(path);
231
+ if (data.results && Array.isArray(data.results)) data.results = data.results.map((item) => stripHeavyFields(item));
232
+ return { content: [{
233
+ type: "text",
234
+ text: JSON.stringify(data, null, 2)
235
+ }] };
236
+ });
237
+ server.tool("list-work-items-summary", "List work items with minimal fields only: name, state, priority, dates. Use this for overviews and large projects.", {
238
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
239
+ cursor: z.string().optional().describe("Pagination cursor from previous response"),
240
+ per_page: z.number().min(1).max(100).optional().describe("Items per page (default 20)"),
241
+ order_by: z.string().optional().describe("Sort field (e.g. -created_at, priority, state)"),
242
+ state_group: z.array(z.enum(STATE_GROUPS)).optional().describe("Filter by state group: backlog, unstarted, started, completed, cancelled"),
243
+ state_id: z.array(z.string().uuid()).optional().describe("Filter by specific state UUIDs")
244
+ }, async ({ project_id, cursor, per_page, order_by, state_group, state_id }) => {
245
+ const pid = resolveProjectId(project_id, config);
246
+ const query = buildListParams({
247
+ cursor,
248
+ per_page,
249
+ order_by,
250
+ state_group,
251
+ state_id
252
+ }).toString();
253
+ const path = `workspaces/${workspaceSlug}/projects/${pid}/work-items/${query ? `?${query}` : ""}`;
254
+ const data = await client.get(path);
255
+ if (data.results && Array.isArray(data.results)) data.results = data.results.map((item) => pickSummaryFields(item));
152
256
  return { content: [{
153
257
  type: "text",
154
258
  text: JSON.stringify(data, null, 2)
@@ -162,17 +266,18 @@ function registerWorkItemTools(server, client, workspaceSlug) {
162
266
  }] };
163
267
  });
164
268
  server.tool("get-work-item-by-id", "Get a work item by its project ID and work item UUID.", {
165
- project_id: z.string().uuid().describe("Project UUID"),
269
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
166
270
  work_item_id: z.string().uuid().describe("Work item UUID")
167
271
  }, async ({ project_id, work_item_id }) => {
168
- const data = await client.get(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/${work_item_id}/`);
272
+ const pid = resolveProjectId(project_id, config);
273
+ const data = await client.get(`workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`);
169
274
  return { content: [{
170
275
  type: "text",
171
276
  text: JSON.stringify(data, null, 2)
172
277
  }] };
173
278
  });
174
279
  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.", {
175
- project_id: z.string().uuid().describe("Project UUID"),
280
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
176
281
  name: z.string().min(1).max(255).describe("Work item title"),
177
282
  description_html: z.string().optional().describe("HTML description content"),
178
283
  priority: z.enum([
@@ -188,15 +293,17 @@ function registerWorkItemTools(server, client, workspaceSlug) {
188
293
  start_date: z.string().optional().describe("Start date (YYYY-MM-DD)"),
189
294
  target_date: z.string().optional().describe("Target date (YYYY-MM-DD)"),
190
295
  parent_id: z.string().uuid().optional().describe("Parent work item UUID for sub-issues")
191
- }, async ({ project_id,...body }) => {
192
- const data = await client.post(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/`, body);
296
+ }, async ({ project_id,...fields }) => {
297
+ const pid = resolveProjectId(project_id, config);
298
+ const body = mapBodyForApi(fields);
299
+ const data = await client.post(`workspaces/${workspaceSlug}/projects/${pid}/work-items/`, body);
193
300
  return { content: [{
194
301
  type: "text",
195
302
  text: JSON.stringify(data, null, 2)
196
303
  }] };
197
304
  });
198
305
  server.tool("update-work-item", "Update an existing work item. Only provide fields you want to change.", {
199
- project_id: z.string().uuid().describe("Project UUID"),
306
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
200
307
  work_item_id: z.string().uuid().describe("Work item UUID"),
201
308
  name: z.string().min(1).max(255).optional().describe("New title"),
202
309
  description_html: z.string().optional().describe("New HTML description"),
@@ -207,23 +314,26 @@ function registerWorkItemTools(server, client, workspaceSlug) {
207
314
  "low",
208
315
  "none"
209
316
  ]).optional().describe("New priority level"),
210
- state_id: z.string().uuid().optional().describe("New state UUID"),
317
+ state_id: z.string().uuid().optional().describe("New state UUID (use list-states to find valid IDs)"),
211
318
  assignees: z.array(z.string().uuid()).optional().describe("New assignee UUIDs (replaces existing)"),
212
319
  labels: z.array(z.string().uuid()).optional().describe("New label UUIDs (replaces existing)"),
213
320
  start_date: z.string().nullable().optional().describe("Start date (YYYY-MM-DD) or null to clear"),
214
321
  target_date: z.string().nullable().optional().describe("Target date (YYYY-MM-DD) or null to clear")
215
- }, async ({ project_id, work_item_id,...body }) => {
216
- const data = await client.patch(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/${work_item_id}/`, body);
322
+ }, async ({ project_id, work_item_id,...fields }) => {
323
+ const pid = resolveProjectId(project_id, config);
324
+ const body = mapBodyForApi(fields);
325
+ const data = await client.patch(`workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`, body);
217
326
  return { content: [{
218
327
  type: "text",
219
328
  text: JSON.stringify(data, null, 2)
220
329
  }] };
221
330
  });
222
331
  server.tool("delete-work-item", "Delete a work item. This action cannot be undone.", {
223
- project_id: z.string().uuid().describe("Project UUID"),
332
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
224
333
  work_item_id: z.string().uuid().describe("Work item UUID")
225
334
  }, async ({ project_id, work_item_id }) => {
226
- await client.delete(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/${work_item_id}/`);
335
+ const pid = resolveProjectId(project_id, config);
336
+ await client.delete(`workspaces/${workspaceSlug}/projects/${pid}/work-items/${work_item_id}/`);
227
337
  return { content: [{
228
338
  type: "text",
229
339
  text: "Work item deleted successfully."
@@ -233,33 +343,36 @@ function registerWorkItemTools(server, client, workspaceSlug) {
233
343
 
234
344
  //#endregion
235
345
  //#region src/tools/comments.ts
236
- function registerCommentTools(server, client, workspaceSlug) {
346
+ function registerCommentTools(server, client, config) {
237
347
  server.tool("list-comments", "List all comments on a work item.", {
238
- project_id: z.string().uuid().describe("Project UUID"),
348
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
239
349
  work_item_id: z.string().uuid().describe("Work item UUID")
240
350
  }, async ({ project_id, work_item_id }) => {
241
- const data = await client.get(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/${work_item_id}/comments/`);
351
+ const pid = resolveProjectId(project_id, config);
352
+ const data = await client.get(`workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/comments/`);
242
353
  return { content: [{
243
354
  type: "text",
244
355
  text: JSON.stringify(data, null, 2)
245
356
  }] };
246
357
  });
247
358
  server.tool("add-comment", "Add a comment to a work item.", {
248
- project_id: z.string().uuid().describe("Project UUID"),
359
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
249
360
  work_item_id: z.string().uuid().describe("Work item UUID"),
250
361
  comment_html: z.string().min(1).describe("Comment content in HTML format")
251
362
  }, async ({ project_id, work_item_id, comment_html }) => {
252
- const data = await client.post(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/${work_item_id}/comments/`, { comment_html });
363
+ const pid = resolveProjectId(project_id, config);
364
+ const data = await client.post(`workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/comments/`, { comment_html });
253
365
  return { content: [{
254
366
  type: "text",
255
367
  text: JSON.stringify(data, null, 2)
256
368
  }] };
257
369
  });
258
370
  server.tool("list-activities", "View the activity history (changelog) of a work item. Shows what changed, when, and by whom.", {
259
- project_id: z.string().uuid().describe("Project UUID"),
371
+ project_id: z.string().uuid().optional().describe("Project UUID (optional if BLITZ_PROJECT_ID is set)"),
260
372
  work_item_id: z.string().uuid().describe("Work item UUID")
261
373
  }, async ({ project_id, work_item_id }) => {
262
- const data = await client.get(`workspaces/${workspaceSlug}/projects/${project_id}/work-items/${work_item_id}/activities/`);
374
+ const pid = resolveProjectId(project_id, config);
375
+ const data = await client.get(`workspaces/${config.workspaceSlug}/projects/${pid}/work-items/${work_item_id}/activities/`);
263
376
  return { content: [{
264
377
  type: "text",
265
378
  text: JSON.stringify(data, null, 2)
@@ -269,18 +382,19 @@ function registerCommentTools(server, client, workspaceSlug) {
269
382
 
270
383
  //#endregion
271
384
  //#region src/tools/index.ts
272
- function registerAllTools(server, client, workspaceSlug) {
273
- registerProjectTools(server, client, workspaceSlug);
274
- registerStateTools(server, client, workspaceSlug);
275
- registerLabelTools(server, client, workspaceSlug);
276
- registerSearchTools(server, client, workspaceSlug);
277
- registerWorkItemTools(server, client, workspaceSlug);
278
- registerCommentTools(server, client, workspaceSlug);
385
+ function registerAllTools(server, client, config) {
386
+ registerProjectTools(server, client, config);
387
+ registerStateTools(server, client, config);
388
+ registerLabelTools(server, client, config);
389
+ registerSearchTools(server, client, config);
390
+ registerWorkItemTools(server, client, config);
391
+ registerCommentTools(server, client, config);
279
392
  }
280
393
 
281
394
  //#endregion
282
395
  //#region src/resources/projects.ts
283
- function registerProjectResources(server, client, workspaceSlug) {
396
+ function registerProjectResources(server, client, config) {
397
+ const { workspaceSlug } = config;
284
398
  server.registerResource("projects", "blitz://projects", {
285
399
  description: "List of all projects in the Blitz workspace with their identifiers, names, and IDs.",
286
400
  mimeType: "application/json"
@@ -318,8 +432,8 @@ function registerProjectResources(server, client, workspaceSlug) {
318
432
 
319
433
  //#endregion
320
434
  //#region src/resources/index.ts
321
- function registerAllResources(server, client, workspaceSlug) {
322
- registerProjectResources(server, client, workspaceSlug);
435
+ function registerAllResources(server, client, config) {
436
+ registerProjectResources(server, client, config);
323
437
  }
324
438
 
325
439
  //#endregion
@@ -328,13 +442,13 @@ function createServer(config) {
328
442
  const client = new BlitzClient(config);
329
443
  const server = new McpServer({
330
444
  name: "blitz-mcp",
331
- version: "0.1.1"
445
+ version: "0.3.0"
332
446
  });
333
- registerAllTools(server, client, config.workspaceSlug);
334
- registerAllResources(server, client, config.workspaceSlug);
447
+ registerAllTools(server, client, config);
448
+ registerAllResources(server, client, config);
335
449
  return server;
336
450
  }
337
451
 
338
452
  //#endregion
339
453
  export { loadConfig as n, createServer as t };
340
- //# sourceMappingURL=server-vVsHZuAO.mjs.map
454
+ //# sourceMappingURL=server-Y1bv_8dx.mjs.map
@@ -0,0 +1 @@
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sixtynine-digital/blitz-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "license": "AGPL-3.0",
5
5
  "description": "MCP server for Blitz project management",
6
6
  "private": false,
@@ -1 +0,0 @@
1
- {"version":3,"file":"http-Dw-3pEjA.mjs","names":["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\nconst transports = new Map<string, StreamableHTTPServerTransport>();\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\nexport function startHttpServer() {\n const config = loadConfig();\n const port = parseInt(process.env.BLITZ_MCP_PORT || \"3100\", 10);\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 if (req.url !== \"/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 && transports.has(sessionId)) {\n const transport = transports.get(sessionId)!;\n const body = await parseBody(req);\n await 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 const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n transports.set(id, transport);\n },\n });\n\n transport.onclose = () => {\n if (transport.sessionId) {\n transports.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 && transports.has(sessionId)) {\n const transport = transports.get(sessionId)!;\n await 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 && transports.has(sessionId)) {\n const transport = transports.get(sessionId)!;\n await 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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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server-vVsHZuAO.mjs","names":["missing: string[]","headers: Record<string, string>"],"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}\n\nexport function loadConfig(): BlitzConfig {\n const apiUrl = process.env.BLITZ_API_URL;\n const apiKey = process.env.BLITZ_API_KEY;\n const workspaceSlug = process.env.BLITZ_WORKSPACE_SLUG;\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 }\n\n return {\n apiUrl: apiUrl.replace(/\\/+$/, \"\"),\n apiKey,\n workspaceSlug,\n };\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\";\n\nexport function registerProjectTools(server: McpServer, client: BlitzClient, workspaceSlug: string) {\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/${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\";\n\nexport function registerStateTools(server: McpServer, client: BlitzClient, workspaceSlug: string) {\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().describe(\"Project UUID\"),\n },\n async ({ project_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/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\";\n\nexport function registerLabelTools(server: McpServer, client: BlitzClient, workspaceSlug: string) {\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().describe(\"Project UUID\"),\n },\n async ({ project_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/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().describe(\"Project UUID\"),\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 data = await client.post(\n `workspaces/${workspaceSlug}/projects/${project_id}/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\";\n\nexport function registerSearchTools(server: McpServer, client: BlitzClient, workspaceSlug: string) {\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\"),\n },\n async ({ query, project_id }) => {\n let path = `workspaces/${workspaceSlug}/work-items/search/?search=${encodeURIComponent(query)}`;\n if (project_id) {\n path += `&project_id=${project_id}`;\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\";\n\nexport function registerWorkItemTools(server: McpServer, client: BlitzClient, workspaceSlug: string) {\n server.tool(\n \"list-work-items\",\n \"List work items (tasks/issues) in a project with pagination and sorting.\",\n {\n project_id: z.string().uuid().describe(\"Project UUID\"),\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 },\n async ({ project_id, cursor, per_page, order_by }) => {\n const params = new URLSearchParams();\n if (cursor) params.set(\"cursor\", cursor);\n if (per_page) params.set(\"per_page\", String(per_page));\n if (order_by) params.set(\"order_by\", order_by);\n\n const query = params.toString();\n const path = `workspaces/${workspaceSlug}/projects/${project_id}/work-items/${query ? `?${query}` : \"\"}`;\n const data = await client.get(path);\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().describe(\"Project UUID\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/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().describe(\"Project UUID\"),\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, ...body }) => {\n const data = await client.post(\n `workspaces/${workspaceSlug}/projects/${project_id}/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().describe(\"Project UUID\"),\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\"),\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, ...body }) => {\n const data = await client.patch(\n `workspaces/${workspaceSlug}/projects/${project_id}/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().describe(\"Project UUID\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n await client.delete(\n `workspaces/${workspaceSlug}/projects/${project_id}/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\";\n\nexport function registerCommentTools(server: McpServer, client: BlitzClient, workspaceSlug: string) {\n server.tool(\n \"list-comments\",\n \"List all comments on a work item.\",\n {\n project_id: z.string().uuid().describe(\"Project UUID\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/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().describe(\"Project UUID\"),\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 data = await client.post(\n `workspaces/${workspaceSlug}/projects/${project_id}/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().describe(\"Project UUID\"),\n work_item_id: z.string().uuid().describe(\"Work item UUID\"),\n },\n async ({ project_id, work_item_id }) => {\n const data = await client.get(\n `workspaces/${workspaceSlug}/projects/${project_id}/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 { 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, workspaceSlug: string) {\n registerProjectTools(server, client, workspaceSlug);\n registerStateTools(server, client, workspaceSlug);\n registerLabelTools(server, client, workspaceSlug);\n registerSearchTools(server, client, workspaceSlug);\n registerWorkItemTools(server, client, workspaceSlug);\n registerCommentTools(server, client, workspaceSlug);\n}\n","import { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { BlitzClient } from \"../client.js\";\n\nexport function registerProjectResources(server: McpServer, client: BlitzClient, workspaceSlug: string) {\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 { registerProjectResources } from \"./projects.js\";\n\nexport function registerAllResources(server: McpServer, client: BlitzClient, workspaceSlug: string) {\n registerProjectResources(server, client, workspaceSlug);\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.1.1\",\n });\n\n registerAllTools(server, client, config.workspaceSlug);\n registerAllResources(server, client, config.workspaceSlug);\n\n return server;\n}\n"],"mappings":"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"}