@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.
- package/dist/bootstrap.d.ts +12 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/cli.mjs +44 -13
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{org-DsA8PUrd.js → org-fuZ3wOph.js} +18 -13
- package/dist/unconfigured.d.ts +11 -0
- package/dist/unconfigured.d.ts.map +1 -0
- package/package.json +6 -6
|
@@ -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,
|
|
2
|
-
import { serveStdio as
|
|
3
|
-
//#region src/
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
29
|
+
await n.request("GET", "/api/v1/me");
|
|
8
30
|
} catch (e) {
|
|
9
|
-
throw e instanceof
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
package/dist/config.d.ts.map
CHANGED
|
@@ -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,
|
|
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,
|
|
2
|
-
export {
|
|
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.
|
|
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.
|
|
34
|
+
zod: "^4.6.2"
|
|
35
35
|
},
|
|
36
36
|
devDependencies: {
|
|
37
37
|
"@modelcontextprotocol/client": "2.0.0",
|
|
38
|
-
"@types/node": "^26.
|
|
38
|
+
"@types/node": "^26.5.1",
|
|
39
39
|
typescript: "^7.0.2",
|
|
40
|
-
vite: "^8.
|
|
41
|
-
"vite-plugin-dts": "^5.0
|
|
42
|
-
vitest: "^
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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.
|
|
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.
|
|
39
|
+
"zod": "^4.6.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@modelcontextprotocol/client": "2.0.0",
|
|
43
|
-
"@types/node": "^26.
|
|
43
|
+
"@types/node": "^26.5.1",
|
|
44
44
|
"typescript": "^7.0.2",
|
|
45
|
-
"vite": "^8.
|
|
46
|
-
"vite-plugin-dts": "^5.0
|
|
47
|
-
"vitest": "^
|
|
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"
|