@studiometa/productive-mcp 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"deals.d.ts","sourceRoot":"","sources":["../../src/handlers/deals.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,eAAO,MAAM,WAAW;;;wFAwBtB,CAAC"}
1
+ {"version":3,"file":"deals.d.ts","sourceRoot":"","sources":["../../src/handlers/deals.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3C,eAAO,MAAM,WAAW;;;wFAsCtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/handlers/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8pB7C;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAevD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CAY/C"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/handlers/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgrB7C;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAevD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CAY/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,YAAY,CAAC;AA0B7D,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8D7C;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE,qBAAqB,GACjC,OAAO,CAAC,UAAU,CAAC,CAgKrB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,YAAY,CAAC;AA2B7D,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8D7C;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE,qBAAqB,GACjC,OAAO,CAAC,UAAU,CAAC,CAoKrB"}
@@ -7,7 +7,7 @@ import type { CommonArgs } from './types.js';
7
7
  /**
8
8
  * Handle projects resource.
9
9
  *
10
- * Supports: list, get, resolve
10
+ * Supports: list, get, resolve, context
11
11
  */
12
12
  export declare const handleProjects: (action: string, args: CommonArgs & {
13
13
  query?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/handlers/projects.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;wFAUzB,CAAC"}
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/handlers/projects.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ7C;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;wFAwBzB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Summaries MCP handler.
3
+ *
4
+ * Custom handler for dashboard-style summaries (not using createResourceHandler).
5
+ * Routes actions to the appropriate summary executor.
6
+ */
7
+ import type { HandlerContext, ToolResult } from './types.js';
8
+ interface SummaryArgs {
9
+ project_id?: string;
10
+ }
11
+ /**
12
+ * Handle summaries resource.
13
+ *
14
+ * Supports: my_day, project_health, team_pulse
15
+ */
16
+ export declare function handleSummaries(action: string, args: SummaryArgs, ctx: HandlerContext): Promise<ToolResult>;
17
+ export {};
18
+ //# sourceMappingURL=summaries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summaries.d.ts","sourceRoot":"","sources":["../../src/handlers/summaries.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO7D,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,UAAU,CAAC,CA2ErB"}
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/handlers/tasks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,eAAO,MAAM,WAAW;;;wFAsCtB,CAAC"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/handlers/tasks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3C,eAAO,MAAM,WAAW;;;wFAsDtB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { ProductiveApi, formatAttachment, formatBooking, formatComment, formatCompany, formatDeal, formatDiscussion, formatListResponse, formatPage, formatPerson, formatProject, formatService, formatTask, formatTimeEntry, formatTimer } from "@studiometa/productive-api";
2
- import { RESOURCES, ResolveError, VALID_REPORT_TYPES, createBooking, createComment, createCompany, createDeal, createDiscussion, createPage, createTask, createTimeEntry, deleteAttachment, deleteDiscussion, deletePage, deleteTimeEntry, fromHandlerContext, getAttachment, getBooking, getComment, getCompany, getDeal, getDiscussion, getPage, getPerson, getProject, getReport, getTask, getTimeEntry, getTimer, listAttachments, listBookings, listComments, listCompanies, listDeals, listDiscussions, listPages, listPeople, listProjects, listServices, listTasks, listTimeEntries, listTimers, reopenDiscussion, resolveDiscussion, resolveResource, startTimer, stopTimer, updateBooking, updateComment, updateCompany, updateDeal, updateDiscussion, updatePage, updateTask, updateTimeEntry } from "@studiometa/productive-core";
2
+ import { RESOURCES, ResolveError, VALID_REPORT_TYPES, createBooking, createComment, createCompany, createDeal, createDiscussion, createPage, createTask, createTimeEntry, deleteAttachment, deleteDiscussion, deletePage, deleteTimeEntry, fromHandlerContext, getAttachment, getBooking, getComment, getCompany, getDeal, getDealContext, getDiscussion, getMyDaySummary, getPage, getPerson, getProject, getProjectContext, getProjectHealthSummary, getReport, getTask, getTaskContext, getTeamPulseSummary, getTimeEntry, getTimer, listAttachments, listBookings, listComments, listCompanies, listDeals, listDiscussions, listPages, listPeople, listProjects, listServices, listTasks, listTimeEntries, listTimers, reopenDiscussion, resolveDiscussion, resolveResource, startTimer, stopTimer, updateBooking, updateComment, updateCompany, updateDeal, updateDiscussion, updatePage, updateTask, updateTimeEntry } from "@studiometa/productive-core";
3
3
  /**
4
4
  * Custom error classes for MCP server
5
5
  *
@@ -1238,7 +1238,8 @@ const handleDeals = createResourceHandler({
1238
1238
  "get",
1239
1239
  "create",
1240
1240
  "update",
1241
- "resolve"
1241
+ "resolve",
1242
+ "context"
1242
1243
  ],
1243
1244
  formatter: formatDeal$1,
1244
1245
  hints: (_data, id) => getDealHints(id),
@@ -1259,6 +1260,20 @@ const handleDeals = createResourceHandler({
1259
1260
  })
1260
1261
  },
1261
1262
  update: { mapOptions: (args) => ({ name: args.name }) },
1263
+ customActions: { context: async (args, ctx, execCtx) => {
1264
+ if (!args.id) return inputErrorResult(ErrorMessages.missingId("context"));
1265
+ const result = await getDealContext({ id: args.id }, execCtx);
1266
+ const formatOptions = {
1267
+ ...ctx.formatOptions,
1268
+ included: result.included
1269
+ };
1270
+ return jsonResult({
1271
+ ...formatDeal$1(result.data.deal, formatOptions),
1272
+ services: result.data.services.map((s) => formatService$1(s, { compact: true })),
1273
+ comments: result.data.comments.map((c) => formatComment$1(c, { compact: true })),
1274
+ time_entries: result.data.time_entries.map((t) => formatTimeEntry$1(t, { compact: true }))
1275
+ });
1276
+ } },
1262
1277
  executors: {
1263
1278
  list: listDeals,
1264
1279
  get: getDeal,
@@ -1389,7 +1404,8 @@ var RESOURCE_HELP = {
1389
1404
  actions: {
1390
1405
  list: "List all projects with optional filters",
1391
1406
  get: "Get a single project by ID (supports PRJ-123, P-123 format)",
1392
- resolve: "Resolve by project number (PRJ-123, P-123)"
1407
+ resolve: "Resolve by project number (PRJ-123, P-123)",
1408
+ context: "Get full project context in one call: project details + open tasks + services + recent time entries"
1393
1409
  },
1394
1410
  filters: {
1395
1411
  query: "Text search on project name",
@@ -1430,6 +1446,14 @@ var RESOURCE_HELP = {
1430
1446
  action: "get",
1431
1447
  id: "12345"
1432
1448
  }
1449
+ },
1450
+ {
1451
+ description: "Get full project context",
1452
+ params: {
1453
+ resource: "projects",
1454
+ action: "context",
1455
+ id: "12345"
1456
+ }
1433
1457
  }
1434
1458
  ]
1435
1459
  },
@@ -1440,7 +1464,8 @@ var RESOURCE_HELP = {
1440
1464
  get: "Get a single task by ID with full details (description, comments, etc.)",
1441
1465
  create: "Create a new task (requires title, project_id, task_list_id)",
1442
1466
  update: "Update an existing task",
1443
- resolve: "Resolve by text search"
1467
+ resolve: "Resolve by text search",
1468
+ context: "Get full task context in one call: task details + comments + time entries + subtasks"
1444
1469
  },
1445
1470
  filters: {
1446
1471
  query: "Text search on task title",
@@ -1516,6 +1541,14 @@ var RESOURCE_HELP = {
1516
1541
  project_id: "12345",
1517
1542
  task_list_id: "111"
1518
1543
  }
1544
+ },
1545
+ {
1546
+ description: "Get full task context",
1547
+ params: {
1548
+ resource: "tasks",
1549
+ action: "context",
1550
+ id: "67890"
1551
+ }
1519
1552
  }
1520
1553
  ]
1521
1554
  },
@@ -1833,7 +1866,8 @@ var RESOURCE_HELP = {
1833
1866
  get: "Get a single deal by ID (supports D-123, DEAL-123 format)",
1834
1867
  create: "Create a new deal (requires name, company_id)",
1835
1868
  update: "Update an existing deal",
1836
- resolve: "Resolve by deal number (D-123, DEAL-123)"
1869
+ resolve: "Resolve by deal number (D-123, DEAL-123)",
1870
+ context: "Get full deal context in one call: deal details + services + comments + time entries"
1837
1871
  },
1838
1872
  filters: {
1839
1873
  query: "Text search on deal name",
@@ -1883,6 +1917,14 @@ var RESOURCE_HELP = {
1883
1917
  action: "list",
1884
1918
  filter: { type: "2" }
1885
1919
  }
1920
+ },
1921
+ {
1922
+ description: "Get full deal context",
1923
+ params: {
1924
+ resource: "deals",
1925
+ action: "context",
1926
+ id: "12345"
1927
+ }
1886
1928
  }
1887
1929
  ]
1888
1930
  },
@@ -2173,7 +2215,7 @@ const handlePages = createResourceHandler({
2173
2215
  /**
2174
2216
  * People MCP handler.
2175
2217
  */
2176
- var VALID_ACTIONS$1 = [
2218
+ var VALID_ACTIONS$2 = [
2177
2219
  "list",
2178
2220
  "get",
2179
2221
  "me",
@@ -2224,7 +2266,7 @@ async function handlePeople(action, args, ctx, credentials) {
2224
2266
  });
2225
2267
  return jsonResult(response);
2226
2268
  }
2227
- return inputErrorResult(ErrorMessages.invalidAction(action, "people", VALID_ACTIONS$1));
2269
+ return inputErrorResult(ErrorMessages.invalidAction(action, "people", VALID_ACTIONS$2));
2228
2270
  }
2229
2271
  /**
2230
2272
  * Projects MCP handler.
@@ -2234,18 +2276,36 @@ async function handlePeople(action, args, ctx, credentials) {
2234
2276
  /**
2235
2277
  * Handle projects resource.
2236
2278
  *
2237
- * Supports: list, get, resolve
2279
+ * Supports: list, get, resolve, context
2238
2280
  */
2239
2281
  const handleProjects = createResourceHandler({
2240
2282
  resource: "projects",
2241
2283
  actions: [
2242
2284
  "list",
2243
2285
  "get",
2244
- "resolve"
2286
+ "resolve",
2287
+ "context"
2245
2288
  ],
2246
2289
  formatter: formatProject$1,
2247
2290
  hints: (_data, id) => getProjectHints(id),
2248
2291
  supportsResolve: true,
2292
+ customActions: { context: async (args, ctx, execCtx) => {
2293
+ if (!args.id) return inputErrorResult(ErrorMessages.missingId("context"));
2294
+ const result = await getProjectContext({ id: args.id }, execCtx);
2295
+ const formatOptions = {
2296
+ ...ctx.formatOptions,
2297
+ included: result.included
2298
+ };
2299
+ return jsonResult({
2300
+ ...formatProject$1(result.data.project, ctx.formatOptions),
2301
+ tasks: result.data.tasks.map((t) => formatTask$1(t, {
2302
+ ...formatOptions,
2303
+ compact: true
2304
+ })),
2305
+ services: result.data.services.map((s) => formatService$1(s, { compact: true })),
2306
+ time_entries: result.data.time_entries.map((t) => formatTimeEntry$1(t, { compact: true }))
2307
+ });
2308
+ } },
2249
2309
  executors: {
2250
2310
  list: listProjects,
2251
2311
  get: getProject
@@ -2264,11 +2324,11 @@ function formatReportData(data) {
2264
2324
  };
2265
2325
  });
2266
2326
  }
2267
- var VALID_ACTIONS = ["get"];
2327
+ var VALID_ACTIONS$1 = ["get"];
2268
2328
  async function handleReports(action, args, ctx) {
2269
2329
  const { filter, page, perPage } = ctx;
2270
2330
  const { report_type, group, from, to, person_id, project_id, company_id, deal_id, status } = args;
2271
- if (action !== "get") return inputErrorResult(ErrorMessages.invalidAction(action, "reports", VALID_ACTIONS));
2331
+ if (action !== "get") return inputErrorResult(ErrorMessages.invalidAction(action, "reports", VALID_ACTIONS$1));
2272
2332
  if (!report_type) return inputErrorResult(ErrorMessages.missingReportType());
2273
2333
  if (!VALID_REPORT_TYPES.includes(report_type)) return inputErrorResult(ErrorMessages.invalidReportType(report_type, [...VALID_REPORT_TYPES]));
2274
2334
  const execCtx = ctx.executor();
@@ -2756,6 +2816,72 @@ const handleServices = createResourceHandler({
2756
2816
  executors: { list: listServices }
2757
2817
  });
2758
2818
  /**
2819
+ * Summaries MCP handler.
2820
+ *
2821
+ * Custom handler for dashboard-style summaries (not using createResourceHandler).
2822
+ * Routes actions to the appropriate summary executor.
2823
+ */
2824
+ var VALID_ACTIONS = [
2825
+ "my_day",
2826
+ "project_health",
2827
+ "team_pulse",
2828
+ "help"
2829
+ ];
2830
+ /**
2831
+ * Handle summaries resource.
2832
+ *
2833
+ * Supports: my_day, project_health, team_pulse
2834
+ */
2835
+ async function handleSummaries(action, args, ctx) {
2836
+ if (!VALID_ACTIONS.includes(action)) return inputErrorResult(ErrorMessages.invalidAction(action, "summaries", VALID_ACTIONS));
2837
+ const execCtx = ctx.executor();
2838
+ switch (action) {
2839
+ case "my_day": return jsonResult((await getMyDaySummary({}, execCtx)).data);
2840
+ case "project_health":
2841
+ if (!args.project_id) return inputErrorResult(new UserInputError("project_id is required for project_health summary", [
2842
+ "Provide the project_id parameter",
2843
+ "You can find project IDs using resource=\"projects\" action=\"list\"",
2844
+ "Or use a project number like \"PRJ-123\""
2845
+ ]));
2846
+ return jsonResult((await getProjectHealthSummary({ projectId: args.project_id }, execCtx)).data);
2847
+ case "team_pulse": return jsonResult((await getTeamPulseSummary({}, execCtx)).data);
2848
+ case "help": return jsonResult({
2849
+ resource: "summaries",
2850
+ description: "Dashboard-style summaries that aggregate data from multiple resources",
2851
+ actions: {
2852
+ my_day: {
2853
+ description: "Personal dashboard for the current user",
2854
+ parameters: {},
2855
+ returns: {
2856
+ tasks: "Open and overdue tasks assigned to you",
2857
+ time: "Time entries logged today",
2858
+ timers: "Currently running timers"
2859
+ }
2860
+ },
2861
+ project_health: {
2862
+ description: "Project status with budget burn and task stats",
2863
+ parameters: { project_id: "Required. Project ID or project number (e.g., PRJ-123)" },
2864
+ returns: {
2865
+ project: "Project details",
2866
+ tasks: "Open and overdue task counts",
2867
+ budget: "Budget burn rate by service",
2868
+ recent_activity: "Time tracking activity in last 7 days"
2869
+ }
2870
+ },
2871
+ team_pulse: {
2872
+ description: "Team-wide time tracking activity for today",
2873
+ parameters: {},
2874
+ returns: {
2875
+ team: "Counts of active users, those tracking time, and with timers",
2876
+ people: "Per-person breakdown of time logged and active timers"
2877
+ }
2878
+ }
2879
+ }
2880
+ });
2881
+ default: return inputErrorResult(ErrorMessages.invalidAction(action, "summaries", VALID_ACTIONS));
2882
+ }
2883
+ }
2884
+ /**
2759
2885
  * Tasks MCP handler.
2760
2886
  */
2761
2887
  const handleTasks = createResourceHandler({
@@ -2766,7 +2892,8 @@ const handleTasks = createResourceHandler({
2766
2892
  "get",
2767
2893
  "create",
2768
2894
  "update",
2769
- "resolve"
2895
+ "resolve",
2896
+ "context"
2770
2897
  ],
2771
2898
  formatter: formatTask$1,
2772
2899
  hints: (data, id) => {
@@ -2798,6 +2925,23 @@ const handleTasks = createResourceHandler({
2798
2925
  description: args.description,
2799
2926
  assigneeId: args.assignee_id
2800
2927
  }) },
2928
+ customActions: { context: async (args, ctx, execCtx) => {
2929
+ if (!args.id) return inputErrorResult(ErrorMessages.missingId("context"));
2930
+ const result = await getTaskContext({ id: args.id }, execCtx);
2931
+ const formatOptions = {
2932
+ ...ctx.formatOptions,
2933
+ included: result.included
2934
+ };
2935
+ return jsonResult({
2936
+ ...formatTask$1(result.data.task, formatOptions),
2937
+ comments: result.data.comments.map((c) => formatComment$1(c, { compact: true })),
2938
+ time_entries: result.data.time_entries.map((t) => formatTimeEntry$1(t, { compact: true })),
2939
+ subtasks: result.data.subtasks.map((s) => formatTask$1(s, {
2940
+ ...formatOptions,
2941
+ compact: true
2942
+ }))
2943
+ });
2944
+ } },
2801
2945
  executors: {
2802
2946
  list: listTasks,
2803
2947
  get: getTask,
@@ -2941,7 +3085,7 @@ async function executeToolWithCredentials(name, args, credentials) {
2941
3085
  query
2942
3086
  };
2943
3087
  const includeHints = no_hints !== true && action === "get" && !isCompact;
2944
- const execCtx = fromHandlerContext({ api });
3088
+ const execCtx = fromHandlerContext({ api }, { userId: credentials.userId });
2945
3089
  const ctx = {
2946
3090
  formatOptions,
2947
3091
  filter: stringFilter,
@@ -2952,7 +3096,7 @@ async function executeToolWithCredentials(name, args, credentials) {
2952
3096
  executor: () => execCtx
2953
3097
  };
2954
3098
  try {
2955
- if (action === "help") return resource ? handleHelp(resource) : handleHelpOverview();
3099
+ if (action === "help" && resource !== "summaries") return resource ? handleHelp(resource) : handleHelpOverview();
2956
3100
  if (action === "schema") return resource ? handleSchema(resource) : handleSchemaOverview();
2957
3101
  const resolveArgs = {
2958
3102
  query,
@@ -2991,6 +3135,7 @@ async function executeToolWithCredentials(name, args, credentials) {
2991
3135
  case "pages": return await handlePages(action, restArgs, ctx);
2992
3136
  case "discussions": return await handleDiscussions(action, restArgs, ctx);
2993
3137
  case "reports": return await handleReports(action, restArgs, ctx);
3138
+ case "summaries": return await handleSummaries(action, restArgs, ctx);
2994
3139
  case "budgets": return inputErrorResult(new UserInputError("The \"budgets\" resource has been removed. Budgets are deals with type=2.", [
2995
3140
  "Use resource=\"deals\" with filter[type]=\"2\" to list only budgets",
2996
3141
  "To create a budget: resource=\"deals\" action=\"create\" with budget=true",
@@ -3011,4 +3156,4 @@ async function executeToolWithCredentials(name, args, credentials) {
3011
3156
  }
3012
3157
  export { executeToolWithCredentials as t };
3013
3158
 
3014
- //# sourceMappingURL=handlers-DWowqxFA.js.map
3159
+ //# sourceMappingURL=handlers-B8GRTaDu.js.map