@featureflip/mcp 0.1.8 → 0.1.9
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 -2
- package/dist/cli.mjs +1 -1
- package/dist/generated/api-types.d.ts +229 -12
- package/dist/generated/api-types.d.ts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{org-DZ1ge1Mx.js → org-8tn1Su68.js} +138 -91
- package/dist/tools/flags.d.ts.map +1 -1
- package/dist/tools/owner.d.ts +10 -0
- package/dist/tools/owner.d.ts.map +1 -0
- package/dist/tools/workflows/stale-flags.d.ts.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -41,8 +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`, `
|
|
45
|
-
`get_targeting`, `update_targeting`, `manage_variation`, `list_segments`,
|
|
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`
|
|
46
47
|
|
|
47
48
|
Webhooks (Admin token required): `list_webhooks`, `list_webhook_deliveries`, `manage_webhook`, `deliver_webhook`
|
|
48
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-8tn1Su68.js";
|
|
2
2
|
import { serveStdio as o } from "@modelcontextprotocol/server/stdio";
|
|
3
3
|
//#region src/unconfigured.ts
|
|
4
4
|
var s = class extends i {
|
|
@@ -993,9 +993,11 @@ export interface paths {
|
|
|
993
993
|
/**
|
|
994
994
|
* Sets the flag's advisory expiry date.
|
|
995
995
|
* @description Evaluation never changes when it passes — the flag is
|
|
996
|
-
* reported stale so it can be cleaned up. Requires at least Member.
|
|
997
|
-
*
|
|
998
|
-
*
|
|
996
|
+
* reported stale so it can be cleaned up. Requires at least Member. `expiresAtUtc` takes a
|
|
997
|
+
* date (`2026-12-01`), which means the end of that day in UTC, the same as picking it in the
|
|
998
|
+
* dashboard, or a full ISO-8601 timestamp, which is stored exactly. It must be in the future
|
|
999
|
+
* (400 `EXPIRY_IN_PAST`), so today's date is accepted, and the flag-expiration feature must
|
|
1000
|
+
* be enabled (400 `FEATURE_NOT_ENABLED`).
|
|
999
1001
|
*/
|
|
1000
1002
|
put: {
|
|
1001
1003
|
parameters: {
|
|
@@ -1369,6 +1371,197 @@ export interface paths {
|
|
|
1369
1371
|
patch?: never;
|
|
1370
1372
|
trace?: never;
|
|
1371
1373
|
};
|
|
1374
|
+
"/api/v1/orgs/{org}/projects/{project}/flags/{flag}/removal-pr": {
|
|
1375
|
+
parameters: {
|
|
1376
|
+
query?: never;
|
|
1377
|
+
header?: never;
|
|
1378
|
+
path?: never;
|
|
1379
|
+
cookie?: never;
|
|
1380
|
+
};
|
|
1381
|
+
get?: never;
|
|
1382
|
+
/**
|
|
1383
|
+
* Records the pull request that removes this flag from code, so the flag's owner is sent a link to it.
|
|
1384
|
+
* @description Called by the Featureflip Flag Cleanup Action. Requires at least Member. The URL
|
|
1385
|
+
* must be an https pull request URL (400 `validation_failed`).
|
|
1386
|
+
*/
|
|
1387
|
+
put: {
|
|
1388
|
+
parameters: {
|
|
1389
|
+
query?: never;
|
|
1390
|
+
header?: never;
|
|
1391
|
+
path: {
|
|
1392
|
+
org: string;
|
|
1393
|
+
project: string;
|
|
1394
|
+
flag: string;
|
|
1395
|
+
};
|
|
1396
|
+
cookie?: never;
|
|
1397
|
+
};
|
|
1398
|
+
requestBody?: {
|
|
1399
|
+
content: {
|
|
1400
|
+
"application/json": components["schemas"]["PublicSetFlagRemovalPrRequest"];
|
|
1401
|
+
"text/json": components["schemas"]["PublicSetFlagRemovalPrRequest"];
|
|
1402
|
+
"application/*+json": components["schemas"]["PublicSetFlagRemovalPrRequest"];
|
|
1403
|
+
};
|
|
1404
|
+
};
|
|
1405
|
+
responses: {
|
|
1406
|
+
/** @description No Content */
|
|
1407
|
+
204: {
|
|
1408
|
+
headers: {
|
|
1409
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1410
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1411
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1412
|
+
[name: string]: unknown;
|
|
1413
|
+
};
|
|
1414
|
+
content?: never;
|
|
1415
|
+
};
|
|
1416
|
+
/** @description Bad Request */
|
|
1417
|
+
400: {
|
|
1418
|
+
headers: {
|
|
1419
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1420
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1421
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1422
|
+
[name: string]: unknown;
|
|
1423
|
+
};
|
|
1424
|
+
content: {
|
|
1425
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1426
|
+
};
|
|
1427
|
+
};
|
|
1428
|
+
/** @description Authentication is required, or the supplied API token is invalid or expired. */
|
|
1429
|
+
401: {
|
|
1430
|
+
headers: {
|
|
1431
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1432
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1433
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1434
|
+
[name: string]: unknown;
|
|
1435
|
+
};
|
|
1436
|
+
content: {
|
|
1437
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1438
|
+
};
|
|
1439
|
+
};
|
|
1440
|
+
/** @description Forbidden */
|
|
1441
|
+
403: {
|
|
1442
|
+
headers: {
|
|
1443
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1444
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1445
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1446
|
+
[name: string]: unknown;
|
|
1447
|
+
};
|
|
1448
|
+
content: {
|
|
1449
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1450
|
+
};
|
|
1451
|
+
};
|
|
1452
|
+
/** @description Not Found */
|
|
1453
|
+
404: {
|
|
1454
|
+
headers: {
|
|
1455
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1456
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1457
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1458
|
+
[name: string]: unknown;
|
|
1459
|
+
};
|
|
1460
|
+
content: {
|
|
1461
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1462
|
+
};
|
|
1463
|
+
};
|
|
1464
|
+
/** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
|
|
1465
|
+
429: {
|
|
1466
|
+
headers: {
|
|
1467
|
+
/** @description Number of seconds to wait before retrying the request. */
|
|
1468
|
+
"Retry-After"?: number;
|
|
1469
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1470
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1471
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1472
|
+
[name: string]: unknown;
|
|
1473
|
+
};
|
|
1474
|
+
content: {
|
|
1475
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1476
|
+
};
|
|
1477
|
+
};
|
|
1478
|
+
};
|
|
1479
|
+
};
|
|
1480
|
+
post?: never;
|
|
1481
|
+
/**
|
|
1482
|
+
* Forgets the flag's removal pull request.
|
|
1483
|
+
* @description Requires at least Member.
|
|
1484
|
+
*/
|
|
1485
|
+
delete: {
|
|
1486
|
+
parameters: {
|
|
1487
|
+
query?: never;
|
|
1488
|
+
header?: never;
|
|
1489
|
+
path: {
|
|
1490
|
+
org: string;
|
|
1491
|
+
project: string;
|
|
1492
|
+
flag: string;
|
|
1493
|
+
};
|
|
1494
|
+
cookie?: never;
|
|
1495
|
+
};
|
|
1496
|
+
requestBody?: never;
|
|
1497
|
+
responses: {
|
|
1498
|
+
/** @description No Content */
|
|
1499
|
+
204: {
|
|
1500
|
+
headers: {
|
|
1501
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1502
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1503
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1504
|
+
[name: string]: unknown;
|
|
1505
|
+
};
|
|
1506
|
+
content?: never;
|
|
1507
|
+
};
|
|
1508
|
+
/** @description Authentication is required, or the supplied API token is invalid or expired. */
|
|
1509
|
+
401: {
|
|
1510
|
+
headers: {
|
|
1511
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1512
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1513
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1514
|
+
[name: string]: unknown;
|
|
1515
|
+
};
|
|
1516
|
+
content: {
|
|
1517
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1518
|
+
};
|
|
1519
|
+
};
|
|
1520
|
+
/** @description Forbidden */
|
|
1521
|
+
403: {
|
|
1522
|
+
headers: {
|
|
1523
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1524
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1525
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1526
|
+
[name: string]: unknown;
|
|
1527
|
+
};
|
|
1528
|
+
content: {
|
|
1529
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1530
|
+
};
|
|
1531
|
+
};
|
|
1532
|
+
/** @description Not Found */
|
|
1533
|
+
404: {
|
|
1534
|
+
headers: {
|
|
1535
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1536
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1537
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1538
|
+
[name: string]: unknown;
|
|
1539
|
+
};
|
|
1540
|
+
content: {
|
|
1541
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1542
|
+
};
|
|
1543
|
+
};
|
|
1544
|
+
/** @description Rate limit exceeded. Retry after the interval indicated by the Retry-After header. */
|
|
1545
|
+
429: {
|
|
1546
|
+
headers: {
|
|
1547
|
+
/** @description Number of seconds to wait before retrying the request. */
|
|
1548
|
+
"Retry-After"?: number;
|
|
1549
|
+
"X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
|
|
1550
|
+
"X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
|
|
1551
|
+
"X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
|
|
1552
|
+
[name: string]: unknown;
|
|
1553
|
+
};
|
|
1554
|
+
content: {
|
|
1555
|
+
"application/json": components["schemas"]["PublicApiErrorEnvelope"];
|
|
1556
|
+
};
|
|
1557
|
+
};
|
|
1558
|
+
};
|
|
1559
|
+
};
|
|
1560
|
+
options?: never;
|
|
1561
|
+
head?: never;
|
|
1562
|
+
patch?: never;
|
|
1563
|
+
trace?: never;
|
|
1564
|
+
};
|
|
1372
1565
|
"/api/v1/orgs/{org}/projects/{project}/flags/{flag}/archive": {
|
|
1373
1566
|
parameters: {
|
|
1374
1567
|
query?: never;
|
|
@@ -5414,8 +5607,8 @@ export interface paths {
|
|
|
5414
5607
|
/**
|
|
5415
5608
|
* Queues a finished delivery (succeeded or dead-lettered) to be sent again, restarting its retry schedule.
|
|
5416
5609
|
* @description Requires Admin. Refused with a 400 when the delivery is still pending, when
|
|
5417
|
-
* the subscription is disabled, or when the
|
|
5418
|
-
*
|
|
5610
|
+
* the subscription is disabled, or when the subscription's current project, environment or
|
|
5611
|
+
* event-type filters no longer cover the delivery's event.
|
|
5419
5612
|
*/
|
|
5420
5613
|
post: {
|
|
5421
5614
|
parameters: {
|
|
@@ -5557,10 +5750,10 @@ export interface components {
|
|
|
5557
5750
|
name?: string | null;
|
|
5558
5751
|
slug?: string | null;
|
|
5559
5752
|
/**
|
|
5560
|
-
* @description Allowed values: Solo, Pro, Business, Enterprise.
|
|
5753
|
+
* @description Allowed values: Solo, Team, Pro, Business, Enterprise.
|
|
5561
5754
|
* @enum {string|null}
|
|
5562
5755
|
*/
|
|
5563
|
-
plan?: "Solo" | "Pro" | "Business" | "Enterprise" | null;
|
|
5756
|
+
plan?: "Solo" | "Team" | "Pro" | "Business" | "Enterprise" | null;
|
|
5564
5757
|
isActive?: boolean;
|
|
5565
5758
|
/** Format: date-time */
|
|
5566
5759
|
createdAt?: string;
|
|
@@ -5648,9 +5841,13 @@ export interface components {
|
|
|
5648
5841
|
* `docsUrl`/`retryAfter`, breaking the published spec. !:JsonPropertyName
|
|
5649
5842
|
* always wins over the policy, so these are pinned explicitly rather than relying on the
|
|
5650
5843
|
* property names already being lowercase for the single-word ones.
|
|
5651
|
-
* `did_you_mean` and `
|
|
5652
|
-
* the global `DefaultIgnoreCondition = WhenWritingNull`), so
|
|
5653
|
-
* are byte-for-byte unchanged when they're absent.
|
|
5844
|
+
* `did_you_mean`, `next_actions` and `connection_id` are ADDITIVE optional keys
|
|
5845
|
+
* (null → omitted via the global `DefaultIgnoreCondition = WhenWritingNull`), so
|
|
5846
|
+
* pre-existing error bodies are byte-for-byte unchanged when they're absent.
|
|
5847
|
+
*
|
|
5848
|
+
* `connection_id` is present only on the `sso_required` error: the organization
|
|
5849
|
+
* requires single sign-on, and this credential didn't come through its identity provider.
|
|
5850
|
+
* `connection_id` identifies which SSO connection to sign in with.
|
|
5654
5851
|
* @example {
|
|
5655
5852
|
* "error": "not_found",
|
|
5656
5853
|
* "message": "Flag 'new-checkout-flw' was not found in project 'checkout'.",
|
|
@@ -5677,6 +5874,8 @@ export interface components {
|
|
|
5677
5874
|
retry_after?: number | null;
|
|
5678
5875
|
did_you_mean?: string[] | null;
|
|
5679
5876
|
next_actions?: components["schemas"]["NextAction"][] | null;
|
|
5877
|
+
/** Format: uuid */
|
|
5878
|
+
connection_id?: string | null;
|
|
5680
5879
|
};
|
|
5681
5880
|
/** @description Request-side condition group, symmetric with PublicConditionGroupResponse. */
|
|
5682
5881
|
PublicConditionGroupRequest: {
|
|
@@ -5756,7 +5955,8 @@ export interface components {
|
|
|
5756
5955
|
* is passed through verbatim to Type, which itself takes a
|
|
5757
5956
|
* bare string (Boolean/String/Number/Json) rather than the domain enum — invalid values surface
|
|
5758
5957
|
* as the handler's own validation failure, not a controller-level 400. ExpiresAtUtc is
|
|
5759
|
-
* optional and advisory;
|
|
5958
|
+
* optional and advisory; a bare date (`2026-12-01`) means the end of that day in UTC, and a full
|
|
5959
|
+
* timestamp is stored exactly. It must be in the future and requires the flag-expiration feature
|
|
5760
5960
|
* (400 `EXPIRY_IN_PAST` / `FEATURE_NOT_ENABLED`). OwnerEmail optionally names
|
|
5761
5961
|
* the owner (an active member, matched case-insensitively; requires the flag-ownership feature —
|
|
5762
5962
|
* 400 `OWNER_NOT_MEMBER` / `FEATURE_NOT_ENABLED`). Omitted, the owner is the caller when
|
|
@@ -6111,6 +6311,7 @@ export interface components {
|
|
|
6111
6311
|
/** Format: date-time */
|
|
6112
6312
|
expiresAtUtc?: string | null;
|
|
6113
6313
|
owner?: components["schemas"]["PublicFlagOwner"];
|
|
6314
|
+
removalPrUrl?: string | null;
|
|
6114
6315
|
};
|
|
6115
6316
|
/**
|
|
6116
6317
|
* @description A page of results plus an opaque cursor for the next page, or null when this is the last
|
|
@@ -6234,6 +6435,7 @@ export interface components {
|
|
|
6234
6435
|
/** Format: date-time */
|
|
6235
6436
|
expiresAtUtc?: string | null;
|
|
6236
6437
|
owner?: components["schemas"]["PublicFlagOwner"];
|
|
6438
|
+
removalPrUrl?: string | null;
|
|
6237
6439
|
/** @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. */
|
|
6238
6440
|
_actions?: {
|
|
6239
6441
|
[key: string]: components["schemas"]["ActionCapability"];
|
|
@@ -6406,7 +6608,8 @@ export interface components {
|
|
|
6406
6608
|
* @description Request body for `PUT /api/v1/orgs/{org}/projects/{project}/flags/{flag}/expiry`. Expiry is a
|
|
6407
6609
|
* dedicated sub-resource, deliberately NOT a field on PublicUpdateFeatureFlagRequest: that
|
|
6408
6610
|
* PUT is a full replace, so a new nullable field there would let any client that doesn't know about
|
|
6409
|
-
* expiry (the Terraform provider included) wipe it on every update.
|
|
6611
|
+
* expiry (the Terraform provider included) wipe it on every update. A bare date means the end of that
|
|
6612
|
+
* UTC day; a full timestamp is stored exactly.
|
|
6410
6613
|
*/
|
|
6411
6614
|
PublicSetFlagExpiryRequest: {
|
|
6412
6615
|
/** Format: date-time */
|
|
@@ -6421,6 +6624,15 @@ export interface components {
|
|
|
6421
6624
|
PublicSetFlagOwnerRequest: {
|
|
6422
6625
|
email?: string | null;
|
|
6423
6626
|
};
|
|
6627
|
+
/**
|
|
6628
|
+
* @description Request body for `PUT /api/v1/orgs/{org}/projects/{project}/flags/{flag}/removal-pr`: the
|
|
6629
|
+
* pull request that removes this flag from code, as opened by the Featureflip Flag Cleanup Action.
|
|
6630
|
+
* A dedicated sub-resource for the same reason as expiry and owner. `url` must be an https
|
|
6631
|
+
* pull request URL (`https://{host}/{owner}/{repo}/pull/{number}`).
|
|
6632
|
+
*/
|
|
6633
|
+
PublicSetFlagRemovalPrRequest: {
|
|
6634
|
+
url?: string | null;
|
|
6635
|
+
};
|
|
6424
6636
|
/**
|
|
6425
6637
|
* @description The full targeting configuration for a flag in a single environment, returned by
|
|
6426
6638
|
* `GET .../targeting`. Maps 1:1 onto TargetingConfigurationDto — including
|
|
@@ -6696,6 +6908,10 @@ export interface components {
|
|
|
6696
6908
|
/**
|
|
6697
6909
|
* @description A webhook subscription. Never carries secret material: signing secrets are listed by id and
|
|
6698
6910
|
* lifecycle only — the value itself is returned once, when it is created or rotated.
|
|
6911
|
+
* `overPlanLimit` is true when the organization has more subscriptions than its plan
|
|
6912
|
+
* allows, which happens after a downgrade. The oldest subscriptions up to the limit keep
|
|
6913
|
+
* delivering. The rest receive nothing and cannot be re-enabled, tested or redelivered to until
|
|
6914
|
+
* the plan is upgraded or older subscriptions are deleted.
|
|
6699
6915
|
* @example {
|
|
6700
6916
|
* "id": "0197b6a4-6f7a-7b8c-9d0e-1f2a3b4c5d6e",
|
|
6701
6917
|
* "name": "Checkout flag changes to Slack relay",
|
|
@@ -6746,6 +6962,7 @@ export interface components {
|
|
|
6746
6962
|
/** Format: date-time */
|
|
6747
6963
|
updatedAt?: string;
|
|
6748
6964
|
secrets?: components["schemas"]["PublicWebhookSecretResponse"][] | null;
|
|
6965
|
+
overPlanLimit?: boolean;
|
|
6749
6966
|
/** @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. */
|
|
6750
6967
|
_actions?: {
|
|
6751
6968
|
[key: string]: components["schemas"]["ActionCapability"];
|