@glie/mcp-polaris 0.1.0 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +53 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@
5
5
  import { createInterface } from "readline";
6
6
  var BASE = process.env.POLARIS_URL ?? "http://127.0.0.1:7843";
7
7
  var TOKEN = process.env.POLARIS_TOKEN ?? "";
8
+ var PROJECT = process.env.POLARIS_PROJECT ?? "";
8
9
  var log = (msg, ctx) => process.stderr.write(`mcp-polaris: ${msg}${ctx ? ` ${JSON.stringify(ctx)}` : ""}
9
10
  `);
10
11
  async function apiCall(method, path, body) {
@@ -41,10 +42,38 @@ function objSchema(properties, required = []) {
41
42
  additionalProperties: false
42
43
  };
43
44
  }
45
+ var INSTRUCTIONS = [
46
+ `Polaris is the studio's operating system. All product work lives as Projects \u2192 Milestones \u2192 Tasks, and agents ("employees") move it forward. Each polaris.* tool wraps one REST call.`,
47
+ PROJECT ? `You are scoped to project \`${PROJECT}\` \u2014 use it as project_key/product_key unless told otherwise.` : "This connector is not pinned to a project; use polaris.project.list to find yours.",
48
+ "",
49
+ "START HERE \u2014 get what is YOURS (resolved from your token, no id lookup needed):",
50
+ '\u2022 agent \u2192 polaris.task.list { assignee_agent_id: "self" }',
51
+ '\u2022 human \u2192 polaris.task.list { assignee_human_id: "self" } (and polaris.me for your identity)',
52
+ " Narrow with status (e.g. dev) once you know what's assigned to you.",
53
+ "\u2022 polaris.claude_md.get(project_key) \u2014 read the project's conventions BEFORE you touch its tasks.",
54
+ "",
55
+ "STATE MACHINES \u2014 transitions are enforced; only legal moves succeed:",
56
+ "\u2022 Task: draft \u2192 backlog \u2192 dev \u2192 test \u2192 approval \u2192 release \u2192 done (any \u2192 canceled)",
57
+ " dev = an agent implements it & opens a PR \xB7 test = QA \xB7 approval = a human reviews \xB7 release = merged to dev/shipped.",
58
+ "\u2022 Milestone: draft \u2192 discovery \u2192 loop \u2192 release \u2192 done (any \u2192 canceled)",
59
+ " discovery = answer the framework Q&A to split it into tasks \xB7 loop = build/test/approve \xB7 release = ship.",
60
+ "\u2022 Stack (Release Candidate): 2+ approval tasks of ONE milestone on an rc branch, tested & shipped together \u2014",
61
+ " liquid (assembling) \u2192 blocked (a member conflicts) | frozen (human-resolved) \u2192 released (any \u2192 canceled).",
62
+ "",
63
+ "WHICH TOOL WHEN:",
64
+ `\u2022 "What's mine / what next?" \u2192 polaris.task.list (assignee \u2026="self", status=\u2026)`,
65
+ '\u2022 "Read X in full" \u2192 polaris.task.get \xB7 milestone.get \xB7 project.get \xB7 stack.get',
66
+ '\u2022 "Move my task forward" \u2192 polaris.task.transition(id, status)',
67
+ `\u2022 "It's reviewed, ship it" \u2192 polaris.task.approve (human-only); ship several together via polaris.stack.* \u2192 stack.release`,
68
+ '\u2022 "Break a milestone into tasks" \u2192 polaris.milestone.qa_list / qa_answer (while in discovery)',
69
+ "",
70
+ "Identifiers: projects by `key` (string, e.g. saasA); milestones/tasks/agents/stacks by numeric `id`. Writes need a token; reads work anonymously."
71
+ ].join(`
72
+ `);
44
73
  var TOOLS = [
45
74
  {
46
75
  name: "polaris.me",
47
- description: "Get the current authenticated human (PAT owner).",
76
+ description: `Resolve the human your PAT belongs to (identity + org). Humans call this first; agents don't need it \u2014 they pass "self" to other tools.`,
48
77
  inputSchema: objSchema({}),
49
78
  call: async () => {
50
79
  const r = await apiCall("GET", "/api/humans/me");
@@ -121,17 +150,27 @@ var TOOLS = [
121
150
  },
122
151
  {
123
152
  name: "polaris.task.list",
124
- description: "List tasks across milestones. Filter by status/product/team/assignee.",
153
+ description: `Find tasks \u2014 the agent's entry point. Pass assignee_agent_id="self" (or assignee_human_id="self" for a human) to get what is YOURS; add status=dev (etc.) to see only active work. Other filters: milestone_id, product_key, team.`,
125
154
  inputSchema: objSchema({
126
- status: strSchema("comma-separated: backlog,dev,test,..."),
155
+ status: strSchema("comma-separated subset of: draft,backlog,dev,test,approval,release,done,canceled"),
127
156
  milestone_id: intSchema(),
128
- product_key: strSchema(),
157
+ product_key: strSchema("project key, e.g. saasA"),
129
158
  team: strSchema("dev|mkt"),
159
+ assignee_agent_id: strSchema('agent id, or "self" for the calling agent'),
160
+ assignee_human_id: strSchema('human id, or "self" for the calling human'),
130
161
  limit: intSchema()
131
162
  }),
132
163
  call: async (args) => {
133
164
  const qs = new URLSearchParams;
134
- for (const k of ["status", "milestone_id", "product_key", "team", "limit"]) {
165
+ for (const k of [
166
+ "status",
167
+ "milestone_id",
168
+ "product_key",
169
+ "team",
170
+ "assignee_agent_id",
171
+ "assignee_human_id",
172
+ "limit"
173
+ ]) {
135
174
  const v = args[k];
136
175
  if (v !== undefined && v !== null)
137
176
  qs.set(k, String(v));
@@ -154,13 +193,13 @@ var TOOLS = [
154
193
  },
155
194
  {
156
195
  name: "polaris.task.transition",
157
- description: "Transition task status (state machine enforced).",
196
+ description: "Move a task to its next status when you finish a stage (e.g. dev\u2192test once your PR is up). Enforced flow: draft\u2192backlog\u2192dev\u2192test\u2192approval\u2192release\u2192done (any\u2192canceled). Illegal jumps are rejected. The approval\u2192release gate is polaris.task.approve (human-only).",
158
197
  inputSchema: objSchema({ id: intSchema(), status: strSchema() }, ["id", "status"]),
159
198
  call: async (args) => (await apiCall("POST", `/api/tasks/${args.id}/state`, { status: args.status })).body
160
199
  },
161
200
  {
162
201
  name: "polaris.task.approve",
163
- description: "Approve a task in approval state (human-only).",
202
+ description: "The human review gate: approve a task in `approval` \u2192 it advances toward release. Human-only. To ship several approval tasks of one milestone together, group them into a stack and use polaris.stack.release instead.",
164
203
  inputSchema: objSchema({ id: intSchema() }, ["id"]),
165
204
  call: async (args) => (await apiCall("POST", `/api/tasks/${args.id}/approve`)).body
166
205
  },
@@ -178,8 +217,8 @@ var TOOLS = [
178
217
  },
179
218
  {
180
219
  name: "polaris.stack.list",
181
- description: "List approval stacks (Release Candidates). Filter by status: liquid|frozen|released|canceled.",
182
- inputSchema: objSchema({ status: strSchema("liquid|frozen|released|canceled") }),
220
+ description: "List Release-Candidate stacks (groups of approval tasks shipped together). Filter by status: liquid|blocked|frozen|released|canceled.",
221
+ inputSchema: objSchema({ status: strSchema("liquid|blocked|frozen|released|canceled") }),
183
222
  call: async (args) => {
184
223
  const qs = typeof args.status === "string" ? `?status=${encodeURIComponent(args.status)}` : "";
185
224
  return (await apiCall("GET", `/api/stacks${qs}`)).body;
@@ -187,22 +226,16 @@ var TOOLS = [
187
226
  },
188
227
  {
189
228
  name: "polaris.stack.get",
190
- description: "Get one approval stack by id \u2014 includes its member tasks and the rc integration branch.",
229
+ description: "Inspect one stack by id \u2014 its member tasks, the rc branch + PR, and (when blocked) which member failed to integrate and why.",
191
230
  inputSchema: objSchema({ id: intSchema() }, ["id"]),
192
231
  call: async (args) => (await apiCall("GET", `/api/stacks/${args.id}`)).body
193
232
  },
194
233
  {
195
234
  name: "polaris.stack.release",
196
- description: "Release a stack \u2014 merge its rc branch to dev and settle members to release (human-only).",
235
+ description: "Ship a stack \u2014 merge its rc PR into dev, settle members to release, then close & delete the member branches (their commits land via the rc). Human-only; barred while blocked.",
197
236
  inputSchema: objSchema({ id: intSchema() }, ["id"]),
198
237
  call: async (args) => (await apiCall("POST", `/api/stacks/${args.id}/release`)).body
199
238
  },
200
- {
201
- name: "polaris.stack.reject",
202
- description: "Reject a stack \u2014 return its member tasks to their prior state (human-only).",
203
- inputSchema: objSchema({ id: intSchema() }, ["id"]),
204
- call: async (args) => (await apiCall("POST", `/api/stacks/${args.id}/reject`)).body
205
- },
206
239
  {
207
240
  name: "polaris.agent.list",
208
241
  description: "List agents.",
@@ -223,7 +256,7 @@ var TOOLS = [
223
256
  },
224
257
  {
225
258
  name: "polaris.claude_md.get",
226
- description: "Read the CLAUDE.md of a project (via polaris-bot).",
259
+ description: "Read a project's CLAUDE.md \u2014 its conventions, stack and rules (served from main via polaris-bot). Do this BEFORE working that project's tasks.",
227
260
  inputSchema: objSchema({ project_key: strSchema() }, ["project_key"]),
228
261
  call: async (args) => (await apiCall("GET", `/api/projects/${args.project_key}/claude-md`)).body
229
262
  },
@@ -252,7 +285,8 @@ async function handle(req) {
252
285
  return ok(id, {
253
286
  protocolVersion: "2024-11-05",
254
287
  capabilities: { tools: {} },
255
- serverInfo: { name: "mcp-polaris", version: "0.1.0" }
288
+ serverInfo: { name: "mcp-polaris", version: "0.1.0" },
289
+ instructions: INSTRUCTIONS
256
290
  });
257
291
  case "initialized":
258
292
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glie/mcp-polaris",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Model Context Protocol (stdio) server exposing Polaris — glie's ops platform — as native tools in Claude Code and any MCP client.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "glie <carlos@glie.ai>",