@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 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`, `toggle_flag`,
45
- `update_flag_environment_config`, `get_targeting`, `update_targeting`, `manage_variation`, `list_segments`,
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-C5dAa5In.js";
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"];