@myspec/mcp-server 0.1.2-next.35 → 0.1.2-next.37

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.
Files changed (2) hide show
  1. package/dist/index.js +65 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1139,6 +1139,7 @@ function transformSpecFileResponse(raw) {
1139
1139
  revisionCount: raw.revision_count,
1140
1140
  createdAt: new Date(raw.created_at),
1141
1141
  updatedAt: new Date(raw.updated_at),
1142
+ trashedAt: raw.trashed_at ? new Date(raw.trashed_at) : void 0,
1142
1143
  deletedAt: raw.deleted_at ? new Date(raw.deleted_at) : void 0
1143
1144
  };
1144
1145
  }
@@ -1475,18 +1476,49 @@ var HttpFileClient = class {
1475
1476
  if (opts?.offset !== void 0) queryParams.set("offset", String(opts.offset));
1476
1477
  if (opts?.hideArchivedIncomplete)
1477
1478
  queryParams.set("hide_archived_incomplete", "true");
1479
+ if (opts?.includeTrashed) queryParams.set("include_trashed", "true");
1478
1480
  const query = queryParams.toString();
1479
1481
  const path4 = `/project/v1/files?${query}`;
1480
1482
  const raw = await this.httpClient.get(path4, jwtToken, {});
1481
1483
  return transformFileListResult(raw);
1482
1484
  }
1483
- async deleteFile(fileId, jwtToken) {
1485
+ async trashFile(fileId, jwtToken) {
1484
1486
  await this.httpClient.delete(
1485
1487
  `/project/v1/files/${fileId}`,
1486
1488
  jwtToken,
1487
1489
  {}
1488
1490
  );
1489
1491
  }
1492
+ async restoreFile(fileId, jwtToken) {
1493
+ await this.httpClient.post(
1494
+ `/project/v1/files/${fileId}/restore`,
1495
+ {},
1496
+ jwtToken,
1497
+ {}
1498
+ );
1499
+ }
1500
+ async deleteFilePermanently(fileId, jwtToken) {
1501
+ await this.httpClient.delete(
1502
+ `/project/v1/files/${fileId}/permanent`,
1503
+ jwtToken,
1504
+ {}
1505
+ );
1506
+ }
1507
+ async listTrashedFiles(projectId, jwtToken) {
1508
+ const raw = await this.httpClient.get(
1509
+ `/project/v1/projects/${projectId}/files/trashed`,
1510
+ jwtToken,
1511
+ {}
1512
+ );
1513
+ return (raw.files ?? []).map(transformSpecFileResponse);
1514
+ }
1515
+ /**
1516
+ * @deprecated Alias of {@link trashFile}. Moves the file to the Trash Bin
1517
+ * (recoverable); for a permanent delete use {@link deleteFilePermanently}.
1518
+ */
1519
+ async deleteFile(fileId, jwtToken) {
1520
+ await this.trashFile(fileId, jwtToken);
1521
+ }
1490
1522
  async deleteRevision(fileId, revisionNumber, jwtToken) {
1491
1523
  const response = await this.httpClient.delete(
1492
1524
  `/project/v1/files/${fileId}/revisions/${revisionNumber}`,
@@ -2036,17 +2068,28 @@ var inputSchema3 = {
2036
2068
  };
2037
2069
  var deleteProjectTool = {
2038
2070
  name: "delete_project",
2039
- description: "Soft-delete a project. The project must be archived first; deleting a non-archived project is rejected.",
2071
+ description: "Soft-delete a project. Only a project that is already archived can be deleted. If the project is still active, this tool refuses and you must NOT archive it on the user's behalf to make the deletion go through \u2014 instead, reconfirm with the user whether deleting the project is truly intended.",
2040
2072
  inputSchema: inputSchema3,
2041
2073
  handler: async (args, ctx) => {
2074
+ let status;
2042
2075
  try {
2043
- await ctx.client.deleteProject(args.project_id);
2076
+ const project = await ctx.client.getProject(args.project_id);
2077
+ status = project.status;
2044
2078
  } catch (err) {
2045
2079
  const message = err instanceof Error ? err.message : String(err);
2080
+ return errorResult(`Failed to load project ${args.project_id}: ${message}`);
2081
+ }
2082
+ if (status !== "archived") {
2046
2083
  return errorResult(
2047
- `Failed to delete project ${args.project_id}: ${message} (a project must be archived before it can be deleted).`
2084
+ `Project ${args.project_id} (status '${status}') can't be deleted. Reconfirm with the user whether deleting this project is intended or a mistake before taking any further action.`
2048
2085
  );
2049
2086
  }
2087
+ try {
2088
+ await ctx.client.deleteProject(args.project_id);
2089
+ } catch (err) {
2090
+ const message = err instanceof Error ? err.message : String(err);
2091
+ return errorResult(`Failed to delete project ${args.project_id}: ${message}`);
2092
+ }
2050
2093
  return jsonResult({ deleted: true, project_id: args.project_id });
2051
2094
  }
2052
2095
  };
@@ -2403,20 +2446,32 @@ var unarchiveProjectTool = {
2403
2446
  import { z as z10 } from "zod";
2404
2447
  var inputSchema10 = {
2405
2448
  project_id: z10.string().min(1).describe("UUID of the project to update."),
2406
- name: z10.string().optional().describe("New project name."),
2407
- description: z10.string().optional().describe("New project description.")
2449
+ name: z10.string().min(1).optional().describe("New project name."),
2450
+ description: z10.string().optional().describe("New project description."),
2451
+ project_type: z10.enum(["greenfield", "brownfield", "auto"]).optional().describe(
2452
+ "Codebase type. 'greenfield' or 'brownfield' sets it explicitly; 'auto' clears it so the workflow decides. Omit to leave unchanged."
2453
+ )
2408
2454
  };
2409
2455
  var updateProjectTool = {
2410
2456
  name: "update_project",
2411
- description: "Update a project's metadata (name, description). Returns the updated metadata.",
2457
+ description: "Update a project's metadata (name, description, project_type). Returns the updated metadata.",
2412
2458
  inputSchema: inputSchema10,
2413
2459
  handler: async (args, ctx) => {
2414
- if (args.name === void 0 && args.description === void 0) {
2415
- return errorResult("Provide at least one field to update (name or description).");
2460
+ if (args.name === void 0 && args.description === void 0 && args.project_type === void 0) {
2461
+ return errorResult(
2462
+ "Provide at least one field to update (name, description, or project_type)."
2463
+ );
2464
+ }
2465
+ let projectType;
2466
+ if (args.project_type === "auto") {
2467
+ projectType = "";
2468
+ } else {
2469
+ projectType = args.project_type;
2416
2470
  }
2417
2471
  const project = await ctx.client.updateProject(args.project_id, {
2418
2472
  name: args.name,
2419
- description: args.description
2473
+ description: args.description,
2474
+ projectType
2420
2475
  });
2421
2476
  return jsonResult({ project: projectSummary(project) });
2422
2477
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myspec/mcp-server",
3
- "version": "0.1.2-next.35",
3
+ "version": "0.1.2-next.37",
4
4
  "description": "MySpec MCP server — exposes MySpec platform projects, files and attachments to MCP-aware clients via OAuth-authenticated access tokens.",
5
5
  "type": "module",
6
6
  "repository": {