@studiometa/productive-mcp 0.9.2 → 0.10.1

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 (61) hide show
  1. package/dist/errors.d.ts +1 -0
  2. package/dist/errors.d.ts.map +1 -1
  3. package/dist/formatters.d.ts +0 -4
  4. package/dist/formatters.d.ts.map +1 -1
  5. package/dist/handlers/attachments.d.ts +5 -2
  6. package/dist/handlers/attachments.d.ts.map +1 -1
  7. package/dist/handlers/batch.d.ts +58 -0
  8. package/dist/handlers/batch.d.ts.map +1 -0
  9. package/dist/handlers/bookings.d.ts +5 -2
  10. package/dist/handlers/bookings.d.ts.map +1 -1
  11. package/dist/handlers/comments.d.ts +5 -2
  12. package/dist/handlers/comments.d.ts.map +1 -1
  13. package/dist/handlers/companies.d.ts +11 -5
  14. package/dist/handlers/companies.d.ts.map +1 -1
  15. package/dist/handlers/deals.d.ts +4 -5
  16. package/dist/handlers/deals.d.ts.map +1 -1
  17. package/dist/handlers/discussions.d.ts +5 -9
  18. package/dist/handlers/discussions.d.ts.map +1 -1
  19. package/dist/handlers/factory.d.ts +116 -0
  20. package/dist/handlers/factory.d.ts.map +1 -0
  21. package/dist/handlers/help.d.ts.map +1 -1
  22. package/dist/handlers/index.d.ts.map +1 -1
  23. package/dist/handlers/pages.d.ts +12 -9
  24. package/dist/handlers/pages.d.ts.map +1 -1
  25. package/dist/handlers/projects.d.ts +11 -5
  26. package/dist/handlers/projects.d.ts.map +1 -1
  27. package/dist/handlers/schema.d.ts +33 -0
  28. package/dist/handlers/schema.d.ts.map +1 -0
  29. package/dist/handlers/search.d.ts +28 -0
  30. package/dist/handlers/search.d.ts.map +1 -0
  31. package/dist/handlers/services.d.ts +12 -2
  32. package/dist/handlers/services.d.ts.map +1 -1
  33. package/dist/handlers/tasks.d.ts +4 -5
  34. package/dist/handlers/tasks.d.ts.map +1 -1
  35. package/dist/handlers/time.d.ts +4 -6
  36. package/dist/handlers/time.d.ts.map +1 -1
  37. package/dist/handlers/timers.d.ts +5 -2
  38. package/dist/handlers/timers.d.ts.map +1 -1
  39. package/dist/handlers/types.d.ts +6 -0
  40. package/dist/handlers/types.d.ts.map +1 -1
  41. package/dist/{handlers-D4tRd30c.js → handlers-DWowqxFA.js} +1247 -898
  42. package/dist/handlers-DWowqxFA.js.map +1 -0
  43. package/dist/handlers.js +1 -1
  44. package/dist/hints.d.ts +0 -4
  45. package/dist/hints.d.ts.map +1 -1
  46. package/dist/http.js +2 -2
  47. package/dist/index.js +2 -2
  48. package/dist/schema.d.ts +17 -2
  49. package/dist/schema.d.ts.map +1 -1
  50. package/dist/server.js +2 -2
  51. package/dist/stdio.js +1 -1
  52. package/dist/tools.d.ts.map +1 -1
  53. package/dist/tools.js +63 -15
  54. package/dist/tools.js.map +1 -1
  55. package/dist/{version-IB2ulmSy.js → version-DoRPyhTL.js} +2 -2
  56. package/dist/{version-IB2ulmSy.js.map → version-DoRPyhTL.js.map} +1 -1
  57. package/package.json +3 -3
  58. package/skills/SKILL.md +35 -54
  59. package/dist/handlers/budgets.d.ts +0 -9
  60. package/dist/handlers/budgets.d.ts.map +0 -1
  61. package/dist/handlers-D4tRd30c.js.map +0 -1
package/dist/tools.js CHANGED
@@ -4,7 +4,18 @@ import { ACTIONS, REPORT_TYPES, RESOURCES } from "@studiometa/productive-core";
4
4
  * Adding a resource or action to constants.ts automatically updates this description.
5
5
  */
6
6
  function generateDescription() {
7
- return `Productive.io API. Resources: ${RESOURCES.join(", ")}. Actions: ${ACTIONS.join(", ")} (varies by resource). Use query for text search on list actions. Reports: use resource=reports, action=get with report_type. Filters: project_id, person_id, service_id, company_id, after/before (dates). Use include to fetch related data. Use compact=false for full details (default for get, true for list). Use action=help with a resource for detailed documentation.`;
7
+ return [
8
+ "Productive.io API.",
9
+ `Resources: ${RESOURCES.join(", ")}.`,
10
+ `Actions: ${ACTIONS.join(", ")} (varies by resource).`,
11
+ "Discovery: action=help with any resource for filters, fields, examples. action=schema for compact machine-readable spec.",
12
+ "Filters: filter:{key:value}. Common: project_id, person_id, after/before (YYYY-MM-DD).",
13
+ "Includes: include:[...] for related data (e.g. [\"project\",\"assignee\"]).",
14
+ "Output: compact=false for full detail (default for get; list defaults true).",
15
+ "Search: query for text search on list actions. Cross-resource: resource=search action=run with query searches projects, companies, people, tasks simultaneously.",
16
+ "Reports: resource=reports action=get with report_type, from, to.",
17
+ "Batch: resource=batch action=run with operations=[{resource,action,...}] executes up to 10 ops in parallel."
18
+ ].join("\n");
8
19
  }
9
20
  /**
10
21
  * Single consolidated tool for Productive.io MCP server
@@ -41,7 +52,7 @@ const TOOLS = [{
41
52
  action: {
42
53
  type: "string",
43
54
  enum: [...ACTIONS],
44
- description: "Action to perform. Use \"help\" for detailed documentation on a resource."
55
+ description: "Use \"help\" for resource documentation"
45
56
  },
46
57
  id: { type: "string" },
47
58
  filter: { type: "object" },
@@ -54,11 +65,16 @@ const TOOLS = [{
54
65
  include: {
55
66
  type: "array",
56
67
  items: { type: "string" },
57
- description: "Related resources to include (e.g., [\"project\", \"assignee\", \"comments\"])"
68
+ description: "Related data to include (e.g. [\"project\",\"assignee\"])"
58
69
  },
59
70
  query: {
60
71
  type: "string",
61
- description: "Text search query for list actions (searches name/title fields)"
72
+ description: "Text search for list actions"
73
+ },
74
+ resources: {
75
+ type: "array",
76
+ items: { type: "string" },
77
+ description: "Resource types to search (for resource=search). Defaults to [projects, companies, people, tasks]. Valid values: projects, companies, people, tasks, deals."
62
78
  },
63
79
  person_id: { type: "string" },
64
80
  service_id: { type: "string" },
@@ -75,30 +91,62 @@ const TOOLS = [{
75
91
  name: { type: "string" },
76
92
  page_id: {
77
93
  type: "string",
78
- description: "Page ID. Find pages using resource=\"pages\" action=\"list\""
94
+ description: "Page ID (list pages to find)"
79
95
  },
80
96
  parent_page_id: {
81
97
  type: "string",
82
- description: "Parent page ID for creating sub-pages"
98
+ description: "Parent page ID for sub-pages"
99
+ },
100
+ body: {
101
+ type: "string",
102
+ description: "Comment/page body content"
83
103
  },
84
- body: { type: "string" },
85
104
  deal_id: { type: "string" },
86
105
  comment_id: {
87
106
  type: "string",
88
- description: "Comment ID for filtering attachments"
107
+ description: "Comment ID (for attachments)"
89
108
  },
90
109
  time_entry_id: { type: "string" },
91
- started_on: { type: "string" },
92
- ended_on: { type: "string" },
110
+ started_on: {
111
+ type: "string",
112
+ description: "Booking date (YYYY-MM-DD)"
113
+ },
114
+ ended_on: {
115
+ type: "string",
116
+ description: "Booking end date (YYYY-MM-DD)"
117
+ },
93
118
  event_id: { type: "string" },
94
119
  report_type: {
95
120
  type: "string",
96
- enum: [...REPORT_TYPES]
121
+ enum: [...REPORT_TYPES],
122
+ description: "Required for resource=reports action=get"
123
+ },
124
+ group: {
125
+ type: "string",
126
+ description: "Report grouping: person, project, service"
127
+ },
128
+ from: {
129
+ type: "string",
130
+ description: "Report start (YYYY-MM-DD); filter.after for time"
131
+ },
132
+ to: {
133
+ type: "string",
134
+ description: "Report end (YYYY-MM-DD); filter.before for time"
97
135
  },
98
- group: { type: "string" },
99
- from: { type: "string" },
100
- to: { type: "string" },
101
- status: { type: "string" }
136
+ status: { type: "string" },
137
+ operations: {
138
+ type: "array",
139
+ items: {
140
+ type: "object",
141
+ properties: {
142
+ resource: { type: "string" },
143
+ action: { type: "string" }
144
+ },
145
+ required: ["resource", "action"]
146
+ },
147
+ maxItems: 10,
148
+ description: "Array of operations for batch execution (max 10). Each operation needs resource, action, and any additional params."
149
+ }
102
150
  },
103
151
  required: ["resource", "action"]
104
152
  }
package/dist/tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","names":[],"sources":["../src/tools.ts"],"sourcesContent":["import type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { RESOURCES, ACTIONS, REPORT_TYPES } from '@studiometa/productive-core';\n\n/**\n * Generate the tool description dynamically from the constants.\n * Adding a resource or action to constants.ts automatically updates this description.\n */\nfunction generateDescription(): string {\n return (\n `Productive.io API. Resources: ${RESOURCES.join(', ')}. ` +\n `Actions: ${ACTIONS.join(', ')} (varies by resource). ` +\n 'Use query for text search on list actions. ' +\n 'Reports: use resource=reports, action=get with report_type. ' +\n 'Filters: project_id, person_id, service_id, company_id, after/before (dates). ' +\n 'Use include to fetch related data. ' +\n 'Use compact=false for full details (default for get, true for list). ' +\n 'Use action=help with a resource for detailed documentation.'\n );\n}\n\n/**\n * Single consolidated tool for Productive.io MCP server\n *\n * The resource/action/report_type enums and description are derived from\n * the shared constants in constants.ts — the single source of truth for both\n * the MCP tool definition and the Zod validation schemas.\n * Adding a new resource, action, or report type there automatically updates\n * both the tool exposed to clients and the validation layer.\n *\n * MCP Annotations (for MCP directory compliance):\n * - readOnlyHint: false - Tool can create/update data\n * - destructiveHint: false - Tool does not permanently delete data\n * - idempotentHint: false - Create actions are not idempotent\n * - openWorldHint: true - Tool interacts with external Productive.io API\n */\nexport const TOOLS: Tool[] = [\n {\n name: 'productive',\n description: generateDescription(),\n annotations: {\n title: 'Productive.io',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: {\n type: 'object',\n properties: {\n resource: {\n type: 'string',\n enum: [...RESOURCES],\n },\n action: {\n type: 'string',\n enum: [...ACTIONS],\n description: 'Action to perform. Use \"help\" for detailed documentation on a resource.',\n },\n id: { type: 'string' },\n filter: { type: 'object' },\n page: { type: 'number' },\n per_page: { type: 'number' },\n compact: {\n type: 'boolean',\n description: 'Compact output (default: true for list, false for get)',\n },\n include: {\n type: 'array',\n items: { type: 'string' },\n description: 'Related resources to include (e.g., [\"project\", \"assignee\", \"comments\"])',\n },\n query: {\n type: 'string',\n description: 'Text search query for list actions (searches name/title fields)',\n },\n // Common fields\n person_id: { type: 'string' },\n service_id: { type: 'string' },\n task_id: { type: 'string' },\n company_id: { type: 'string' },\n time: { type: 'number' },\n date: { type: 'string' },\n note: { type: 'string' },\n // Task fields\n title: { type: 'string' },\n project_id: { type: 'string' },\n task_list_id: { type: 'string' },\n description: { type: 'string' },\n assignee_id: { type: 'string' },\n // Company fields\n name: { type: 'string' },\n // Page fields\n page_id: {\n type: 'string',\n description: 'Page ID. Find pages using resource=\"pages\" action=\"list\"',\n },\n parent_page_id: { type: 'string', description: 'Parent page ID for creating sub-pages' },\n // Comment fields\n body: { type: 'string' },\n deal_id: { type: 'string' },\n // Attachment fields\n comment_id: { type: 'string', description: 'Comment ID for filtering attachments' },\n // Timer fields\n time_entry_id: { type: 'string' },\n // Booking fields\n started_on: { type: 'string' },\n ended_on: { type: 'string' },\n event_id: { type: 'string' },\n // Report fields\n report_type: {\n type: 'string',\n enum: [...REPORT_TYPES],\n },\n group: { type: 'string' },\n from: { type: 'string' },\n to: { type: 'string' },\n status: { type: 'string' },\n },\n required: ['resource', 'action'],\n },\n },\n];\n\n/**\n * Additional tools only available in stdio mode (local execution)\n * These tools manage persistent configuration\n */\nexport const STDIO_ONLY_TOOLS: Tool[] = [\n {\n name: 'productive_configure',\n description: 'Configure Productive.io credentials',\n annotations: {\n title: 'Configure Productive',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: {\n type: 'object',\n properties: {\n organizationId: { type: 'string' },\n apiToken: { type: 'string' },\n userId: { type: 'string' },\n },\n required: ['organizationId', 'apiToken'],\n },\n },\n {\n name: 'productive_get_config',\n description: 'Get current configuration',\n annotations: {\n title: 'Get Productive Config',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n];\n"],"mappings":";;;;;AAQA,SAAS,sBAA8B;AACrC,QACE,iCAAiC,UAAU,KAAK,KAAK,CAAC,aAC1C,QAAQ,KAAK,KAAK,CAAC;;;;;;;;;;;;;;;;;AAyBnC,MAAa,QAAgB,CAC3B;CACE,MAAM;CACN,aAAa,qBAAqB;CAClC,aAAa;EACX,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,aAAa;EACX,MAAM;EACN,YAAY;GACV,UAAU;IACR,MAAM;IACN,MAAM,CAAC,GAAG,UAAU;IACrB;GACD,QAAQ;IACN,MAAM;IACN,MAAM,CAAC,GAAG,QAAQ;IAClB,aAAa;IACd;GACD,IAAI,EAAE,MAAM,UAAU;GACtB,QAAQ,EAAE,MAAM,UAAU;GAC1B,MAAM,EAAE,MAAM,UAAU;GACxB,UAAU,EAAE,MAAM,UAAU;GAC5B,SAAS;IACP,MAAM;IACN,aAAa;IACd;GACD,SAAS;IACP,MAAM;IACN,OAAO,EAAE,MAAM,UAAU;IACzB,aAAa;IACd;GACD,OAAO;IACL,MAAM;IACN,aAAa;IACd;GAED,WAAW,EAAE,MAAM,UAAU;GAC7B,YAAY,EAAE,MAAM,UAAU;GAC9B,SAAS,EAAE,MAAM,UAAU;GAC3B,YAAY,EAAE,MAAM,UAAU;GAC9B,MAAM,EAAE,MAAM,UAAU;GACxB,MAAM,EAAE,MAAM,UAAU;GACxB,MAAM,EAAE,MAAM,UAAU;GAExB,OAAO,EAAE,MAAM,UAAU;GACzB,YAAY,EAAE,MAAM,UAAU;GAC9B,cAAc,EAAE,MAAM,UAAU;GAChC,aAAa,EAAE,MAAM,UAAU;GAC/B,aAAa,EAAE,MAAM,UAAU;GAE/B,MAAM,EAAE,MAAM,UAAU;GAExB,SAAS;IACP,MAAM;IACN,aAAa;IACd;GACD,gBAAgB;IAAE,MAAM;IAAU,aAAa;IAAyC;GAExF,MAAM,EAAE,MAAM,UAAU;GACxB,SAAS,EAAE,MAAM,UAAU;GAE3B,YAAY;IAAE,MAAM;IAAU,aAAa;IAAwC;GAEnF,eAAe,EAAE,MAAM,UAAU;GAEjC,YAAY,EAAE,MAAM,UAAU;GAC9B,UAAU,EAAE,MAAM,UAAU;GAC5B,UAAU,EAAE,MAAM,UAAU;GAE5B,aAAa;IACX,MAAM;IACN,MAAM,CAAC,GAAG,aAAa;IACxB;GACD,OAAO,EAAE,MAAM,UAAU;GACzB,MAAM,EAAE,MAAM,UAAU;GACxB,IAAI,EAAE,MAAM,UAAU;GACtB,QAAQ,EAAE,MAAM,UAAU;GAC3B;EACD,UAAU,CAAC,YAAY,SAAS;EACjC;CACF,CACF;;;;;AAMD,MAAa,mBAA2B,CACtC;CACE,MAAM;CACN,aAAa;CACb,aAAa;EACX,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,aAAa;EACX,MAAM;EACN,YAAY;GACV,gBAAgB,EAAE,MAAM,UAAU;GAClC,UAAU,EAAE,MAAM,UAAU;GAC5B,QAAQ,EAAE,MAAM,UAAU;GAC3B;EACD,UAAU,CAAC,kBAAkB,WAAW;EACzC;CACF,EACD;CACE,MAAM;CACN,aAAa;CACb,aAAa;EACX,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,aAAa;EACX,MAAM;EACN,YAAY,EAAE;EACf;CACF,CACF"}
1
+ {"version":3,"file":"tools.js","names":[],"sources":["../src/tools.ts"],"sourcesContent":["import type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { RESOURCES, ACTIONS, REPORT_TYPES } from '@studiometa/productive-core';\n\n/**\n * Generate the tool description dynamically from the constants.\n * Adding a resource or action to constants.ts automatically updates this description.\n */\nfunction generateDescription(): string {\n return [\n 'Productive.io API.',\n `Resources: ${RESOURCES.join(', ')}.`,\n `Actions: ${ACTIONS.join(', ')} (varies by resource).`,\n 'Discovery: action=help with any resource for filters, fields, examples. action=schema for compact machine-readable spec.',\n 'Filters: filter:{key:value}. Common: project_id, person_id, after/before (YYYY-MM-DD).',\n 'Includes: include:[...] for related data (e.g. [\"project\",\"assignee\"]).',\n 'Output: compact=false for full detail (default for get; list defaults true).',\n 'Search: query for text search on list actions. Cross-resource: resource=search action=run with query searches projects, companies, people, tasks simultaneously.',\n 'Reports: resource=reports action=get with report_type, from, to.',\n 'Batch: resource=batch action=run with operations=[{resource,action,...}] executes up to 10 ops in parallel.',\n ].join('\\n');\n}\n\n/**\n * Single consolidated tool for Productive.io MCP server\n *\n * The resource/action/report_type enums and description are derived from\n * the shared constants in constants.ts — the single source of truth for both\n * the MCP tool definition and the Zod validation schemas.\n * Adding a new resource, action, or report type there automatically updates\n * both the tool exposed to clients and the validation layer.\n *\n * MCP Annotations (for MCP directory compliance):\n * - readOnlyHint: false - Tool can create/update data\n * - destructiveHint: false - Tool does not permanently delete data\n * - idempotentHint: false - Create actions are not idempotent\n * - openWorldHint: true - Tool interacts with external Productive.io API\n */\nexport const TOOLS: Tool[] = [\n {\n name: 'productive',\n description: generateDescription(),\n annotations: {\n title: 'Productive.io',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: {\n type: 'object',\n properties: {\n resource: {\n type: 'string',\n enum: [...RESOURCES],\n },\n action: {\n type: 'string',\n enum: [...ACTIONS],\n description: 'Use \"help\" for resource documentation',\n },\n id: { type: 'string' },\n filter: { type: 'object' },\n page: { type: 'number' },\n per_page: { type: 'number' },\n compact: {\n type: 'boolean',\n description: 'Compact output (default: true for list, false for get)',\n },\n include: {\n type: 'array',\n items: { type: 'string' },\n description: 'Related data to include (e.g. [\"project\",\"assignee\"])',\n },\n query: { type: 'string', description: 'Text search for list actions' },\n resources: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Resource types to search (for resource=search). Defaults to [projects, companies, people, tasks]. Valid values: projects, companies, people, tasks, deals.',\n },\n // Common fields\n person_id: { type: 'string' },\n service_id: { type: 'string' },\n task_id: { type: 'string' },\n company_id: { type: 'string' },\n time: { type: 'number' },\n date: { type: 'string' },\n note: { type: 'string' },\n // Task fields\n title: { type: 'string' },\n project_id: { type: 'string' },\n task_list_id: { type: 'string' },\n description: { type: 'string' },\n assignee_id: { type: 'string' },\n // Company fields\n name: { type: 'string' },\n // Page fields\n page_id: { type: 'string', description: 'Page ID (list pages to find)' },\n parent_page_id: { type: 'string', description: 'Parent page ID for sub-pages' },\n // Comment fields\n body: { type: 'string', description: 'Comment/page body content' },\n deal_id: { type: 'string' },\n // Attachment fields\n comment_id: { type: 'string', description: 'Comment ID (for attachments)' },\n // Timer fields\n time_entry_id: { type: 'string' },\n // Booking fields\n started_on: { type: 'string', description: 'Booking date (YYYY-MM-DD)' },\n ended_on: { type: 'string', description: 'Booking end date (YYYY-MM-DD)' },\n event_id: { type: 'string' },\n // Report fields\n report_type: {\n type: 'string',\n enum: [...REPORT_TYPES],\n description: 'Required for resource=reports action=get',\n },\n group: { type: 'string', description: 'Report grouping: person, project, service' },\n from: { type: 'string', description: 'Report start (YYYY-MM-DD); filter.after for time' },\n to: { type: 'string', description: 'Report end (YYYY-MM-DD); filter.before for time' },\n status: { type: 'string' },\n // Batch fields\n operations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n resource: { type: 'string' },\n action: { type: 'string' },\n },\n required: ['resource', 'action'],\n },\n maxItems: 10,\n description:\n 'Array of operations for batch execution (max 10). Each operation needs resource, action, and any additional params.',\n },\n },\n required: ['resource', 'action'],\n },\n },\n];\n\n/**\n * Additional tools only available in stdio mode (local execution)\n * These tools manage persistent configuration\n */\nexport const STDIO_ONLY_TOOLS: Tool[] = [\n {\n name: 'productive_configure',\n description: 'Configure Productive.io credentials',\n annotations: {\n title: 'Configure Productive',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: {\n type: 'object',\n properties: {\n organizationId: { type: 'string' },\n apiToken: { type: 'string' },\n userId: { type: 'string' },\n },\n required: ['organizationId', 'apiToken'],\n },\n },\n {\n name: 'productive_get_config',\n description: 'Get current configuration',\n annotations: {\n title: 'Get Productive Config',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n];\n"],"mappings":"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"}
@@ -23,7 +23,7 @@ function loadInstructions() {
23
23
  }
24
24
  }
25
25
  const INSTRUCTIONS = loadInstructions();
26
- const VERSION = "0.9.2";
26
+ const VERSION = "0.10.1";
27
27
  export { INSTRUCTIONS as n, VERSION as t };
28
28
 
29
- //# sourceMappingURL=version-IB2ulmSy.js.map
29
+ //# sourceMappingURL=version-DoRPyhTL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version-IB2ulmSy.js","names":[],"sources":["../src/instructions.ts","../src/version.ts"],"sourcesContent":["/**\n * MCP Server Instructions\n *\n * These instructions are sent to Claude Desktop during initialization\n * and used as context/hints for the LLM. This ensures the AI agent\n * knows how to properly use the Productive.io MCP server.\n *\n * The content is derived from skills/SKILL.md (without YAML frontmatter).\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Load instructions from SKILL.md file\n * Removes YAML frontmatter (content between --- markers)\n */\nfunction loadInstructions(): string {\n try {\n // In dist/, go up to package root, then to skills/\n const skillPath = join(__dirname, '..', 'skills', 'SKILL.md');\n const content = readFileSync(skillPath, 'utf-8');\n\n // Remove YAML frontmatter (between --- markers at start of file)\n const withoutFrontmatter = content.replace(/^---\\n[\\s\\S]*?\\n---\\n+/, '');\n\n return withoutFrontmatter.trim();\n } catch {\n // Fallback if file not found (shouldn't happen in production)\n return 'Productive.io MCP Server - Use the productive tool with resource and action parameters.';\n }\n}\n\nexport const INSTRUCTIONS = loadInstructions();\n","/**\n * Package version - injected from package.json at build time\n */\ndeclare const __VERSION__: string;\nexport const VERSION = __VERSION__;\n"],"mappings":";;;;;;;;;;;;AAcA,IAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;;;;;AAMzD,SAAS,mBAA2B;AAClC,KAAI;AAQF,SALgB,aADE,KAAK,WAAW,MAAM,UAAU,WAAW,EACrB,QAAQ,CAGb,QAAQ,0BAA0B,GAAG,CAE9C,MAAM;SAC1B;AAEN,SAAO;;;AAIX,MAAa,eAAe,kBAAkB;AChC9C,MAAa,UAAA"}
1
+ {"version":3,"file":"version-DoRPyhTL.js","names":[],"sources":["../src/instructions.ts","../src/version.ts"],"sourcesContent":["/**\n * MCP Server Instructions\n *\n * These instructions are sent to Claude Desktop during initialization\n * and used as context/hints for the LLM. This ensures the AI agent\n * knows how to properly use the Productive.io MCP server.\n *\n * The content is derived from skills/SKILL.md (without YAML frontmatter).\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Load instructions from SKILL.md file\n * Removes YAML frontmatter (content between --- markers)\n */\nfunction loadInstructions(): string {\n try {\n // In dist/, go up to package root, then to skills/\n const skillPath = join(__dirname, '..', 'skills', 'SKILL.md');\n const content = readFileSync(skillPath, 'utf-8');\n\n // Remove YAML frontmatter (between --- markers at start of file)\n const withoutFrontmatter = content.replace(/^---\\n[\\s\\S]*?\\n---\\n+/, '');\n\n return withoutFrontmatter.trim();\n } catch {\n // Fallback if file not found (shouldn't happen in production)\n return 'Productive.io MCP Server - Use the productive tool with resource and action parameters.';\n }\n}\n\nexport const INSTRUCTIONS = loadInstructions();\n","/**\n * Package version - injected from package.json at build time\n */\ndeclare const __VERSION__: string;\nexport const VERSION = __VERSION__;\n"],"mappings":";;;;;;;;;;;;AAcA,IAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;;;;;AAMzD,SAAS,mBAA2B;AAClC,KAAI;AAQF,SALgB,aADE,KAAK,WAAW,MAAM,UAAU,WAAW,EACrB,QAAQ,CAGb,QAAQ,0BAA0B,GAAG,CAE9C,MAAM;SAC1B;AAEN,SAAO;;;AAIX,MAAa,eAAe,kBAAkB;AChC9C,MAAa,UAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/productive-mcp",
3
- "version": "0.9.2",
3
+ "version": "0.10.1",
4
4
  "description": "MCP server for Productive.io API - Model Context Protocol integration for Claude Desktop",
5
5
  "keywords": [
6
6
  "ai",
@@ -87,8 +87,8 @@
87
87
  },
88
88
  "dependencies": {
89
89
  "@modelcontextprotocol/sdk": "^1.26.0",
90
- "@studiometa/productive-api": "0.9.2",
91
- "@studiometa/productive-core": "0.9.2",
90
+ "@studiometa/productive-api": "0.10.1",
91
+ "@studiometa/productive-core": "0.10.1",
92
92
  "h3": "^1.15.1",
93
93
  "zod": "4.3.6"
94
94
  },
package/skills/SKILL.md CHANGED
@@ -7,6 +7,10 @@ description: MCP server for Productive.io - use with Claude Desktop or MCP-compa
7
7
 
8
8
  MCP (Model Context Protocol) server for Productive.io. Provides a single unified tool for all operations.
9
9
 
10
+ ## Quick Start
11
+
12
+ Before your first interaction with any resource, call `action=help` with that resource to discover valid filters, required fields, includes, and examples.
13
+
10
14
  ## The `productive` Tool
11
15
 
12
16
  Single unified tool with this signature:
@@ -17,36 +21,35 @@ productive(resource, action, [parameters...])
17
21
 
18
22
  ### Resources & Actions
19
23
 
20
- | Resource | Actions | Description |
21
- | ------------- | ------------------------------------------------------------------------ | ----------------------- |
22
- | `projects` | `list`, `get`, `resolve`, `help` | Project management |
23
- | `time` | `list`, `get`, `create`, `update`, `resolve`, `help` | Time tracking |
24
- | `tasks` | `list`, `get`, `create`, `update`, `resolve`, `help` | Task management |
25
- | `services` | `list`, `get`, `resolve`, `help` | Budget line items |
26
- | `people` | `list`, `get`, `me`, `resolve`, `help` | Team members |
27
- | `companies` | `list`, `get`, `create`, `update`, `resolve`, `help` | Client companies |
28
- | `comments` | `list`, `get`, `create`, `update`, `help` | Comments on tasks/deals |
29
- | `attachments` | `list`, `get`, `delete`, `help` | File attachments |
30
- | `timers` | `list`, `get`, `start`, `stop`, `help` | Active timers |
31
- | `deals` | `list`, `get`, `create`, `update`, `resolve`, `help` | Sales deals |
32
- | `bookings` | `list`, `get`, `create`, `update`, `help` | Resource scheduling |
33
- | `budgets` | `list`, `get`, `help` | Budget tracking |
34
- | `reports` | `get`, `help` | Generate reports |
35
- | Resource | Actions | Description |
36
- | ------------- | ------------------------------------------------------------------------ | ----------------------- |
37
- | `projects` | `list`, `get`, `resolve`, `help` | Project management |
38
- | `time` | `list`, `get`, `create`, `update`, `resolve`, `help` | Time tracking |
39
- | `tasks` | `list`, `get`, `create`, `update`, `resolve`, `help` | Task management |
40
- | `services` | `list`, `get`, `resolve`, `help` | Budget line items |
41
- | `people` | `list`, `get`, `me`, `resolve`, `help` | Team members |
42
- | `companies` | `list`, `get`, `create`, `update`, `resolve`, `help` | Client companies |
43
- | `comments` | `list`, `get`, `create`, `update`, `help` | Comments on tasks/deals |
44
- | `timers` | `list`, `get`, `start`, `stop`, `help` | Active timers |
45
- | `deals` | `list`, `get`, `create`, `update`, `resolve`, `help` | Sales deals |
46
- | `bookings` | `list`, `get`, `create`, `update`, `help` | Resource scheduling |
47
- | `pages` | `list`, `get`, `create`, `update`, `delete`, `help` | Wiki/docs pages |
48
- | `discussions` | `list`, `get`, `create`, `update`, `delete`, `resolve`, `reopen`, `help` | Discussions on pages |
49
- | `reports` | `get`, `help` | Generate reports |
24
+ | Resource | Actions | Description |
25
+ | ------------- | ------------------------------------------------------------------------ | -------------------------------------------------------- |
26
+ | `projects` | `list`, `get`, `resolve`, `help` | Project management |
27
+ | `time` | `list`, `get`, `create`, `update`, `resolve`, `help` | Time tracking |
28
+ | `tasks` | `list`, `get`, `create`, `update`, `resolve`, `help` | Task management |
29
+ | `services` | `list`, `get`, `resolve`, `help` | Budget line items |
30
+ | `people` | `list`, `get`, `me`, `resolve`, `help` | Team members |
31
+ | `companies` | `list`, `get`, `create`, `update`, `resolve`, `help` | Client companies |
32
+ | `comments` | `list`, `get`, `create`, `update`, `help` | Comments on tasks/deals |
33
+ | `attachments` | `list`, `get`, `delete`, `help` | File attachments |
34
+ | `timers` | `list`, `get`, `start`, `stop`, `help` | Active timers |
35
+ | `deals` | `list`, `get`, `create`, `update`, `resolve`, `help` | Sales deals & budgets (use `filter[type]=2` for budgets) |
36
+ | `bookings` | `list`, `get`, `create`, `update`, `help` | Resource scheduling |
37
+ | `reports` | `get`, `help` | Generate reports |
38
+ | Resource | Actions | Description |
39
+ | ------------- | ------------------------------------------------------------------------ | ----------------------- |
40
+ | `projects` | `list`, `get`, `resolve`, `help` | Project management |
41
+ | `time` | `list`, `get`, `create`, `update`, `resolve`, `help` | Time tracking |
42
+ | `tasks` | `list`, `get`, `create`, `update`, `resolve`, `help` | Task management |
43
+ | `services` | `list`, `get`, `resolve`, `help` | Budget line items |
44
+ | `people` | `list`, `get`, `me`, `resolve`, `help` | Team members |
45
+ | `companies` | `list`, `get`, `create`, `update`, `resolve`, `help` | Client companies |
46
+ | `comments` | `list`, `get`, `create`, `update`, `help` | Comments on tasks/deals |
47
+ | `timers` | `list`, `get`, `start`, `stop`, `help` | Active timers |
48
+ | `deals` | `list`, `get`, `create`, `update`, `resolve`, `help` | Sales deals & budgets |
49
+ | `bookings` | `list`, `get`, `create`, `update`, `help` | Resource scheduling |
50
+ | `pages` | `list`, `get`, `create`, `update`, `delete`, `help` | Wiki/docs pages |
51
+ | `discussions` | `list`, `get`, `create`, `update`, `delete`, `resolve`, `reopen`, `help` | Discussions on pages |
52
+ | `reports` | `get`, `help` | Generate reports |
50
53
 
51
54
  ### Getting Help
52
55
 
@@ -302,22 +305,6 @@ Response:
302
305
  { "resource": "timers", "action": "stop", "id": "67890" }
303
306
  ```
304
307
 
305
- ### Budgets
306
-
307
- ```json
308
- // List all budgets
309
- { "resource": "budgets", "action": "list" }
310
-
311
- // List budgets for a project
312
- { "resource": "budgets", "action": "list", "filter": { "project_id": "12345" } }
313
-
314
- // Get budget details
315
- { "resource": "budgets", "action": "get", "id": "67890" }
316
-
317
- // List billable budgets
318
- { "resource": "budgets", "action": "list", "filter": { "billable": "true" } }
319
- ```
320
-
321
308
  ### Reports
322
309
 
323
310
  ```json
@@ -465,6 +452,8 @@ Response:
465
452
  - `type` - Type: `1`=deal, `2`=budget
466
453
  - `budget_status` - Budget status: `1`=open, `2`=closed
467
454
 
455
+ > **Note:** Budgets are deals with `budget=true`. There is no separate `/budgets` endpoint. Use `filter[type]=2` to list only budgets.
456
+
468
457
  ### Bookings
469
458
 
470
459
  - `person_id` - Filter by person
@@ -476,14 +465,6 @@ Response:
476
465
  - `booking_type` - Type: `event` (absence) or `service` (budget)
477
466
  - `draft` - Tentative status: `true`/`false`
478
467
 
479
- ### Budgets
480
-
481
- - `project_id` - Filter by project
482
- - `company_id` - Filter by company
483
- - `deal_id` - Filter by deal
484
- - `billable` - Filter by billable status: `true`/`false`
485
- - `budget_type` - Filter by budget type
486
-
487
468
  ### Pages
488
469
 
489
470
  - `project_id` - Filter by project
@@ -1,9 +0,0 @@
1
- /**
2
- * Budgets MCP handler.
3
- *
4
- * Thin adapter that delegates business logic to core executors
5
- * and handles MCP-specific concerns (hints, error formatting, JSON results).
6
- */
7
- import type { CommonArgs, HandlerContext, ToolResult } from './types.js';
8
- export declare function handleBudgets(action: string, args: CommonArgs, ctx: HandlerContext): Promise<ToolResult>;
9
- //# sourceMappingURL=budgets.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../../src/handlers/budgets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASzE,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,UAAU,CAAC,CAiCrB"}