@featureflip/mcp 0.1.4 → 0.1.5

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.
@@ -0,0 +1,12 @@
1
+ import { ToolContext } from './tools/context.js';
2
+ /**
3
+ * Decides what the server serves before it starts.
4
+ *
5
+ * A configured token still preflights and still fails fast on a bad one — the
6
+ * startup error is unchanged. No token at all is a different situation: nobody
7
+ * has wired this up yet, and the caller may only be enumerating the tool surface,
8
+ * so we hand back a context that serves definitions and errors on use. Exiting
9
+ * there made the server indistinguishable from one with no tools.
10
+ */
11
+ export declare function resolveContext(env?: Record<string, string | undefined>, fetchImpl?: typeof fetch): Promise<ToolContext>;
12
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAyBtD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,SAAS,CAAC,EAAE,OAAO,KAAK,GACvB,OAAO,CAAC,WAAW,CAAC,CAGtB"}
package/dist/cli.mjs CHANGED
@@ -1,20 +1,51 @@
1
- import { a as e, i as t, n, r, t as i } from "./org-DsA8PUrd.js";
2
- import { serveStdio as a } from "@modelcontextprotocol/server/stdio";
3
- //#region src/cli.ts
4
- async function o() {
5
- let o = n(), s = new e(o);
1
+ import { a as e, i as t, n, o as r, s as i, t as a } from "./org-fuZ3wOph.js";
2
+ import { serveStdio as o } from "@modelcontextprotocol/server/stdio";
3
+ //#region src/unconfigured.ts
4
+ var s = class extends i {
5
+ constructor() {
6
+ super({
7
+ token: "",
8
+ baseUrl: "https://api.featureflip.io"
9
+ });
10
+ }
11
+ request() {
12
+ return Promise.reject(Error(n));
13
+ }
14
+ };
15
+ function c() {
16
+ return {
17
+ api: new s(),
18
+ org: ""
19
+ };
20
+ }
21
+ //#endregion
22
+ //#region src/bootstrap.ts
23
+ async function l(e, t) {
24
+ let n = new i({
25
+ ...e,
26
+ fetchImpl: t
27
+ });
6
28
  try {
7
- await s.request("GET", "/api/v1/me");
29
+ await n.request("GET", "/api/v1/me");
8
30
  } catch (e) {
9
- throw e instanceof t && e.status === 401 ? Error("FEATUREFLIP_TOKEN was rejected (401). Check the token in the Featureflip dashboard (Settings → API Tokens).") : e instanceof t && e.status === 404 ? Error("The public Management API returned 404 for /api/v1/me. This usually means the public API is not enabled for your organization yet — contact Featureflip support.") : e;
31
+ throw e instanceof r && e.status === 401 ? Error("FEATUREFLIP_TOKEN was rejected (401). Check the token in the Featureflip dashboard (Settings → API Tokens).") : e instanceof r && e.status === 404 ? Error("The public Management API returned 404 for /api/v1/me. This usually means the public API is not enabled for your organization yet — contact Featureflip support.") : e;
10
32
  }
11
- let c = await i(s, o.org);
12
- a(() => r({
13
- api: s,
14
- org: c
15
- }));
33
+ return {
34
+ api: n,
35
+ org: await a(n, e.org)
36
+ };
37
+ }
38
+ function u(e = process.env, n) {
39
+ let r = t(e);
40
+ return r ? l(r, n) : Promise.resolve(c());
41
+ }
42
+ //#endregion
43
+ //#region src/cli.ts
44
+ async function d() {
45
+ let t = await u();
46
+ o(() => e(t));
16
47
  }
17
- o().catch((e) => {
48
+ d().catch((e) => {
18
49
  console.error(`[featureflip-mcp] ${e instanceof Error ? e.message : String(e)}`), process.exit(1);
19
50
  });
20
51
  //#endregion
package/dist/config.d.ts CHANGED
@@ -3,5 +3,12 @@ export interface McpConfig {
3
3
  baseUrl: string;
4
4
  org?: string;
5
5
  }
6
+ export declare const MISSING_TOKEN_MESSAGE: string;
7
+ /**
8
+ * Returns null instead of throwing when no token is configured, so the server can
9
+ * still start and advertise its tool definitions to a client that is only
10
+ * inspecting the surface (registries, `tools/list` probes, first-run editors).
11
+ */
12
+ export declare function tryLoadConfig(env?: Record<string, string | undefined>): McpConfig | null;
6
13
  export declare function loadConfig(env?: Record<string, string | undefined>): McpConfig;
7
14
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,SAAS,CAY3F"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,qBAAqB,QAGO,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,SAAS,GAAG,IAAI,CAMrG;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,SAAS,CAI3F"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as e, i as t, n, o as r, r as i, t as a } from "./org-DsA8PUrd.js";
2
- export { t as ApiError, e as FeatureflipApi, r as PKG_VERSION, i as createServer, n as loadConfig, a as resolveOrg };
1
+ import { a as e, c as t, o as n, r, s as i, t as a } from "./org-fuZ3wOph.js";
2
+ export { n as ApiError, i as FeatureflipApi, t as PKG_VERSION, e as createServer, r as loadConfig, a as resolveOrg };
@@ -4,7 +4,7 @@ import * as t from "zod/v4";
4
4
  //#region src/version.ts
5
5
  var n = {
6
6
  name: "@featureflip/mcp",
7
- version: "0.1.4",
7
+ version: "0.1.5",
8
8
  mcpName: "io.github.canopy-labs/featureflip",
9
9
  description: "MCP server for managing Featureflip feature flags from AI agents and editors",
10
10
  license: "Apache-2.0",
@@ -31,15 +31,15 @@ var n = {
31
31
  },
32
32
  dependencies: {
33
33
  "@modelcontextprotocol/server": "2.0.0",
34
- zod: "^4.0.0"
34
+ zod: "^4.6.2"
35
35
  },
36
36
  devDependencies: {
37
37
  "@modelcontextprotocol/client": "2.0.0",
38
- "@types/node": "^26.2.0",
38
+ "@types/node": "^26.5.1",
39
39
  typescript: "^7.0.2",
40
- vite: "^8.2.2",
41
- "vite-plugin-dts": "^5.0.3",
42
- vitest: "^4.1.11"
40
+ vite: "^8.3.0",
41
+ "vite-plugin-dts": "^5.1.0",
42
+ vitest: "^5.0.0"
43
43
  },
44
44
  engines: { node: ">=20.19.0" }
45
45
  }.version, r = class extends Error {
@@ -460,7 +460,7 @@ function S(e, n) {
460
460
  let t = await n.api.request("GET", `${r}/${i(e.key)}/environments`);
461
461
  if (t.length === 0) continue;
462
462
  let a = t.every((e) => e.isEnabled), o = t.every((e) => !e.isEnabled);
463
- !a && !o || d.push({
463
+ (a || o) && d.push({
464
464
  key: e.key,
465
465
  name: e.name,
466
466
  updatedAt: e.updatedAt,
@@ -704,18 +704,23 @@ function A(t) {
704
704
  }
705
705
  //#endregion
706
706
  //#region src/config.ts
707
- function j(e = process.env) {
707
+ var j = "FEATUREFLIP_TOKEN is required. Create one in the Featureflip dashboard — Settings → API Tokens (personal token, ffp_...) or Organization Settings → Service Tokens (ffs_...) — and set it in your MCP client config.";
708
+ function M(e = process.env) {
708
709
  let t = e.FEATUREFLIP_TOKEN?.trim();
709
- if (!t) throw Error("FEATUREFLIP_TOKEN is required. Create one in the Featureflip dashboard — Settings → API Tokens (personal token, ffp_...) or Organization Settings → Service Tokens (ffs_...) — and set it in your MCP client config.");
710
- return {
710
+ return t ? {
711
711
  token: t,
712
712
  baseUrl: (e.FEATUREFLIP_API_URL?.trim() || "https://api.featureflip.io").replace(/\/+$/, ""),
713
713
  org: e.FEATUREFLIP_ORG?.trim() || void 0
714
- };
714
+ } : null;
715
+ }
716
+ function N(e = process.env) {
717
+ let t = M(e);
718
+ if (!t) throw Error(j);
719
+ return t;
715
720
  }
716
721
  //#endregion
717
722
  //#region src/org.ts
718
- async function M(e, t) {
723
+ async function P(e, t) {
719
724
  if (t) return t;
720
725
  let n = (await e.request("GET", "/api/v1/orgs", { query: { limit: 100 } })).items ?? [];
721
726
  if (n.length === 1) {
@@ -726,4 +731,4 @@ async function M(e, t) {
726
731
  throw n.length === 0 ? Error("The token can see no organizations. Check the token in the Featureflip dashboard.") : Error(`The token can see ${n.length} organizations — set FEATUREFLIP_ORG to one of: ` + n.map((e) => e.slug ?? "?").join(", "));
727
732
  }
728
733
  //#endregion
729
- export { a, r as i, j as n, n as o, A as r, M as t };
734
+ export { A as a, n as c, M as i, j as n, r as o, N as r, a as s, P as t };
@@ -0,0 +1,11 @@
1
+ import { ToolContext } from './tools/context.js';
2
+ /**
3
+ * A context that serves tool *definitions* but no data.
4
+ *
5
+ * `tools/list` is how a client discovers what this server can do, and registries
6
+ * (Glama among them) enumerate it before anyone has wired a token. Exiting at
7
+ * startup made the server look like it had no tools at all — so with no token we
8
+ * start anyway and fail at call time instead.
9
+ */
10
+ export declare function unconfiguredContext(): ToolContext;
11
+ //# sourceMappingURL=unconfigured.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unconfigured.d.ts","sourceRoot":"","sources":["../src/unconfigured.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAkBtD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CAEjD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featureflip/mcp",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "mcpName": "io.github.canopy-labs/featureflip",
5
5
  "description": "MCP server for managing Featureflip feature flags from AI agents and editors",
6
6
  "license": "Apache-2.0",
@@ -36,15 +36,15 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@modelcontextprotocol/server": "2.0.0",
39
- "zod": "^4.0.0"
39
+ "zod": "^4.6.2"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@modelcontextprotocol/client": "2.0.0",
43
- "@types/node": "^26.2.0",
43
+ "@types/node": "^26.5.1",
44
44
  "typescript": "^7.0.2",
45
- "vite": "^8.2.2",
46
- "vite-plugin-dts": "^5.0.3",
47
- "vitest": "^4.1.11"
45
+ "vite": "^8.3.0",
46
+ "vite-plugin-dts": "^5.1.0",
47
+ "vitest": "^5.0.0"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=20.19.0"