pipebrain-mcp 0.20.0 → 0.22.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/main.js +39 -4
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -15640,6 +15640,12 @@ var setStatusInputSchema = external_exports.strictObject({
15640
15640
  issue: issueRefSchema,
15641
15641
  status: issueStatusSchema
15642
15642
  });
15643
+ var getWorkContextInputSchema = external_exports.strictObject({
15644
+ issue: issueRefSchema.optional(),
15645
+ project: projectRefSchema.optional()
15646
+ }).refine((v) => v.issue === void 0 !== (v.project === void 0), {
15647
+ message: "pass exactly one of `issue` or `project` \u2014 an issue names its own project, and passing neither names nothing to read"
15648
+ });
15643
15649
  var claimInputSchema = external_exports.strictObject({
15644
15650
  issue: issueRefSchema
15645
15651
  });
@@ -16563,6 +16569,22 @@ var ApiClient = class _ApiClient {
16563
16569
  const query = filter?.mine === true ? { mine: "1" } : void 0;
16564
16570
  return this.requestList("GET", "/api/v1/waiting", { query });
16565
16571
  }
16572
+ // --- the working-context pack ----------------------------------------------
16573
+ /**
16574
+ * Everything a session needs before it starts work, in ONE read (PIPE-86): the
16575
+ * item, the documents that bind it AT THE REVISION IT WAS SPECIFIED AGAINST, the
16576
+ * project's cross-cutting requirements and the release being worked — or, given a
16577
+ * project, the work available to pick up instead.
16578
+ *
16579
+ * ONE method for two routes because they are two forms of one pack, decided by
16580
+ * which of `issue`/`project` is named — exactly one of them, as
16581
+ * `getWorkContextInputSchema` requires. The API assembles the pack and this computes
16582
+ * nothing of its own, so the browser, the command line and the agent read the same
16583
+ * answer.
16584
+ */
16585
+ getWorkContext(input) {
16586
+ return input.issue !== void 0 ? this.request("GET", `/api/v1/issues/${enc(input.issue)}/work-context`) : this.request("GET", `/api/v1/projects/${enc(input.project)}/work-context`);
16587
+ }
16566
16588
  // --- secrets ---------------------------------------------------------------
16567
16589
  // Metadata only: no method here returns a secret VALUE (the reveal plane is a
16568
16590
  // separate surface). Every response type is a `*View` with no `value` field.
@@ -16920,7 +16942,11 @@ async function resolveDeliverableTargetId(client2, projectKey, ref) {
16920
16942
  function createMcpServer(client2, apiBaseUrl, orgInstructions2 = /* @__PURE__ */ new Map(), opts = {}) {
16921
16943
  const surface = opts.surface ?? "local";
16922
16944
  const server2 = new McpServer({ name: "pipebrain", version: opts.version ?? DEFAULT_VERSION }, {
16923
- instructions: withGeneralInstructions(successorNotice() + `Pipebrain MCP server, bound to the ${apiBindingLabel(apiBaseUrl)} API at ${apiBaseUrl}. Every tool reads and writes THAT environment \u2014 confirm it is the one you intend (a local dev API vs production) before mutating. Tools are namespaced by this server's registration name in .mcp.json (e.g. pipebrain-local:* vs pipebrain:*).`, orgInstructions2)
16945
+ instructions: withGeneralInstructions(successorNotice() + `Pipebrain MCP server, bound to the ${apiBindingLabel(apiBaseUrl)} API at ${apiBaseUrl}. Every tool reads and writes THAT environment \u2014 confirm it is the one you intend (a local dev API vs production) before mutating. Tools are namespaced by this server's registration name in .mcp.json (e.g. pipebrain-local:* vs pipebrain:*).
16946
+
16947
+ Technical decisions are yours. Inside an approved requirement you choose the design, the libraries, the structure, and the sequencing. Do not ask, do not report the choice, and do not seek ratification for it. Escalate on consequence, not on uncertainty: a choice that changes what a user sees, costs money, or contradicts an approved requirement is filed as a question with the options you propose, and everything else you decide and carry on. A technical choice worth keeping is recorded as a decision record, never as a paragraph.
16948
+
16949
+ Every loose end has one destination, and none of them is prose. Anything you notice that is not the work in front of you goes to exactly one of three places: a question, when the operator has to choose; a new issue at triage, when it is real work outside this item\u2019s scope; or nowhere. Drop it unless it clears the bar for one of the first two \u2014 nowhere is the default, and it is the right outcome whenever knowing the thing would change nothing anyone does. Never open a section called notes, caveats, observations, things to know, or next steps in a body or a comment. Filing is the report: an item recorded and then repeated in prose asks the operator to triage it twice.`, orgInstructions2)
16924
16950
  });
16925
16951
  const registerTool = (name, config3, cb) => server2.registerTool(name, { ...config3, description: decorateDescription(name, config3.description ?? "", orgInstructions2) }, cb);
16926
16952
  registerTool("list_projects", {
@@ -16956,6 +16982,15 @@ function createMcpServer(client2, apiBaseUrl, orgInstructions2 = /* @__PURE__ */
16956
16982
  // makes that comparable at a glance.
16957
16983
  run(async () => ({ items: await client2.listWaiting() }))
16958
16984
  ));
16985
+ registerTool("get_work_context", {
16986
+ description: "Everything a session needs before it starts work, in ONE read \u2014 assembled by the API and returned verbatim. Addressed by `issue` OR by `project`, never both and never neither: an issue names its own project, so the pair is refused rather than resolved for you (\xA77). Given an ISSUE: that issue\u2019s full detail \u2014 the same payload `get_issue` returns \u2014 PLUS the BODY TEXT of every requirement it links, AT THE REVISION THE LINK IS PINNED AT. That text is the round trip this removes: `get_issue` names which documents bind the work and at which revision, never what they SAY, so a session that has read the issue still owes one fetch per link \u2014 and the one it skips leaves it building against rules it never read. Comments come CAPPED at the newest `commentLimit`, with `commentCount` \u2014 the issue\u2019s TRUE total \u2014 beside them, so a shortened list reads AS shortened rather than as the whole history; read the issue directly for the rest. Given a PROJECT: `available`, the work a session could START right now. It EXCLUDES finished and abandoned work (`done`, `killed`), work another person has claimed, and anything blocked \u2014 the status guard would refuse to start that, and offering work that cannot be started is offering a refusal. Your OWN claims stay, and so does unscheduled work carrying no milestone. The item form carries no `available`; the project form carries no item. BOTH forms also carry the project half: the release currently being worked (the active milestone) and the project\u2019s cross-cutting requirements WITH their text \u2014 they bind every epic automatically, and each is otherwise a separate call a session can simply forget to make. READ-ONLY \u2014 this claims nothing, moves nothing and writes nothing.",
16987
+ // The WHOLE domain schema rather than its `.shape`: the exactly-one-of rule is a
16988
+ // refinement on the OBJECT, and a raw shape drops it — the SDK validates against
16989
+ // what it is handed, so the shape alone would quietly accept both arguments and
16990
+ // neither. Handing it the schema lets its refusal reach the caller verbatim,
16991
+ // naming the two arguments it refused rather than a reworded stand-in.
16992
+ inputSchema: getWorkContextInputSchema
16993
+ }, (args) => run(() => client2.getWorkContext(args)));
16959
16994
  registerTool("create_milestone", {
16960
16995
  description: "Create a milestone on a project. `token` is the short ref issues point at via their `milestone` field (e.g. `M1`) and is unique per project (a duplicate is rejected); `label` is its display name (e.g. `Feature Verification`). Optional `position` orders it (0-based, defaults to last); optional `active` marks it the current milestone \u2014 AT MOST ONE milestone per project is active, so `active: true` transactionally DEMOTES the previously active one rather than failing. Returns the created milestone (\xA77).",
16961
16996
  inputSchema: {
@@ -17046,11 +17081,11 @@ function createMcpServer(client2, apiBaseUrl, orgInstructions2 = /* @__PURE__ */
17046
17081
  inputSchema: { issue: issueRefSchema }
17047
17082
  }, (args) => run(() => client2.getIssue(args.issue)));
17048
17083
  registerTool("create_issue", {
17049
- description: 'Create an issue (epic/task/bug/feedback). Omitted status defaults to triage (still subject to \xA76 guards); omitted environment resolves explicit \u2192 parent\u2019s environment \u2192 project default (prod). Optional parent (self/cycle rejected), priority, milestone, requirement_links (pins each at its approved revision; a target with no approved revision is rejected), deliverable_links (content deliverables like DWB-C3/bsky \u2014 pins each at its current revision; the promotion path), and ordered {text, verification, howTo} criteria (\xA77). A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9): work past triage belongs to a release, and the create is refused (`milestone_required`) without one. Search before you create: `list_issues` takes a `text` filter \u2014 run it on the distinctive nouns first. Sessions do not see each other, so a duplicate is invisible until someone finds both; on a near match, comment or amend the existing record rather than filing again. Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Before assigning any verification mode, establish what this project can drive end to end \u2014 an end-to-end test harness and the command that runs it. A criterion is `auto` when an evaluator can drive the input and read the result against the running system, which includes behavior shown in the interface wherever such a harness exists; the mode follows from what can be driven, not from where the behavior appears. What qualifies a criterion as `auto` is the evaluator\u2019s own run, never the existence of a test the implementer wrote. Mark `manual` only when the verdict needs a person\u2019s judgment; a criterion you cannot describe as drivable is usually worded too vaguely, so reword it against the observable rather than fall back to a person. A `manual` criterion must also carry `howTo` \u2014 one or two sentences, not an essay, saying where to look, what to do, and what counts as passing for whoever checks it by hand. Writing or changing one without it is refused (`how_to_required`); so is supplying it on an `auto` criterion, which a machine checks. Criteria live on epics only: a task cannot carry a criteria list and instead states in its own body what would count as done. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17084
+ description: 'Create an issue (epic/task/bug/feedback). Omitted status defaults to triage (still subject to \xA76 guards); omitted environment resolves explicit \u2192 parent\u2019s environment \u2192 project default (prod). Optional parent (self/cycle rejected), priority, milestone, requirement_links (pins each at its approved revision; a target with no approved revision is rejected), deliverable_links (content deliverables like DWB-C3/bsky \u2014 pins each at its current revision; the promotion path), and ordered {text, verification, howTo} criteria (\xA77). A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9): work past triage belongs to a release, and the create is refused (`milestone_required`) without one. Search before you create: `list_issues` takes a `text` filter \u2014 run it on the distinctive nouns first. Sessions do not see each other, so a duplicate is invisible until someone finds both; on a near match, comment or amend the existing record rather than filing again. The bar for filing a bug: file `type: bug` only when the observed behavior breaks an approved requirement or a defined acceptance criterion, and name which one before you file. If you cannot name one, this is not a bug \u2014 code you find unclear, an edge case nobody specified, a performance number nobody set, and anything you would phrase as "this could be better" are opinions about the product, so file each as `type: feedback`, or not at all. The bar exists because a queue holding both real defects and unshared taste has to be read entirely before any of it can be trusted. Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Before assigning any verification mode, establish what this project can drive end to end \u2014 an end-to-end test harness and the command that runs it. A criterion is `auto` when an evaluator can drive the input and read the result against the running system, which includes behavior shown in the interface wherever such a harness exists; the mode follows from what can be driven, not from where the behavior appears. What qualifies a criterion as `auto` is the evaluator\u2019s own run, never the existence of a test the implementer wrote. Mark `manual` only when the verdict needs a person\u2019s judgment; a criterion you cannot describe as drivable is usually worded too vaguely, so reword it against the observable rather than fall back to a person. A `manual` criterion must also carry `howTo` \u2014 one or two sentences, not an essay, saying where to look, what to do, and what counts as passing for whoever checks it by hand. Writing or changing one without it is refused (`how_to_required`); so is supplying it on an `auto` criterion, which a machine checks. Criteria live on epics only: a task cannot carry a criteria list and instead states in its own body what would count as done. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17050
17085
  inputSchema: createIssueInputSchema.shape
17051
17086
  }, (args) => run(() => client2.createIssue(args)));
17052
17087
  registerTool("promote_feedback", {
17053
- description: 'Promote a FEEDBACK issue into a NEW epic or task (PIPE-143): creates the issue in the feedback\u2019s project (`title` + `type` required; omitted environment inherits the FEEDBACK\u2019s environment, not the project default; optional status/body/priority/milestone/requirement_links/criteria as in create_issue), records the feedback as its permanent source (`promotedFrom`/`promotedTo` on both details), closes the feedback as done, and comments the new key on it. The feedback\u2019s own title/body are never touched \u2014 write the new issue\u2019s body as real work, do not paste the feedback in. Rejected (409) for non-feedback, terminal, or already-promoted sources. Returns the created issue. A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9), exactly as in create_issue; the SOURCE feedback needs none to be closed by the promotion. Search before you promote: `list_issues` takes a `text` filter \u2014 run it on the feedback\u2019s distinctive nouns first; an issue covering it may already exist, and sessions do not see each other. On a near match, comment on or amend the existing issue rather than promoting a duplicate. Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Before assigning any verification mode, establish what this project can drive end to end \u2014 an end-to-end test harness and the command that runs it. A criterion is `auto` when an evaluator can drive the input and read the result against the running system, which includes behavior shown in the interface wherever such a harness exists; the mode follows from what can be driven, not from where the behavior appears. What qualifies a criterion as `auto` is the evaluator\u2019s own run, never the existence of a test the implementer wrote. Mark `manual` only when the verdict needs a person\u2019s judgment; a criterion you cannot describe as drivable is usually worded too vaguely, so reword it against the observable rather than fall back to a person. A `manual` criterion must also carry `howTo` \u2014 one or two sentences, not an essay, saying where to look, what to do, and what counts as passing for whoever checks it by hand. Writing or changing one without it is refused (`how_to_required`); so is supplying it on an `auto` criterion, which a machine checks. Criteria live on epics only: a task cannot carry a criteria list and instead states in its own body what would count as done. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17088
+ description: 'Promote a FEEDBACK issue into a NEW epic or task (PIPE-143): creates the issue in the feedback\u2019s project (`title` + `type` required; omitted environment inherits the FEEDBACK\u2019s environment, not the project default; optional status/body/priority/milestone/requirement_links/criteria as in create_issue), records the feedback as its permanent source (`promotedFrom`/`promotedTo` on both details), closes the feedback as done, and comments the new key on it. The feedback\u2019s own title/body are never touched \u2014 write the new issue\u2019s body as real work, do not paste the feedback in. Rejected (409) for non-feedback, terminal, or already-promoted sources. Returns the created issue. A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9), exactly as in create_issue; the SOURCE feedback needs none to be closed by the promotion. Search before you promote: `list_issues` takes a `text` filter \u2014 run it on the feedback\u2019s distinctive nouns first; an issue covering it may already exist, and sessions do not see each other. On a near match, comment on or amend the existing issue rather than promoting a duplicate. The bar for promoting to a bug: choose `type: bug` only when the reported behavior breaks an approved requirement or a defined acceptance criterion, and name which one. If you cannot name one, promote it as `task` \u2014 or leave it as feedback. A queue holding both real defects and unshared taste has to be read entirely before any of it can be trusted. Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Before assigning any verification mode, establish what this project can drive end to end \u2014 an end-to-end test harness and the command that runs it. A criterion is `auto` when an evaluator can drive the input and read the result against the running system, which includes behavior shown in the interface wherever such a harness exists; the mode follows from what can be driven, not from where the behavior appears. What qualifies a criterion as `auto` is the evaluator\u2019s own run, never the existence of a test the implementer wrote. Mark `manual` only when the verdict needs a person\u2019s judgment; a criterion you cannot describe as drivable is usually worded too vaguely, so reword it against the observable rather than fall back to a person. A `manual` criterion must also carry `howTo` \u2014 one or two sentences, not an essay, saying where to look, what to do, and what counts as passing for whoever checks it by hand. Writing or changing one without it is refused (`how_to_required`); so is supplying it on an `auto` criterion, which a machine checks. Criteria live on epics only: a task cannot carry a criteria list and instead states in its own body what would count as done. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17054
17089
  inputSchema: {
17055
17090
  issue: external_exports.string().min(1),
17056
17091
  ...promoteFeedbackInputSchema.shape
@@ -17372,7 +17407,7 @@ function loadMcpConfig() {
17372
17407
  }
17373
17408
 
17374
17409
  // src/version.ts
17375
- var VERSION = "0.20.0";
17410
+ var VERSION = "0.22.0";
17376
17411
 
17377
17412
  // src/main.ts
17378
17413
  var config2 = loadMcpConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipebrain-mcp",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Pipebrain MCP server for Claude Code and Claude Desktop — issues, requirements, content, assets, and metadata-only secrets over the Pipebrain API.",
5
5
  "type": "module",
6
6
  "license": "MIT",