@pennant/mcp 1.0.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.
- package/README.md +78 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +29 -0
- package/dist/config.js.map +1 -0
- package/dist/console-client.d.ts +55 -0
- package/dist/console-client.js +128 -0
- package/dist/console-client.js.map +1 -0
- package/dist/explain.d.ts +21 -0
- package/dist/explain.js +168 -0
- package/dist/explain.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/sdk-guide.d.ts +27 -0
- package/dist/sdk-guide.js +259 -0
- package/dist/sdk-guide.js.map +1 -0
- package/dist/tools.d.ts +5 -0
- package/dist/tools.js +306 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const SDKS = ["react", "vue", "js", "node", "python", "go", "rust"];
|
|
4
|
+
const MANIFESTS = [
|
|
5
|
+
"package.json",
|
|
6
|
+
"pyproject.toml",
|
|
7
|
+
"requirements.txt",
|
|
8
|
+
"go.mod",
|
|
9
|
+
"Cargo.toml",
|
|
10
|
+
];
|
|
11
|
+
const SERVER_FRAMEWORKS = ["express", "fastify", "koa", "hono", "@nestjs/core", "@hapi/hapi"];
|
|
12
|
+
/** Picks SDKs from manifest file contents, keyed by file name. */
|
|
13
|
+
function detectStack(files) {
|
|
14
|
+
const found = [];
|
|
15
|
+
const pkgText = files.get("package.json");
|
|
16
|
+
if (pkgText) {
|
|
17
|
+
let deps = {};
|
|
18
|
+
try {
|
|
19
|
+
const pkg = JSON.parse(pkgText);
|
|
20
|
+
deps = { ...pkg.devDependencies, ...pkg.dependencies };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
deps = {};
|
|
24
|
+
}
|
|
25
|
+
const has = (name) => name in deps;
|
|
26
|
+
const framework = has("next") ? "next" : has("nuxt") ? "nuxt" : has("vite") ? "vite" : undefined;
|
|
27
|
+
if (has("react"))
|
|
28
|
+
found.push({ sdk: "react", reason: "package.json depends on react.", framework });
|
|
29
|
+
else if (has("vue"))
|
|
30
|
+
found.push({ sdk: "vue", reason: "package.json depends on vue.", framework });
|
|
31
|
+
const server = SERVER_FRAMEWORKS.find(has);
|
|
32
|
+
if (server)
|
|
33
|
+
found.push({ sdk: "node", reason: `package.json depends on ${server}.` });
|
|
34
|
+
if (!has("react") && !has("vue") && !server) {
|
|
35
|
+
found.push(framework === "vite"
|
|
36
|
+
? { sdk: "js", reason: "A Vite app without React or Vue.", framework }
|
|
37
|
+
: { sdk: "node", reason: "A JavaScript project without a browser framework." });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (files.has("pyproject.toml") || files.has("requirements.txt")) {
|
|
41
|
+
found.push({
|
|
42
|
+
sdk: "python",
|
|
43
|
+
reason: files.has("pyproject.toml") ? "Found pyproject.toml." : "Found requirements.txt.",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (files.has("go.mod"))
|
|
47
|
+
found.push({ sdk: "go", reason: "Found go.mod." });
|
|
48
|
+
if (files.has("Cargo.toml"))
|
|
49
|
+
found.push({ sdk: "rust", reason: "Found Cargo.toml." });
|
|
50
|
+
return found;
|
|
51
|
+
}
|
|
52
|
+
/** Reads the manifest files in one directory. Missing files are skipped. */
|
|
53
|
+
async function readManifests(dir) {
|
|
54
|
+
const files = new Map();
|
|
55
|
+
await Promise.all(MANIFESTS.map(async (name) => {
|
|
56
|
+
try {
|
|
57
|
+
files.set(name, await readFile(path.join(dir, name), "utf8"));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* not present */
|
|
61
|
+
}
|
|
62
|
+
}));
|
|
63
|
+
return files;
|
|
64
|
+
}
|
|
65
|
+
function browserKeyVar(framework) {
|
|
66
|
+
if (framework === "next")
|
|
67
|
+
return "NEXT_PUBLIC_PENNANT_CLIENT_KEY";
|
|
68
|
+
if (framework === "nuxt")
|
|
69
|
+
return "NUXT_PUBLIC_PENNANT_CLIENT_KEY";
|
|
70
|
+
return "VITE_PENNANT_CLIENT_KEY";
|
|
71
|
+
}
|
|
72
|
+
function browserEnvRead(framework, name) {
|
|
73
|
+
return framework === "next" || framework === "nuxt"
|
|
74
|
+
? `process.env.${name}`
|
|
75
|
+
: `import.meta.env.${name}`;
|
|
76
|
+
}
|
|
77
|
+
/** Install line, environment variables, and a first flag check for one SDK. */
|
|
78
|
+
function setupGuide(sdk, options) {
|
|
79
|
+
const flag = options.flagKey ?? "new-checkout";
|
|
80
|
+
const keyNote = "Copy the client key from the project's Configure page. It can only read flag results, but keep it in configuration, not source.";
|
|
81
|
+
const offNote = `Write the code so ${flag} being off is the safe path. Unknown flags read as off.`;
|
|
82
|
+
switch (sdk) {
|
|
83
|
+
case "react": {
|
|
84
|
+
const keyVar = browserKeyVar(options.framework);
|
|
85
|
+
return {
|
|
86
|
+
sdk,
|
|
87
|
+
install: "npm install @pennant/react",
|
|
88
|
+
env: { [keyVar]: "<project client key>" },
|
|
89
|
+
code: `import { PennantProvider, useFlag } from "@pennant/react"
|
|
90
|
+
|
|
91
|
+
export function Root({ user, children }) {
|
|
92
|
+
return (
|
|
93
|
+
<PennantProvider
|
|
94
|
+
apiUrl="${options.apiUrl}"
|
|
95
|
+
clientKey={${browserEnvRead(options.framework, keyVar)}}
|
|
96
|
+
environment="production"
|
|
97
|
+
context={{ userId: user.id }}
|
|
98
|
+
>
|
|
99
|
+
{children}
|
|
100
|
+
</PennantProvider>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function Checkout() {
|
|
105
|
+
const enabled = useFlag("${flag}")
|
|
106
|
+
return enabled ? <NewCheckout /> : <ClassicCheckout />
|
|
107
|
+
}`,
|
|
108
|
+
notes: [
|
|
109
|
+
keyNote,
|
|
110
|
+
offNote,
|
|
111
|
+
"The provider refreshes every 15 seconds by default. Set pollIntervalMs to change it.",
|
|
112
|
+
...(options.framework === "next"
|
|
113
|
+
? ['In the Next.js App Router, render PennantProvider from a "use client" component.']
|
|
114
|
+
: []),
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
case "vue": {
|
|
119
|
+
const keyVar = browserKeyVar(options.framework);
|
|
120
|
+
return {
|
|
121
|
+
sdk,
|
|
122
|
+
install: "npm install @pennant/vue",
|
|
123
|
+
env: { [keyVar]: "<project client key>" },
|
|
124
|
+
code: `<script setup>
|
|
125
|
+
import { Flag, PennantProvider } from "@pennant/vue"
|
|
126
|
+
const clientKey = ${browserEnvRead(options.framework, keyVar)}
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<template>
|
|
130
|
+
<PennantProvider
|
|
131
|
+
api-url="${options.apiUrl}"
|
|
132
|
+
:client-key="clientKey"
|
|
133
|
+
environment="production"
|
|
134
|
+
:context="{ userId: user.id }"
|
|
135
|
+
>
|
|
136
|
+
<Flag name="${flag}">
|
|
137
|
+
<NewCheckout />
|
|
138
|
+
</Flag>
|
|
139
|
+
</PennantProvider>
|
|
140
|
+
</template>`,
|
|
141
|
+
notes: [
|
|
142
|
+
keyNote,
|
|
143
|
+
offNote,
|
|
144
|
+
"useFlag and useVariant work in any component under PennantProvider.",
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
case "js":
|
|
149
|
+
return {
|
|
150
|
+
sdk,
|
|
151
|
+
install: "npm install @pennant/js",
|
|
152
|
+
env: { VITE_PENNANT_CLIENT_KEY: "<project client key>" },
|
|
153
|
+
code: `import { createPennantClient } from "@pennant/js"
|
|
154
|
+
|
|
155
|
+
const pennant = createPennantClient({
|
|
156
|
+
apiUrl: "${options.apiUrl}",
|
|
157
|
+
clientKey: import.meta.env.VITE_PENNANT_CLIENT_KEY,
|
|
158
|
+
environment: "production",
|
|
159
|
+
context: { userId: currentUser.id },
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
await pennant.evaluate()
|
|
163
|
+
if (pennant.isEnabled("${flag}")) {
|
|
164
|
+
showNewCheckout()
|
|
165
|
+
}`,
|
|
166
|
+
notes: [keyNote, offNote, "Call evaluate again after sign-in or when the context changes."],
|
|
167
|
+
};
|
|
168
|
+
case "node":
|
|
169
|
+
return {
|
|
170
|
+
sdk,
|
|
171
|
+
install: "npm install @pennant/node",
|
|
172
|
+
env: { PENNANT_API_URL: options.apiUrl, PENNANT_CLIENT_KEY: "<project client key>" },
|
|
173
|
+
code: `import { createPennantClient } from "@pennant/node"
|
|
174
|
+
|
|
175
|
+
const pennant = createPennantClient({
|
|
176
|
+
apiUrl: process.env.PENNANT_API_URL,
|
|
177
|
+
clientKey: process.env.PENNANT_CLIENT_KEY,
|
|
178
|
+
environment: "production",
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// Evaluate per request with that request's user.
|
|
182
|
+
const flags = await pennant.evaluate({ userId: req.user.id, remoteAddress: req.ip })
|
|
183
|
+
if (flags["${flag}"]?.enabled) {
|
|
184
|
+
return newCheckout(req, res)
|
|
185
|
+
}`,
|
|
186
|
+
notes: [
|
|
187
|
+
keyNote,
|
|
188
|
+
offNote,
|
|
189
|
+
"Server SDKs evaluate when called, so pass the current user's context each time.",
|
|
190
|
+
],
|
|
191
|
+
};
|
|
192
|
+
case "python":
|
|
193
|
+
return {
|
|
194
|
+
sdk,
|
|
195
|
+
install: 'pip install "pennant-sdk @ git+https://github.com/flypennant/pennant-sdks.git@python/v1.1.0#subdirectory=python"',
|
|
196
|
+
env: { PENNANT_API_URL: options.apiUrl, PENNANT_CLIENT_KEY: "<project client key>" },
|
|
197
|
+
code: `import os
|
|
198
|
+
from pennant import PennantClient
|
|
199
|
+
|
|
200
|
+
pennant = PennantClient(
|
|
201
|
+
api_url=os.environ["PENNANT_API_URL"],
|
|
202
|
+
client_key=os.environ["PENNANT_CLIENT_KEY"],
|
|
203
|
+
environment="production",
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
flags = pennant.evaluate({"userId": user.id})
|
|
207
|
+
if flags.get("${flag}", {}).get("enabled"):
|
|
208
|
+
return new_checkout(request)`,
|
|
209
|
+
notes: [keyNote, offNote, "The package is pennant-sdk; the import name is pennant."],
|
|
210
|
+
};
|
|
211
|
+
case "go":
|
|
212
|
+
return {
|
|
213
|
+
sdk,
|
|
214
|
+
install: "go get github.com/flypennant/pennant-sdks/go@latest",
|
|
215
|
+
env: { PENNANT_API_URL: options.apiUrl, PENNANT_CLIENT_KEY: "<project client key>" },
|
|
216
|
+
code: `import pennant "github.com/flypennant/pennant-sdks/go"
|
|
217
|
+
|
|
218
|
+
client := pennant.NewClient(pennant.ClientOptions{
|
|
219
|
+
APIURL: os.Getenv("PENNANT_API_URL"),
|
|
220
|
+
ClientKey: os.Getenv("PENNANT_CLIENT_KEY"),
|
|
221
|
+
Environment: "production",
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
flags, err := client.Evaluate(&pennant.EvaluationContext{UserID: user.ID})
|
|
225
|
+
if err == nil && pennant.IsEnabledIn(flags, "${flag}") {
|
|
226
|
+
return newCheckout(w, r)
|
|
227
|
+
}`,
|
|
228
|
+
notes: [
|
|
229
|
+
keyNote,
|
|
230
|
+
offNote,
|
|
231
|
+
"Treat an evaluate error as off, so an outage falls back to the current behaviour.",
|
|
232
|
+
],
|
|
233
|
+
};
|
|
234
|
+
case "rust":
|
|
235
|
+
return {
|
|
236
|
+
sdk,
|
|
237
|
+
install: "cargo add pennant-sdk --rename pennant --git https://github.com/flypennant/pennant-sdks --tag rust/v1.1.0",
|
|
238
|
+
env: { PENNANT_API_URL: options.apiUrl, PENNANT_CLIENT_KEY: "<project client key>" },
|
|
239
|
+
code: `use pennant::{is_enabled, Client, ClientOptions, EvaluationContext};
|
|
240
|
+
|
|
241
|
+
let mut client = Client::new(ClientOptions {
|
|
242
|
+
api_url: std::env::var("PENNANT_API_URL")?,
|
|
243
|
+
client_key: std::env::var("PENNANT_CLIENT_KEY")?,
|
|
244
|
+
environment: "production".into(),
|
|
245
|
+
project: None,
|
|
246
|
+
context: EvaluationContext::default(),
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
let context = EvaluationContext { user_id: Some(user.id.clone()), ..EvaluationContext::default() };
|
|
250
|
+
let flags = client.evaluate(Some(&context))?;
|
|
251
|
+
if is_enabled(&flags, "${flag}") {
|
|
252
|
+
return new_checkout(req);
|
|
253
|
+
}`,
|
|
254
|
+
notes: [keyNote, offNote, "The crate is pennant-sdk; the library name is pennant."],
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
export { MANIFESTS, SDKS, detectStack, readManifests, setupGuide };
|
|
259
|
+
//# sourceMappingURL=sdk-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-guide.js","sourceRoot":"","sources":["../src/sdk-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAU,CAAA;AAc5E,MAAM,SAAS,GAAG;IAChB,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,QAAQ;IACR,YAAY;CACJ,CAAA;AAEV,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,CAAA;AAE7F,kEAAkE;AAClE,SAAS,WAAW,CAAC,KAA0B;IAC7C,MAAM,KAAK,GAAgB,EAAE,CAAA;IAE7B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACzC,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,IAAI,GAA2B,EAAE,CAAA;QACrC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAG7B,CAAA;YACD,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,eAAe,EAAE,GAAG,GAAG,CAAC,YAAY,EAAE,CAAA;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,CAAA;QACX,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAA;QAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;QAChG,IAAI,GAAG,CAAC,OAAO,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,gCAAgC,EAAE,SAAS,EAAE,CAAC,CAAA;aAC9E,IAAI,GAAG,CAAC,KAAK,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,SAAS,EAAE,CAAC,CAAA;QAC/E,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC1C,IAAI,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,2BAA2B,MAAM,GAAG,EAAE,CAAC,CAAA;QACrF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CACR,SAAS,KAAK,MAAM;gBAClB,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,kCAAkC,EAAE,SAAS,EAAE;gBACtE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,mDAAmD,EAAE,CACjF,CAAA;QACH,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACjE,KAAK,CAAC,IAAI,CAAC;YACT,GAAG,EAAE,QAAQ;YACb,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,yBAAyB;SAC1F,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;IAC3E,IAAI,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAA;IACrF,OAAO,KAAK,CAAA;AACd,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,aAAa,CAAC,GAAW;IACtC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAA;IACvC,MAAM,OAAO,CAAC,GAAG,CACf,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;QACnB,CAAC;IACH,CAAC,CAAC,CACH,CAAA;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,aAAa,CAAC,SAAkC;IACvD,IAAI,SAAS,KAAK,MAAM;QAAE,OAAO,gCAAgC,CAAA;IACjE,IAAI,SAAS,KAAK,MAAM;QAAE,OAAO,gCAAgC,CAAA;IACjE,OAAO,yBAAyB,CAAA;AAClC,CAAC;AAED,SAAS,cAAc,CAAC,SAAiC,EAAE,IAAY;IACrE,OAAO,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,MAAM;QACjD,CAAC,CAAC,eAAe,IAAI,EAAE;QACvB,CAAC,CAAC,mBAAmB,IAAI,EAAE,CAAA;AAC/B,CAAC;AAED,+EAA+E;AAC/E,SAAS,UAAU,CACjB,GAAU,EACV,OAAiF;IAEjF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,CAAA;IAC9C,MAAM,OAAO,GACX,iIAAiI,CAAA;IACnI,MAAM,OAAO,GAAG,qBAAqB,IAAI,yDAAyD,CAAA;IAElG,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC/C,OAAO;gBACL,GAAG;gBACH,OAAO,EAAE,4BAA4B;gBACrC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,sBAAsB,EAAE;gBACzC,IAAI,EAAE;;;;;gBAKE,OAAO,CAAC,MAAM;mBACX,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;;;;;;;;;;6BAU/B,IAAI;;EAE/B;gBACM,KAAK,EAAE;oBACL,OAAO;oBACP,OAAO;oBACP,sFAAsF;oBACtF,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,MAAM;wBAC9B,CAAC,CAAC,CAAC,kFAAkF,CAAC;wBACtF,CAAC,CAAC,EAAE,CAAC;iBACR;aACF,CAAA;QACH,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC/C,OAAO;gBACL,GAAG;gBACH,OAAO,EAAE,0BAA0B;gBACnC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,sBAAsB,EAAE;gBACzC,IAAI,EAAE;;oBAEM,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;;;;;eAK9C,OAAO,CAAC,MAAM;;;;;kBAKX,IAAI;;;;YAIV;gBACJ,KAAK,EAAE;oBACL,OAAO;oBACP,OAAO;oBACP,qEAAqE;iBACtE;aACF,CAAA;QACH,CAAC;QACD,KAAK,IAAI;YACP,OAAO;gBACL,GAAG;gBACH,OAAO,EAAE,yBAAyB;gBAClC,GAAG,EAAE,EAAE,uBAAuB,EAAE,sBAAsB,EAAE;gBACxD,IAAI,EAAE;;;aAGD,OAAO,CAAC,MAAM;;;;;;;yBAOF,IAAI;;EAE3B;gBACM,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,gEAAgE,CAAC;aAC5F,CAAA;QACH,KAAK,MAAM;YACT,OAAO;gBACL,GAAG;gBACH,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE;gBACpF,IAAI,EAAE;;;;;;;;;;aAUD,IAAI;;EAEf;gBACM,KAAK,EAAE;oBACL,OAAO;oBACP,OAAO;oBACP,iFAAiF;iBAClF;aACF,CAAA;QACH,KAAK,QAAQ;YACX,OAAO;gBACL,GAAG;gBACH,OAAO,EACL,kHAAkH;gBACpH,GAAG,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE;gBACpF,IAAI,EAAE;;;;;;;;;;gBAUE,IAAI;iCACa;gBACzB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,yDAAyD,CAAC;aACrF,CAAA;QACH,KAAK,IAAI;YACP,OAAO;gBACL,GAAG;gBACH,OAAO,EAAE,qDAAqD;gBAC9D,GAAG,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE;gBACpF,IAAI,EAAE;;;;;;;;;+CASiC,IAAI;;EAEjD;gBACM,KAAK,EAAE;oBACL,OAAO;oBACP,OAAO;oBACP,mFAAmF;iBACpF;aACF,CAAA;QACH,KAAK,MAAM;YACT,OAAO;gBACL,GAAG;gBACH,OAAO,EACL,2GAA2G;gBAC7G,GAAG,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE;gBACpF,IAAI,EAAE;;;;;;;;;;;;yBAYW,IAAI;;EAE3B;gBACM,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,wDAAwD,CAAC;aACpF,CAAA;IACL,CAAC;AACH,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,CAAA"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { McpConfig } from "./config.ts";
|
|
3
|
+
import { type ConsoleClient } from "./console-client.ts";
|
|
4
|
+
declare function registerTools(server: McpServer, client: ConsoleClient, config: McpConfig): void;
|
|
5
|
+
export { registerTools };
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { ConsoleError } from "./console-client.js";
|
|
4
|
+
import { describeStrategy, explainFlag } from "./explain.js";
|
|
5
|
+
import { SDKS, detectStack, readManifests, setupGuide } from "./sdk-guide.js";
|
|
6
|
+
import { FLAG_TYPES } from "./types.js";
|
|
7
|
+
const projectArg = z
|
|
8
|
+
.string()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Project id. Defaults to PENNANT_PROJECT or 'default'.");
|
|
11
|
+
const strategySchema = z.discriminatedUnion("type", [
|
|
12
|
+
z.object({ type: z.literal("everyone") }),
|
|
13
|
+
z.object({ type: z.literal("gradual"), percentage: z.number().int().min(0).max(100) }),
|
|
14
|
+
z.object({ type: z.literal("allowlist"), userIds: z.array(z.string()) }),
|
|
15
|
+
z.object({ type: z.literal("remoteAddress"), addresses: z.array(z.string()) }),
|
|
16
|
+
z.object({ type: z.literal("hostname"), hostnames: z.array(z.string()) }),
|
|
17
|
+
]);
|
|
18
|
+
const constraintSchema = z.object({
|
|
19
|
+
contextName: z.string().describe("Context field, such as userId or a custom property like plan."),
|
|
20
|
+
operator: z.enum(["IN", "NOT_IN"]),
|
|
21
|
+
values: z.array(z.string()),
|
|
22
|
+
});
|
|
23
|
+
const contextSchema = z
|
|
24
|
+
.object({
|
|
25
|
+
userId: z.string().optional(),
|
|
26
|
+
sessionId: z.string().optional(),
|
|
27
|
+
remoteAddress: z.string().optional(),
|
|
28
|
+
hostname: z.string().optional(),
|
|
29
|
+
properties: z.record(z.string(), z.string()).optional(),
|
|
30
|
+
})
|
|
31
|
+
.describe("Who the flag is evaluated for.");
|
|
32
|
+
function ok(text) {
|
|
33
|
+
return { content: [{ type: "text", text }] };
|
|
34
|
+
}
|
|
35
|
+
function json(value) {
|
|
36
|
+
return ok(JSON.stringify(value, null, 2));
|
|
37
|
+
}
|
|
38
|
+
/** Turns console errors into tool errors the assistant can read and act on. */
|
|
39
|
+
async function guarded(run) {
|
|
40
|
+
try {
|
|
41
|
+
return await run();
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const message = error instanceof ConsoleError
|
|
45
|
+
? `Pennant returned ${error.status}: ${error.message}`
|
|
46
|
+
: error instanceof Error
|
|
47
|
+
? error.message
|
|
48
|
+
: "Unexpected error.";
|
|
49
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function flagSummary(flag) {
|
|
53
|
+
return {
|
|
54
|
+
key: flag.key,
|
|
55
|
+
name: flag.name,
|
|
56
|
+
type: flag.type,
|
|
57
|
+
archived: flag.archived,
|
|
58
|
+
parentKey: flag.parentKey ?? null,
|
|
59
|
+
tags: flag.tags,
|
|
60
|
+
environments: Object.fromEntries(Object.entries(flag.environments).map(([env, config]) => [
|
|
61
|
+
env,
|
|
62
|
+
`${config.enabled ? "on" : "off"}, ${describeStrategy(config.strategy)}`,
|
|
63
|
+
])),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function registerTools(server, client, config) {
|
|
67
|
+
const project = (value) => value ?? config.project;
|
|
68
|
+
/* ---------- read ---------- */
|
|
69
|
+
server.registerTool("list_projects", {
|
|
70
|
+
title: "List projects",
|
|
71
|
+
description: "List the Pennant projects the signed-in user can open.",
|
|
72
|
+
annotations: { readOnlyHint: true },
|
|
73
|
+
}, () => guarded(async () => json(await client.listProjects())));
|
|
74
|
+
server.registerTool("list_environments", {
|
|
75
|
+
title: "List environments",
|
|
76
|
+
description: "List a project's environments, such as development and production.",
|
|
77
|
+
inputSchema: { project: projectArg },
|
|
78
|
+
annotations: { readOnlyHint: true },
|
|
79
|
+
}, (args) => guarded(async () => json(await client.listEnvironments(project(args.project)))));
|
|
80
|
+
server.registerTool("list_flags", {
|
|
81
|
+
title: "List flags",
|
|
82
|
+
description: "List flags in a project with their type, tags, parent, and on/off state per environment.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
project: projectArg,
|
|
85
|
+
includeArchived: z.boolean().optional(),
|
|
86
|
+
tag: z.string().optional().describe("Only flags with this tag."),
|
|
87
|
+
},
|
|
88
|
+
annotations: { readOnlyHint: true },
|
|
89
|
+
}, (args) => guarded(async () => {
|
|
90
|
+
const flags = await client.listFlags(project(args.project), args.includeArchived ?? false);
|
|
91
|
+
const filtered = args.tag ? flags.filter((flag) => flag.tags.includes(args.tag)) : flags;
|
|
92
|
+
return json(filtered.map(flagSummary));
|
|
93
|
+
}));
|
|
94
|
+
server.registerTool("get_flag", {
|
|
95
|
+
title: "Get flag",
|
|
96
|
+
description: "Get a flag's full configuration: strategy, constraints, segments, and variants per environment.",
|
|
97
|
+
inputSchema: { key: z.string(), project: projectArg },
|
|
98
|
+
annotations: { readOnlyHint: true },
|
|
99
|
+
}, (args) => guarded(async () => json(await client.getFlag(project(args.project), args.key))));
|
|
100
|
+
server.registerTool("list_segments", {
|
|
101
|
+
title: "List segments",
|
|
102
|
+
description: "List a project's saved audiences and their constraints.",
|
|
103
|
+
inputSchema: { project: projectArg },
|
|
104
|
+
annotations: { readOnlyHint: true },
|
|
105
|
+
}, (args) => guarded(async () => json(await client.listSegments(project(args.project)))));
|
|
106
|
+
/* ---------- explain ---------- */
|
|
107
|
+
server.registerTool("explain_flag", {
|
|
108
|
+
title: "Explain a flag result",
|
|
109
|
+
description: "Explain why a flag is on or off for a given user in an environment. Walks the same rules the server checks: archive, environment switch, constraints, segments, parent flag, then strategy.",
|
|
110
|
+
inputSchema: {
|
|
111
|
+
key: z.string(),
|
|
112
|
+
environment: z.string(),
|
|
113
|
+
context: contextSchema,
|
|
114
|
+
project: projectArg,
|
|
115
|
+
},
|
|
116
|
+
annotations: { readOnlyHint: true },
|
|
117
|
+
}, (args) => guarded(async () => {
|
|
118
|
+
const id = project(args.project);
|
|
119
|
+
const [flags, segments, live] = await Promise.all([
|
|
120
|
+
client.listFlags(id, true),
|
|
121
|
+
client.listSegments(id),
|
|
122
|
+
client.evaluate(args.environment, args.context, id),
|
|
123
|
+
]);
|
|
124
|
+
const flag = flags.find((item) => item.key === args.key);
|
|
125
|
+
if (!flag)
|
|
126
|
+
return {
|
|
127
|
+
content: [{ type: "text", text: `No flag ${args.key} in project ${id}.` }],
|
|
128
|
+
isError: true,
|
|
129
|
+
};
|
|
130
|
+
const explanation = explainFlag(flag, args.environment, args.context, {
|
|
131
|
+
flags: new Map(flags.map((item) => [item.key, item])),
|
|
132
|
+
segments: new Map(segments.map((item) => [item.id, item])),
|
|
133
|
+
live: live ?? undefined,
|
|
134
|
+
});
|
|
135
|
+
const verdict = explanation.enabled === null
|
|
136
|
+
? "Depends on the rollout"
|
|
137
|
+
: explanation.enabled
|
|
138
|
+
? "On"
|
|
139
|
+
: "Off";
|
|
140
|
+
const source = live
|
|
141
|
+
? "Confirmed against the live evaluate API."
|
|
142
|
+
: "Worked out from the flag configuration.";
|
|
143
|
+
return ok([
|
|
144
|
+
`${verdict}: ${explanation.reason}`,
|
|
145
|
+
"",
|
|
146
|
+
...explanation.steps.map((step, i) => `${i + 1}. ${step}`),
|
|
147
|
+
"",
|
|
148
|
+
source,
|
|
149
|
+
].join("\n"));
|
|
150
|
+
}));
|
|
151
|
+
/* ---------- sdk ---------- */
|
|
152
|
+
server.registerTool("detect_stack", {
|
|
153
|
+
title: "Detect the codebase's stack",
|
|
154
|
+
description: "Read the manifest files (package.json, pyproject.toml, go.mod, Cargo.toml) in a directory and say which Pennant SDK fits.",
|
|
155
|
+
inputSchema: {
|
|
156
|
+
path: z
|
|
157
|
+
.string()
|
|
158
|
+
.optional()
|
|
159
|
+
.describe("Directory to inspect. Defaults to the current directory."),
|
|
160
|
+
},
|
|
161
|
+
annotations: { readOnlyHint: true },
|
|
162
|
+
}, (args) => guarded(async () => {
|
|
163
|
+
const dir = path.resolve(args.path ?? process.cwd());
|
|
164
|
+
const detections = detectStack(await readManifests(dir));
|
|
165
|
+
if (detections.length === 0) {
|
|
166
|
+
return ok(`No package.json, pyproject.toml, requirements.txt, go.mod, or Cargo.toml in ${dir}. Run sdk_setup with the SDK you want.`);
|
|
167
|
+
}
|
|
168
|
+
return json({
|
|
169
|
+
directory: dir,
|
|
170
|
+
matches: detections,
|
|
171
|
+
next: "Call sdk_setup with the sdk (and framework) for install steps and code.",
|
|
172
|
+
});
|
|
173
|
+
}));
|
|
174
|
+
server.registerTool("sdk_setup", {
|
|
175
|
+
title: "SDK setup steps",
|
|
176
|
+
description: "Install command, environment variables, and a first flag check for one Pennant SDK, pointed at this Pennant console.",
|
|
177
|
+
inputSchema: {
|
|
178
|
+
sdk: z.enum(SDKS),
|
|
179
|
+
framework: z.enum(["next", "vite", "nuxt"]).optional(),
|
|
180
|
+
flagKey: z
|
|
181
|
+
.string()
|
|
182
|
+
.optional()
|
|
183
|
+
.describe("Flag to use in the example. Defaults to new-checkout."),
|
|
184
|
+
},
|
|
185
|
+
annotations: { readOnlyHint: true },
|
|
186
|
+
}, (args) => guarded(async () => {
|
|
187
|
+
const guide = setupGuide(args.sdk, {
|
|
188
|
+
apiUrl: config.url,
|
|
189
|
+
flagKey: args.flagKey,
|
|
190
|
+
framework: args.framework,
|
|
191
|
+
});
|
|
192
|
+
const env = Object.entries(guide.env).map(([name, value]) => `${name}=${value}`);
|
|
193
|
+
return ok([
|
|
194
|
+
`Install:\n${guide.install}`,
|
|
195
|
+
`Environment:\n${env.join("\n")}`,
|
|
196
|
+
`Code:\n${guide.code}`,
|
|
197
|
+
`Notes:\n${guide.notes.map((note) => `- ${note}`).join("\n")}`,
|
|
198
|
+
].join("\n\n"));
|
|
199
|
+
}));
|
|
200
|
+
if (config.readOnly)
|
|
201
|
+
return;
|
|
202
|
+
/* ---------- write ---------- */
|
|
203
|
+
server.registerTool("create_flag", {
|
|
204
|
+
title: "Create flag",
|
|
205
|
+
description: "Create a flag. It starts switched off in every environment.",
|
|
206
|
+
inputSchema: {
|
|
207
|
+
key: z.string().describe("Lowercase key used in code, such as new-checkout."),
|
|
208
|
+
name: z.string(),
|
|
209
|
+
description: z.string().optional(),
|
|
210
|
+
type: z.enum(FLAG_TYPES).optional(),
|
|
211
|
+
strategy: strategySchema.optional().describe("Starting strategy for every environment."),
|
|
212
|
+
project: projectArg,
|
|
213
|
+
},
|
|
214
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
215
|
+
}, (args) => guarded(async () => {
|
|
216
|
+
const { project: id, ...input } = args;
|
|
217
|
+
const flag = await client.createFlag(project(id), input);
|
|
218
|
+
return ok(`Created ${flag.key}. It is off everywhere until you switch it on.\n\n${JSON.stringify(flagSummary(flag), null, 2)}`);
|
|
219
|
+
}));
|
|
220
|
+
server.registerTool("set_flag_enabled", {
|
|
221
|
+
title: "Switch a flag on or off",
|
|
222
|
+
description: "Switch a flag on or off in one environment. If the project requires approval for production, this opens a change request instead of applying the change.",
|
|
223
|
+
inputSchema: {
|
|
224
|
+
key: z.string(),
|
|
225
|
+
environment: z.string(),
|
|
226
|
+
enabled: z.boolean(),
|
|
227
|
+
project: projectArg,
|
|
228
|
+
},
|
|
229
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },
|
|
230
|
+
}, (args) => guarded(async () => {
|
|
231
|
+
const result = await client.setEnabled(project(args.project), args.key, args.environment, args.enabled);
|
|
232
|
+
if (result.mode === "change-request") {
|
|
233
|
+
return ok(`Production changes need approval in this project, so a change request was opened (${result.changeRequest.id}). An admin must approve it in the console.`);
|
|
234
|
+
}
|
|
235
|
+
return ok(`${args.key} is now ${args.enabled ? "on" : "off"} in ${args.environment}.`);
|
|
236
|
+
}));
|
|
237
|
+
server.registerTool("update_targeting", {
|
|
238
|
+
title: "Update targeting",
|
|
239
|
+
description: "Change who gets a flag in one environment: strategy, constraints, variants, or segments. Production changes become a change request when the project requires approval.",
|
|
240
|
+
inputSchema: {
|
|
241
|
+
key: z.string(),
|
|
242
|
+
environment: z.string(),
|
|
243
|
+
strategy: strategySchema.optional(),
|
|
244
|
+
constraints: z.array(constraintSchema).optional(),
|
|
245
|
+
variants: z
|
|
246
|
+
.array(z.object({ name: z.string(), weight: z.number().int().min(0) }))
|
|
247
|
+
.optional(),
|
|
248
|
+
segmentIds: z.array(z.string()).optional(),
|
|
249
|
+
project: projectArg,
|
|
250
|
+
},
|
|
251
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
252
|
+
}, (args) => guarded(async () => {
|
|
253
|
+
const id = project(args.project);
|
|
254
|
+
const change = {};
|
|
255
|
+
if (args.strategy)
|
|
256
|
+
change.strategy = args.strategy;
|
|
257
|
+
if (args.constraints)
|
|
258
|
+
change.constraints = args.constraints;
|
|
259
|
+
if (args.variants)
|
|
260
|
+
change.variants = args.variants;
|
|
261
|
+
if (args.segmentIds)
|
|
262
|
+
change.segmentIds = args.segmentIds;
|
|
263
|
+
if (Object.keys(change).length === 0) {
|
|
264
|
+
return {
|
|
265
|
+
content: [
|
|
266
|
+
{
|
|
267
|
+
type: "text",
|
|
268
|
+
text: "Pass at least one of strategy, constraints, variants, or segmentIds.",
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
isError: true,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (args.environment === "production" && (await client.approvalRequired(id))) {
|
|
275
|
+
const current = (await client.getFlag(id, args.key)).environments.production;
|
|
276
|
+
if (!current)
|
|
277
|
+
return {
|
|
278
|
+
content: [{ type: "text", text: `${args.key} has no production settings.` }],
|
|
279
|
+
isError: true,
|
|
280
|
+
};
|
|
281
|
+
const { changeRequest } = await client.proposeProductionChange(id, args.key, {
|
|
282
|
+
...current,
|
|
283
|
+
...change,
|
|
284
|
+
});
|
|
285
|
+
return ok(`Production changes need approval in this project, so a change request was opened (${changeRequest.id}). An admin must approve it in the console.`);
|
|
286
|
+
}
|
|
287
|
+
const flag = await client.updateFlag(id, args.key, {
|
|
288
|
+
environments: { [args.environment]: change },
|
|
289
|
+
});
|
|
290
|
+
const config = flag.environments[args.environment];
|
|
291
|
+
return ok(`Updated ${args.key} in ${args.environment}: ${config ? describeStrategy(config.strategy) : "saved"}.`);
|
|
292
|
+
}));
|
|
293
|
+
server.registerTool("archive_flag", {
|
|
294
|
+
title: "Archive or restore a flag",
|
|
295
|
+
description: "Archive a flag so it stops being sent to apps, or restore it. Archived flags can always be restored.",
|
|
296
|
+
inputSchema: { key: z.string(), archived: z.boolean().default(true), project: projectArg },
|
|
297
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },
|
|
298
|
+
}, (args) => guarded(async () => {
|
|
299
|
+
await client.updateFlag(project(args.project), args.key, { archived: args.archived });
|
|
300
|
+
return ok(args.archived
|
|
301
|
+
? `Archived ${args.key}. Apps no longer receive it.`
|
|
302
|
+
: `Restored ${args.key}.`);
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
export { registerTools };
|
|
306
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|