@featureflip/mcp 0.1.10 → 0.1.11
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 +3 -3
- package/dist/cli.mjs +1 -1
- package/dist/generated/api-types.d.ts +198 -2
- package/dist/generated/api-types.d.ts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{org-C5dAa5In.js → org-c4iWMSzU.js} +31 -10
- package/dist/tools/flags.d.ts.map +1 -1
- package/dist/tools/workflows/stale-flags.d.ts.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -41,9 +41,9 @@ claude mcp add featureflip -e FEATUREFLIP_TOKEN=ffp_your_token -- npx -y @featur
|
|
|
41
41
|
## Tools
|
|
42
42
|
|
|
43
43
|
CRUD: `list_projects`, `list_environments`, `list_flags`, `get_flag`, `create_flag`, `update_flag`,
|
|
44
|
-
`delete_flag`, `archive_flag`, `restore_flag`, `set_flag_expiry`, `set_flag_owner`, `
|
|
45
|
-
`update_flag_environment_config`, `get_targeting`, `update_targeting`, `manage_variation`,
|
|
46
|
-
`get_segment`
|
|
44
|
+
`delete_flag`, `archive_flag`, `restore_flag`, `set_flag_expiry`, `set_flag_owner`, `set_flag_permanent`,
|
|
45
|
+
`toggle_flag`, `update_flag_environment_config`, `get_targeting`, `update_targeting`, `manage_variation`,
|
|
46
|
+
`list_segments`, `get_segment`
|
|
47
47
|
|
|
48
48
|
Webhooks (Admin token required): `list_webhooks`, `list_webhook_deliveries`, `manage_webhook`, `deliver_webhook`
|
|
49
49
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, s as i, t as a } from "./org-
|
|
1
|
+
import { a as e, i as t, n, o as r, s as i, t as a } from "./org-c4iWMSzU.js";
|
|
2
2
|
import { serveStdio as o } from "@modelcontextprotocol/server/stdio";
|
|
3
3
|
//#region src/unconfigured.ts
|
|
4
4
|
var s = class extends i {
|
|
@@ -445,6 +445,7 @@ export interface paths {
|
|
|
445
445
|
* Decode's "garbage input degrades gracefully" precedent)
|
|
446
446
|
* rather than a 400, since it's a non-critical list filter, not a mutation. `owner` filters
|
|
447
447
|
* by owner: an email (an active member, case-insensitive) or `none` for unowned flags.
|
|
448
|
+
* `permanent` filters to permanent (`true`) or temporary (`false`) flags.
|
|
448
449
|
*/
|
|
449
450
|
get: {
|
|
450
451
|
parameters: {
|
|
@@ -456,6 +457,7 @@ export interface paths {
|
|
|
456
457
|
limit?: number;
|
|
457
458
|
cursor?: string;
|
|
458
459
|
owner?: string;
|
|
460
|
+
permanent?: boolean;
|
|
459
461
|
};
|
|
460
462
|
header?: never;
|
|
461
463
|
path: {
|
|
@@ -1001,7 +1003,8 @@ export interface paths {
|
|
|
1001
1003
|
* date (`2026-12-01`), which means the end of that day in UTC, the same as picking it in the
|
|
1002
1004
|
* dashboard, or a full ISO-8601 timestamp, which is stored exactly. It must be in the future
|
|
1003
1005
|
* (400 `EXPIRY_IN_PAST`), so today's date is accepted, and the flag-expiration feature must
|
|
1004
|
-
* be enabled (400 `FEATURE_NOT_ENABLED`).
|
|
1006
|
+
* be enabled (400 `FEATURE_NOT_ENABLED`). A permanent flag can't have a date
|
|
1007
|
+
* (400 `PERMANENT_FLAG_HAS_EXPIRY`).
|
|
1005
1008
|
*/
|
|
1006
1009
|
put: {
|
|
1007
1010
|
parameters: {
|
|
@@ -1375,6 +1378,193 @@ export interface paths {
|
|
|
1375
1378
|
patch?: never;
|
|
1376
1379
|
trace?: never;
|
|
1377
1380
|
};
|
|
1381
|
+
"/api/v1/orgs/{org}/projects/{project}/flags/{flag}/permanent": {
|
|
1382
|
+
parameters: {
|
|
1383
|
+
query?: never;
|
|
1384
|
+
header?: never;
|
|
1385
|
+
path?: never;
|
|
1386
|
+
cookie?: never;
|
|
1387
|
+
};
|
|
1388
|
+
get?: never;
|
|
1389
|
+
/**
|
|
1390
|
+
* Marks the flag permanent: a kill switch, ops toggle or entitlement gate that is meant to stay.
|
|
1391
|
+
* @description A permanent flag is never offered as a removal candidate and never reported past expiry.
|
|
1392
|
+
* Requires at least Member. The flag can't have an expiry date (400 `PERMANENT_FLAG_HAS_EXPIRY`;
|
|
1393
|
+
* remove the date first) and the flag-permanence feature must be enabled (400 `FEATURE_NOT_ENABLED`).
|
|
1394
|
+
*/
|
|
1395
|
+
put: {
|
|
1396
|
+
parameters: {
|
|
1397
|
+
query?: never;
|
|
1398
|
+
header?: never;
|
|
1399
|
+
path: {
|
|
1400
|
+
org: string;
|
|
1401
|
+
project: string;
|
|
1402
|
+
flag: string;
|
|
1403
|
+
};
|
|
1404
|
+
cookie?: never;
|
|
1405
|
+
};
|
|
1406
|
+
requestBody?: never;
|
|
1407
|
+
responses: {
|
|
1408
|
+
/** @description No Content */
|
|
1409
|
+
204: {
|
|
1410
|
+
headers: {
|
|
1411
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1412
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1413
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1414
|
+
[name: string]: unknown;
|
|
1415
|
+
};
|
|
1416
|
+
content?: never;
|
|
1417
|
+
};
|
|
1418
|
+
/** @description Bad Request */
|
|
1419
|
+
400: {
|
|
1420
|
+
headers: {
|
|
1421
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1422
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1423
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1424
|
+
[name: string]: unknown;
|
|
1425
|
+
};
|
|
1426
|
+
content: {
|
|
1427
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1428
|
+
};
|
|
1429
|
+
};
|
|
1430
|
+
/** @description Authentication is required, or the supplied API token is invalid or expired. */
|
|
1431
|
+
401: {
|
|
1432
|
+
headers: {
|
|
1433
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1434
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1435
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1436
|
+
[name: string]: unknown;
|
|
1437
|
+
};
|
|
1438
|
+
content: {
|
|
1439
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1440
|
+
};
|
|
1441
|
+
};
|
|
1442
|
+
/** @description Forbidden */
|
|
1443
|
+
403: {
|
|
1444
|
+
headers: {
|
|
1445
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1446
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1447
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1448
|
+
[name: string]: unknown;
|
|
1449
|
+
};
|
|
1450
|
+
content: {
|
|
1451
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1452
|
+
};
|
|
1453
|
+
};
|
|
1454
|
+
/** @description Not Found */
|
|
1455
|
+
404: {
|
|
1456
|
+
headers: {
|
|
1457
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1458
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1459
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1460
|
+
[name: string]: unknown;
|
|
1461
|
+
};
|
|
1462
|
+
content: {
|
|
1463
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1464
|
+
};
|
|
1465
|
+
};
|
|
1466
|
+
/** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
|
|
1467
|
+
429: {
|
|
1468
|
+
headers: {
|
|
1469
|
+
/** @description Number of seconds to wait before retrying the request. */
|
|
1470
|
+
"Retry-After"?: number;
|
|
1471
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1472
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1473
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1474
|
+
[name: string]: unknown;
|
|
1475
|
+
};
|
|
1476
|
+
content: {
|
|
1477
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1478
|
+
};
|
|
1479
|
+
};
|
|
1480
|
+
};
|
|
1481
|
+
};
|
|
1482
|
+
post?: never;
|
|
1483
|
+
/**
|
|
1484
|
+
* Makes the flag temporary again.
|
|
1485
|
+
* @description Requires at least Member. Always allowed, even when the
|
|
1486
|
+
* flag-permanence feature is disabled.
|
|
1487
|
+
*/
|
|
1488
|
+
delete: {
|
|
1489
|
+
parameters: {
|
|
1490
|
+
query?: never;
|
|
1491
|
+
header?: never;
|
|
1492
|
+
path: {
|
|
1493
|
+
org: string;
|
|
1494
|
+
project: string;
|
|
1495
|
+
flag: string;
|
|
1496
|
+
};
|
|
1497
|
+
cookie?: never;
|
|
1498
|
+
};
|
|
1499
|
+
requestBody?: never;
|
|
1500
|
+
responses: {
|
|
1501
|
+
/** @description No Content */
|
|
1502
|
+
204: {
|
|
1503
|
+
headers: {
|
|
1504
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1505
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1506
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1507
|
+
[name: string]: unknown;
|
|
1508
|
+
};
|
|
1509
|
+
content?: never;
|
|
1510
|
+
};
|
|
1511
|
+
/** @description Authentication is required, or the supplied API token is invalid or expired. */
|
|
1512
|
+
401: {
|
|
1513
|
+
headers: {
|
|
1514
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1515
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1516
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1517
|
+
[name: string]: unknown;
|
|
1518
|
+
};
|
|
1519
|
+
content: {
|
|
1520
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1521
|
+
};
|
|
1522
|
+
};
|
|
1523
|
+
/** @description Forbidden */
|
|
1524
|
+
403: {
|
|
1525
|
+
headers: {
|
|
1526
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1527
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1528
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1529
|
+
[name: string]: unknown;
|
|
1530
|
+
};
|
|
1531
|
+
content: {
|
|
1532
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1533
|
+
};
|
|
1534
|
+
};
|
|
1535
|
+
/** @description Not Found */
|
|
1536
|
+
404: {
|
|
1537
|
+
headers: {
|
|
1538
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1539
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1540
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1541
|
+
[name: string]: unknown;
|
|
1542
|
+
};
|
|
1543
|
+
content: {
|
|
1544
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1545
|
+
};
|
|
1546
|
+
};
|
|
1547
|
+
/** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
|
|
1548
|
+
429: {
|
|
1549
|
+
headers: {
|
|
1550
|
+
/** @description Number of seconds to wait before retrying the request. */
|
|
1551
|
+
"Retry-After"?: number;
|
|
1552
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1553
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1554
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1555
|
+
[name: string]: unknown;
|
|
1556
|
+
};
|
|
1557
|
+
content: {
|
|
1558
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1559
|
+
};
|
|
1560
|
+
};
|
|
1561
|
+
};
|
|
1562
|
+
};
|
|
1563
|
+
options?: never;
|
|
1564
|
+
head?: never;
|
|
1565
|
+
patch?: never;
|
|
1566
|
+
trace?: never;
|
|
1567
|
+
};
|
|
1378
1568
|
"/api/v1/orgs/{org}/projects/{project}/flags/{flag}/removal-pr": {
|
|
1379
1569
|
parameters: {
|
|
1380
1570
|
query?: never;
|
|
@@ -5964,7 +6154,10 @@ export interface components {
|
|
|
5964
6154
|
* (400 `EXPIRY_IN_PAST` / `FEATURE_NOT_ENABLED`). OwnerEmail optionally names
|
|
5965
6155
|
* the owner (an active member, matched case-insensitively; requires the flag-ownership feature —
|
|
5966
6156
|
* 400 `OWNER_NOT_MEMBER` / `FEATURE_NOT_ENABLED`). Omitted, the owner is the caller when
|
|
5967
|
-
* the caller is a member, so a service token creates an unowned flag.
|
|
6157
|
+
* the caller is a member, so a service token creates an unowned flag. IsPermanent marks
|
|
6158
|
+
* the flag permanent (a kill switch, ops toggle or entitlement that is meant to stay; never reported for
|
|
6159
|
+
* cleanup). It requires the flag-permanence feature and can't be combined with ExpiresAtUtc
|
|
6160
|
+
* (400 `FEATURE_NOT_ENABLED` / `PERMANENT_FLAG_HAS_EXPIRY`).
|
|
5968
6161
|
* @example {
|
|
5969
6162
|
* "key": "new-checkout-flow",
|
|
5970
6163
|
* "name": "New Checkout Flow",
|
|
@@ -6006,6 +6199,7 @@ export interface components {
|
|
|
6006
6199
|
/** Format: date-time */
|
|
6007
6200
|
expiresAtUtc?: string | null;
|
|
6008
6201
|
ownerEmail?: string | null;
|
|
6202
|
+
isPermanent?: boolean;
|
|
6009
6203
|
};
|
|
6010
6204
|
/**
|
|
6011
6205
|
* @description Request body for `POST /api/v1/orgs/{org}/projects`. Named distinctly from the
|
|
@@ -6316,6 +6510,7 @@ export interface components {
|
|
|
6316
6510
|
expiresAtUtc?: string | null;
|
|
6317
6511
|
owner?: components["schemas"]["PublicFlagOwner"];
|
|
6318
6512
|
removalPrUrl?: string | null;
|
|
6513
|
+
isPermanent?: boolean;
|
|
6319
6514
|
};
|
|
6320
6515
|
/**
|
|
6321
6516
|
* @description A page of results plus an opaque cursor for the next page, or null when this is the last
|
|
@@ -6443,6 +6638,7 @@ export interface components {
|
|
|
6443
6638
|
expiresAtUtc?: string | null;
|
|
6444
6639
|
owner?: components["schemas"]["PublicFlagOwner"];
|
|
6445
6640
|
removalPrUrl?: string | null;
|
|
6641
|
+
isPermanent?: boolean;
|
|
6446
6642
|
/** @description Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it. */
|
|
6447
6643
|
_actions?: {
|
|
6448
6644
|
[key: string]: components["schemas"]["ActionCapability"];
|