pipebrain-mcp 0.43.1 → 0.44.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 +48 -1
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -16622,6 +16622,30 @@ var ApiClient = class _ApiClient {
16622
16622
  timeoutMs: this.timeoutMs
16623
16623
  });
16624
16624
  }
16625
+ /**
16626
+ * The inverse of {@link forOrg}: a thin copy that stamps NO `X-Org-Id`, for the
16627
+ * org-INDEPENDENT routes named above.
16628
+ *
16629
+ * IT EXISTS BECAUSE A BASE CLIENT IS NOT ALWAYS UNSCOPED. The rule above assumes the
16630
+ * caller reaches those routes through the client it started with, which holds for the
16631
+ * web application. It does not hold for `pipebrain-mcp`, which scopes its client ONCE at
16632
+ * startup from `PIPEBRAIN_ORG` and hands that scoped client to the tool registry as its
16633
+ * base — so an org-independent call made there carries a header anyway.
16634
+ *
16635
+ * That is harmless while the default is good and actively harmful when it is not. A
16636
+ * default naming an organization its holder has since been removed from makes EVERY call
16637
+ * of that session refuse, including the one call whose whole purpose is to tell the
16638
+ * caller which organizations it may name instead. Asking that question has to work from
16639
+ * inside the broken state, or it does not help in the only case it is needed.
16640
+ */
16641
+ unscoped() {
16642
+ return new _ApiClient({
16643
+ baseUrl: this.baseUrl,
16644
+ auth: this.auth,
16645
+ fetch: this.fetchImpl,
16646
+ timeoutMs: this.timeoutMs
16647
+ });
16648
+ }
16625
16649
  // --- core ------------------------------------------------------------------
16626
16650
  /** Builds the auth + active-org headers for the configured mode. */
16627
16651
  authHeaders() {
@@ -17628,6 +17652,29 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
17628
17652
  })
17629
17653
  );
17630
17654
  }
17655
+ registerStrict("list_orgs", {
17656
+ description: "List the organizations this credential may act in \u2014 each with its name, slug, id, kind (personal or shared) and your role there. THIS IS THE ONE TOOL THAT NEEDS NO `org`: every other call names the organization it acts in and is refused if it names none, and this is how you find out which names you may use. The answer is your live memberships at this moment, which is exactly what that check tests against, so an organization you have just joined appears here and one you have been removed from does not (\xA77)."
17657
+ // NO inputSchema, and the absence is the point rather than an omission. There is
17658
+ // nothing to narrow: the answer is the caller's own memberships, and a filter over a
17659
+ // list this short would be a second way to ask one question.
17660
+ }, () => (
17661
+ // A BARE ARRAY, unlike `list_waiting`'s `{ items }`, and for the reason that tool
17662
+ // gives rather than against it: the envelope has already been unwrapped by
17663
+ // `ApiClient.listOrgs`, so passing it through is what avoids deciding the shape a
17664
+ // second time. The sibling list tools return bare arrays for the same reason.
17665
+ //
17666
+ // `.unscoped()` IS LOAD-BEARING, and this is the only tool that uses it. Every other
17667
+ // tool wants whatever scope is in force; this one must have none, because it is the
17668
+ // tool a caller reaches for when the scope in force is the problem. Two ways in:
17669
+ // a call naming an organization the caller cannot use, and — worse, because the
17670
+ // caller names nothing at all — a stdio server started with a `PIPEBRAIN_ORG` whose
17671
+ // organization its holder has since left, which scopes the registry's base client
17672
+ // once at startup. In either state every other call refuses, and without this the
17673
+ // one call that could say which organizations ARE available refuses along with them.
17674
+ // The answer does not depend on scope, so dropping it costs nothing and is what
17675
+ // makes the tool's own description true.
17676
+ run(() => client2().unscoped().listOrgs(), GUIDANCE_POINTER)
17677
+ ));
17631
17678
  registerStrict("list_projects", {
17632
17679
  description: "List all projects with their key, environments, milestones (token, label, active), deliverable targets (slug, label, active), and open-issue counts \u2014 the project switcher and workflow entry point (\xA77).",
17633
17680
  // Optional pagination (§9) — bounds mirror list_issues/list_requirements; the
@@ -18246,7 +18293,7 @@ function loadMcpConfig() {
18246
18293
  }
18247
18294
 
18248
18295
  // src/version.ts
18249
- var VERSION = "0.43.1";
18296
+ var VERSION = "0.44.0";
18250
18297
 
18251
18298
  // src/main.ts
18252
18299
  async function scopedClient(base, org) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipebrain-mcp",
3
- "version": "0.43.1",
3
+ "version": "0.44.0",
4
4
  "description": "Pipebrain MCP server for Claude Code and Claude Desktop — issues, requirements, decision records, conventions, prompts, content, assets, metadata-only secrets, and more of the platform's modules over the Pipebrain API.",
5
5
  "type": "module",
6
6
  "license": "MIT",