@aioproductoscom/mcp 0.15.3 → 0.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -48,6 +48,18 @@ export class PlatformClient {
48
48
  createTask(body) {
49
49
  return this.req("/api/pm/tasks", { method: "POST", body: JSON.stringify(body) });
50
50
  }
51
+ createFeature(body) {
52
+ return this.req("/api/me/features", { method: "POST", body: JSON.stringify(body) });
53
+ }
54
+ createObjective(body) {
55
+ return this.req("/api/me/objectives", { method: "POST", body: JSON.stringify(body) });
56
+ }
57
+ createSprint(body) {
58
+ return this.req("/api/me/sprints", { method: "POST", body: JSON.stringify(body) });
59
+ }
60
+ createPage(body) {
61
+ return this.req("/api/me/pages", { method: "POST", body: JSON.stringify(body) });
62
+ }
51
63
  updateTask(id, body) {
52
64
  return this.req(`/api/pm/tasks/${encodeURIComponent(id)}`, { method: "PATCH", body: JSON.stringify(body) });
53
65
  }
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ function text(data) {
23
23
  function promptMsg(body) {
24
24
  return { messages: [{ role: "user", content: { type: "text", text: body } }] };
25
25
  }
26
- const server = new McpServer({ name: "AIOProductOS", version: "0.15.3" }, {
26
+ const server = new McpServer({ name: "AIOProductOS", version: "0.15.4" }, {
27
27
  instructions: "You manage product work on AIOProductOS for the connected member — board, insights, features, and " +
28
28
  "analytics all hang off one spine. Call get_pm_playbook first for how to operate: ground in " +
29
29
  "get_product_brain, keep work tied to the spine (insight→feature→task→outcome), and prioritize on " +
@@ -49,6 +49,41 @@ server.tool("create_task", "Create a task and return the created task. A write
49
49
  insight_id: z.string().optional().describe("Link to an insight (optional)."),
50
50
  assignee_member_ids: z.array(z.string()).optional().describe("Member ids to assign, from pm_meta (optional)."),
51
51
  }, async (a) => text(await client.createTask(a)));
52
+ server.tool("create_feature", "Create a feature on the product spine and return it (id, key, name, status). The key is generated from the name; status starts 'active'. product_id defaults to the org's primary product when omitted — pass one from whoami for a multi-product org. Only name is required; create the feature before linking tasks to it with create_task.", {
53
+ name: z.string().describe("Feature name (the only required field), e.g. 'SAML SSO'."),
54
+ description: z.string().optional().describe("What the feature is / why it matters (optional)."),
55
+ product_id: z.string().optional().describe("Product to create it under, from whoami (optional; the org's primary product when omitted)."),
56
+ }, async (a) => text(await client.createFeature(a)));
57
+ server.tool("create_objective", "Create an objective (OKR), optionally with key results, and return it. period is free text (e.g. 'Q3 2026'); product_id and parent_id (a parent objective) are optional and verified in-org. Each key result takes name + optional unit / start_value / target_value. Only name is required.", {
58
+ name: z.string().describe("Objective name (the only required field), e.g. 'Reach $50k MRR'."),
59
+ description: z.string().optional().describe("Context for the objective (optional)."),
60
+ period: z.string().optional().describe("Free-text period, e.g. 'Q3 2026' (optional)."),
61
+ product_id: z.string().optional().describe("Product to scope it to, from whoami (optional)."),
62
+ parent_id: z.string().optional().describe("Parent objective id to nest under (optional)."),
63
+ key_results: z
64
+ .array(z.object({
65
+ name: z.string().describe("Key result name, e.g. 'MRR'."),
66
+ unit: z.string().optional().describe("Unit, e.g. 'USD' or '%' (optional)."),
67
+ start_value: z.number().optional().describe("Starting value (optional; default 0)."),
68
+ target_value: z.number().optional().describe("Target value (optional)."),
69
+ }))
70
+ .optional()
71
+ .describe("Key results to attach (optional; up to 10)."),
72
+ }, async (a) => text(await client.createObjective(a)));
73
+ server.tool("create_sprint", "Create a sprint and return it (id, name, goal, state, dates). state is 'future' (default) or 'active'; start_date / end_date are optional ISO 8601. Only name is required. Schedule tasks into it by passing the returned sprint id as sprint_id on create_task / update_task.", {
74
+ name: z.string().describe("Sprint name (the only required field), e.g. 'Sprint 12'."),
75
+ goal: z.string().optional().describe("The sprint goal (optional)."),
76
+ state: z.enum(["future", "active"]).optional().describe("Lifecycle state (optional; default 'future')."),
77
+ start_date: z.string().optional().describe("Start, ISO 8601 e.g. '2026-07-15T00:00:00Z' (optional)."),
78
+ end_date: z.string().optional().describe("End, ISO 8601 (optional)."),
79
+ }, async (a) => text(await client.createSprint(a)));
80
+ server.tool("create_page", "Create a Page (in-product doc / PRD on the spine) and return it (id, title). `body` is plain text — blank-line-separated blocks become paragraphs; omit it for a blank page. title defaults to 'Untitled'. product_id / parent_id (a parent page) are optional and verified in-org.", {
81
+ title: z.string().optional().describe("Page title (optional; 'Untitled' when omitted)."),
82
+ body: z.string().optional().describe("Page content as plain text; blank lines separate paragraphs (optional)."),
83
+ icon: z.string().optional().describe("An emoji icon for the page (optional)."),
84
+ product_id: z.string().optional().describe("Product to scope it to, from whoami (optional)."),
85
+ parent_id: z.string().optional().describe("Parent page id to nest under (optional)."),
86
+ }, async (a) => text(await client.createPage(a)));
52
87
  server.tool("update_task", "Update one or more of a task's fields and return the updated task; fields you omit are left unchanged (idempotent — re-sending the same values is a no-op), and passing null clears a nullable field. Resolve ids first — the task via list_tasks/get_task, and status/feature/insight/member ids via pm_meta — never guess them. Only id is required.", {
53
88
  id: z.string().describe("Task id, from list_tasks or get_task."),
54
89
  title: z.string().optional().describe("New title (optional)."),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aioproductoscom/mcp",
3
- "version": "0.15.3",
3
+ "version": "0.15.4",
4
4
  "mcpName": "com.aioproductos/mcp",
5
5
  "description": "AIOProductOS MCP — manage the board, read your product brain + analytics, and run the support inbox from Claude Code, Cursor, Codex, and any MCP host.",
6
6
  "type": "module",