@configcat/mcp-server 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/DEPLOY.md +3 -1
- package/build/index.js +1 -1
- package/build/tools/configcat-api.js +69 -13
- package/package.json +1 -1
- package/server.json +2 -2
package/DEPLOY.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Steps to deploy
|
|
2
2
|
## Preparation
|
|
3
3
|
1. Increase the `serverVersion` in [src/index.ts](src/index.ts).
|
|
4
|
-
2.
|
|
4
|
+
2. Increase the `version` in [server.json](server.json).
|
|
5
|
+
3. Increase the `version` in [package.json](package.json).
|
|
6
|
+
4. Commit & Push
|
|
5
7
|
## Publish
|
|
6
8
|
Use the **same version** for the git tag as in [src/index.ts](src/index.ts).
|
|
7
9
|
- Via git tag
|
package/build/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const baseUrl = process.env.CONFIGCAT_BASE_URL ?? "https://api.configcat.com";
|
|
|
8
8
|
const username = process.env.CONFIGCAT_API_USER ?? "";
|
|
9
9
|
const password = process.env.CONFIGCAT_API_PASS ?? "";
|
|
10
10
|
const serverName = "ConfigCat MCP";
|
|
11
|
-
const serverVersion = "0.1.
|
|
11
|
+
const serverVersion = "0.1.5";
|
|
12
12
|
const http = new HttpClient({ baseUrl, username, password, userAgent: `${serverName}/${serverVersion}` });
|
|
13
13
|
const server = new McpServer({ name: serverName, version: serverVersion }, { capabilities: { tools: {} } });
|
|
14
14
|
async function main() {
|
|
@@ -185,6 +185,7 @@ The Parameters dictionary differs for each IntegrationType:
|
|
|
185
185
|
- Slack
|
|
186
186
|
Connecting the Slack integration through the Public Management API will not post messages with the ConfigCat Feature Flags Slack app but with an incoming webhook.
|
|
187
187
|
- \`incoming_webhook.url\`: Required. The [incoming webhook URL](https://api.slack.com/messaging/webhooks) where the integration should post messages.
|
|
188
|
+
- \`includeSensitiveData\`: Set to "true" to include [sensitive (hashed) comparison values](https://configcat.com/docs/targeting/targeting-rule/user-condition/#confidential-text-comparators). By default, the integration will mask these values in the posted messages. We recommend hiding sensitive comparison values for shared or public Slack channels.
|
|
188
189
|
- Amplitude
|
|
189
190
|
- \`apiKey\`: Required. Amplitude API Key.
|
|
190
191
|
- \`secretKey\`: Required. Amplitude Secret Key.
|
|
@@ -201,10 +202,10 @@ The Parameters dictionary differs for each IntegrationType:
|
|
|
201
202
|
productId: z.string().uuid().describe("The identifier of the Product."),
|
|
202
203
|
requestBody: z.object({
|
|
203
204
|
integrationType: z.enum(["dataDog", "slack", "amplitude", "mixPanel", "segment", "pubNub"]),
|
|
204
|
-
name: z.string().min(1).describe("Name of the Integration."),
|
|
205
|
+
name: z.string().min(1).max(255).describe("Name of the Integration."),
|
|
205
206
|
parameters: z.record(z.string().nullable()).describe("Parameters of the Integration."),
|
|
206
|
-
environmentIds: z.array(z.string().uuid()).describe("List of Environment IDs that are connected with this Integration. If the list is empty, all
|
|
207
|
-
configIds: z.array(z.string().uuid()).describe("List of Config IDs that are connected with this Integration. If the list is empty, all
|
|
207
|
+
environmentIds: z.array(z.string().uuid()).describe("List of Environment IDs that are connected with this Integration. If the list is empty, all the Environments are connected."),
|
|
208
|
+
configIds: z.array(z.string().uuid()).describe("List of Config IDs that are connected with this Integration. If the list is empty, all the Configs are connected."),
|
|
208
209
|
}),
|
|
209
210
|
},
|
|
210
211
|
method: "post",
|
|
@@ -272,9 +273,19 @@ identified by the \`configId\` parameter.
|
|
|
272
273
|
key: z.string().min(1).max(255).describe("The key of the Feature Flag or Setting."),
|
|
273
274
|
name: z.string().min(1).max(255).describe("The name of the Feature Flag or Setting."),
|
|
274
275
|
settingType: z.enum(["boolean", "string", "int", "double"]).describe("The type of the Feature Flag or Setting."),
|
|
276
|
+
predefinedVariations: z.array(z.object({
|
|
277
|
+
value: z.object({
|
|
278
|
+
boolValue: z.boolean().nullable().optional().describe("The served value in case of a boolean Feature Flag."),
|
|
279
|
+
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
280
|
+
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
281
|
+
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
282
|
+
}).describe("Represents the value of a Predefined Variation."),
|
|
283
|
+
name: z.string().min(0).max(255).nullable().optional().describe("The name of the Predefined Variation, shown on the Dashboard UI. If not set, the Value will be shown."),
|
|
284
|
+
hint: z.string().min(0).max(1000).nullable().optional().describe("The name of the Predefined Variation, shown on the Dashboard UI. If not set, the Value will be shown."),
|
|
285
|
+
}).describe("A Predefined Variation.")).nullable().optional().describe("The Feature Flag or Setting's Variations."),
|
|
275
286
|
initialValues: z.array(z.object({
|
|
276
287
|
environmentId: z.string().uuid().describe("The ID of the Environment where the initial value must be set."),
|
|
277
|
-
value: z.union([z.boolean(), z.string(), z.number()]).describe("The initial value in the given Environment. It must respect the setting type. In some generated clients for strictly typed languages you may use double/float properties to handle integer values."),
|
|
288
|
+
value: z.union([z.boolean(), z.string(), z.number()]).describe("The initial value in the given Environment. It must respect the setting type. In some generated clients for strictly typed languages, you may use double/float properties to handle integer values. In case of a Feature Flag with predefined variations, the value must match one of the predefined variations' value."),
|
|
278
289
|
})).nullable().optional().describe("Optional, initial value of the Feature Flag or Setting in the given Environments. Only one of the SettingIdToInitFrom or the InitialValues properties can be set."),
|
|
279
290
|
settingIdToInitFrom: z.number().int().nullable().optional().describe("Optional, the SettingId to initialize the values and tags of the Feature Flag or Setting from. Only can be set if you have at least ReadOnly access in all the Environments. Only one of the SettingIdToInitFrom or the InitialValues properties can be set."),
|
|
280
291
|
}),
|
|
@@ -301,7 +312,8 @@ The distance between \`fromUtcDateTime\` and \`toUtcDateTime\` cannot exceed **3
|
|
|
301
312
|
"teamMemberRemoved", "teamMemberLeft", "teamMemberInvitationChanged", "teamMemberInvitationResent",
|
|
302
313
|
"teamMemberInvitationRejected", "configCreated", "configChanged", "configDeleted", "configsReordered",
|
|
303
314
|
"environmentCreated", "environmentChanged", "environmentDeleted", "environmentsReordered", "settingCreated",
|
|
304
|
-
"settingChanged", "settingDeleted", "settingsReordered", "
|
|
315
|
+
"settingChanged", "settingDeleted", "settingsReordered", "predefinedVariationsChanged",
|
|
316
|
+
"settingConvertedToPredefinedVariations", "settingConvertedToFreeFormValues", "settingValueChanged", "webHookCreated",
|
|
305
317
|
"webHookChanged", "webHookDeleted", "permissionGroupCreated", "permissionGroupChanged", "permissionGroupDeleted",
|
|
306
318
|
"permissionGroupDefault", "apiKeyAdded", "apiKeyRemoved", "integrationAdded", "integrationChanged",
|
|
307
319
|
"integrationRemoved", "apiKeyConnected", "integrationLinkAdded", "integrationLinkRemoved", "organizationAdded",
|
|
@@ -513,6 +525,7 @@ The Parameters dictionary differs for each IntegrationType:
|
|
|
513
525
|
- Slack
|
|
514
526
|
Connecting the Slack integration through the Public Management API will not post messages with the ConfigCat Feature Flags Slack app but with an incoming webhook.
|
|
515
527
|
- \`incoming_webhook.url\`: Required. The [incoming webhook URL](https://api.slack.com/messaging/webhooks) where the integration should post messages.
|
|
528
|
+
- \`includeSensitiveData\`: Set to "true" to include [sensitive (hashed) comparison values](https://configcat.com/docs/targeting/targeting-rule/user-condition/#confidential-text-comparators). By default, the integration will mask these values in the posted messages. We recommend hiding sensitive comparison values for shared or public Slack channels.
|
|
516
529
|
- Amplitude
|
|
517
530
|
- \`apiKey\`: Required. Amplitude API Key.
|
|
518
531
|
- \`secretKey\`: Required. Amplitude Secret Key.
|
|
@@ -528,10 +541,10 @@ The Parameters dictionary differs for each IntegrationType:
|
|
|
528
541
|
inputSchema: {
|
|
529
542
|
integrationId: z.string().uuid().describe("The identifier of the Integration."),
|
|
530
543
|
requestBody: z.object({
|
|
531
|
-
name: z.string().min(1).describe("Name of the Integration."),
|
|
544
|
+
name: z.string().min(1).max(255).describe("Name of the Integration."),
|
|
532
545
|
parameters: z.record(z.string().nullable()).describe("Parameters of the Integration."),
|
|
533
|
-
environmentIds: z.array(z.string().uuid()).describe("List of Environment IDs that are connected with this Integration. If the list is empty, all
|
|
534
|
-
configIds: z.array(z.string().uuid()).describe("List of Config IDs that are connected with this Integration. If the list is empty, all
|
|
546
|
+
environmentIds: z.array(z.string().uuid()).describe("List of Environment IDs that are connected with this Integration. If the list is empty, all the Environments are connected."),
|
|
547
|
+
configIds: z.array(z.string().uuid()).describe("List of Config IDs that are connected with this Integration. If the list is empty, all the Configs are connected."),
|
|
535
548
|
}),
|
|
536
549
|
},
|
|
537
550
|
method: "put",
|
|
@@ -578,7 +591,8 @@ The distance between \`fromUtcDateTime\` and \`toUtcDateTime\` cannot exceed **3
|
|
|
578
591
|
"teamMemberRemoved", "teamMemberLeft", "teamMemberInvitationChanged", "teamMemberInvitationResent",
|
|
579
592
|
"teamMemberInvitationRejected", "configCreated", "configChanged", "configDeleted", "configsReordered",
|
|
580
593
|
"environmentCreated", "environmentChanged", "environmentDeleted", "environmentsReordered", "settingCreated",
|
|
581
|
-
"settingChanged", "settingDeleted", "settingsReordered", "
|
|
594
|
+
"settingChanged", "settingDeleted", "settingsReordered", "predefinedVariationsChanged",
|
|
595
|
+
"settingConvertedToPredefinedVariations", "settingConvertedToFreeFormValues", "settingValueChanged", "webHookCreated",
|
|
582
596
|
"webHookChanged", "webHookDeleted", "permissionGroupCreated", "permissionGroupChanged", "permissionGroupDeleted",
|
|
583
597
|
"permissionGroupDefault", "apiKeyAdded", "apiKeyRemoved", "integrationAdded", "integrationChanged",
|
|
584
598
|
"integrationRemoved", "apiKeyConnected", "integrationLinkAdded", "integrationLinkRemoved", "organizationAdded",
|
|
@@ -643,6 +657,40 @@ given Product identified by the \`productId\` parameter.`,
|
|
|
643
657
|
pathTemplate: "/v1/products/{productId}/invitations",
|
|
644
658
|
executionParameters: [{ "name": "productId", "in": "path" }],
|
|
645
659
|
}],
|
|
660
|
+
["list-predefined-variations", {
|
|
661
|
+
name: "list-predefined-variations",
|
|
662
|
+
description: "This endpoint returns the predefined variations along with their usages in the Environments for a Feature Flag or Setting identified by the `settingId` parameter.",
|
|
663
|
+
inputSchema: {
|
|
664
|
+
settingId: z.number().int().describe("The identifier of the Setting."),
|
|
665
|
+
},
|
|
666
|
+
method: "get",
|
|
667
|
+
pathTemplate: "/v1/settings/{settingId}/predefined-variations",
|
|
668
|
+
executionParameters: [{ "name": "settingId", "in": "path" }],
|
|
669
|
+
}],
|
|
670
|
+
["update-predefined-variations", {
|
|
671
|
+
name: "update-predefined-variations",
|
|
672
|
+
description: `This endpoint updates the predefined variations for a Feature Flag or Setting identified by the \`settingId\` parameter.
|
|
673
|
+
**Important:** You can only update a predefined variation's value if it is not used anywhere in your feature flags.`,
|
|
674
|
+
inputSchema: {
|
|
675
|
+
settingId: z.number().int().describe("The identifier of the Setting."),
|
|
676
|
+
requestBody: z.object({
|
|
677
|
+
predefinedVariations: z.array(z.object({
|
|
678
|
+
value: z.object({
|
|
679
|
+
boolValue: z.boolean().nullable().optional().describe("The served value in case of a boolean Feature Flag."),
|
|
680
|
+
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
681
|
+
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
682
|
+
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
683
|
+
}).describe("Represents the value of a Predefined Variation."),
|
|
684
|
+
name: z.string().min(0).max(255).nullable().optional().describe("The name of the Predefined Variation, shown on the Dashboard UI. If not set, the Value will be shown."),
|
|
685
|
+
hint: z.string().min(0).max(1000).nullable().optional().describe("The name of the Predefined Variation, shown on the Dashboard UI. If not set, the Value will be shown."),
|
|
686
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The Predefined Variation's identifier to update. Omit the value if you want to add a new predefined variation."),
|
|
687
|
+
}).describe("A Predefined Variation.")).describe("A collection of Predefined Variations."),
|
|
688
|
+
}),
|
|
689
|
+
},
|
|
690
|
+
method: "put",
|
|
691
|
+
pathTemplate: "/v1/settings/{settingId}/predefined-variations",
|
|
692
|
+
executionParameters: [{ "name": "settingId", "in": "path" }],
|
|
693
|
+
}],
|
|
646
694
|
["get-product", {
|
|
647
695
|
name: "get-product",
|
|
648
696
|
description: `This endpoint returns the metadata of a Product
|
|
@@ -786,10 +834,10 @@ want to change in its original state. Not listing one means it will reset.`,
|
|
|
786
834
|
inputSchema: {
|
|
787
835
|
settingId: z.number().int().describe("The identifier of the Setting."),
|
|
788
836
|
requestBody: z.object({
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
837
|
+
name: z.string().min(1).max(255).describe("The name of the Feature Flag or Setting."),
|
|
838
|
+
hint: z.string().min(0).max(1000).nullable().optional().describe("A short description for the setting, shown on the Dashboard UI."),
|
|
839
|
+
tags: z.array(z.number().int()).nullable().optional().describe("The IDs of the tags which are attached to the setting."),
|
|
840
|
+
order: z.number().int().nullable().optional().describe("The order of the Setting represented on the ConfigCat Dashboard. Determined from an ascending sequence of integers."),
|
|
793
841
|
}),
|
|
794
842
|
},
|
|
795
843
|
method: "put",
|
|
@@ -1158,6 +1206,7 @@ So we get a response like this:
|
|
|
1158
1206
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1159
1207
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1160
1208
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1209
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1161
1210
|
}).describe("Represents the value of a Feature Flag or Setting."),
|
|
1162
1211
|
targetingRules: z.array(z.object({
|
|
1163
1212
|
conditions: z.array(z.object({
|
|
@@ -1185,6 +1234,7 @@ So we get a response like this:
|
|
|
1185
1234
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1186
1235
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1187
1236
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1237
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1188
1238
|
}).describe("Represents the value of a Feature Flag or Setting."),
|
|
1189
1239
|
}).nullable().optional().describe("Describes a condition that is based on a prerequisite flag."),
|
|
1190
1240
|
})).nullable().optional().describe("The list of conditions that are combined with logical AND operators. It can be one of the following: User condition, Segment condition, Prerequisite flag condition"),
|
|
@@ -1195,6 +1245,7 @@ So we get a response like this:
|
|
|
1195
1245
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1196
1246
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1197
1247
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1248
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1198
1249
|
}).describe("Represents the value of a Feature Flag or Setting."),
|
|
1199
1250
|
})).nullable().optional().describe("The percentage options from where the evaluation process will choose a value based on the flag's percentage evaluation attribute."),
|
|
1200
1251
|
value: z.object({
|
|
@@ -1202,6 +1253,7 @@ So we get a response like this:
|
|
|
1202
1253
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1203
1254
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1204
1255
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1256
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1205
1257
|
}).nullable().optional().describe("Represents the value of a Feature Flag or Setting."),
|
|
1206
1258
|
})).nullable().optional().describe("The targeting rules of the Feature Flag or Setting."),
|
|
1207
1259
|
percentageEvaluationAttribute: z.string().max(1000).nullable().optional().describe("The user attribute used for percentage evaluation. If not set, it defaults to the `Identifier` user object attribute."),
|
|
@@ -1523,6 +1575,7 @@ So we get a response like this:
|
|
|
1523
1575
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1524
1576
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1525
1577
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1578
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1526
1579
|
}).describe("Represents the value of a Feature Flag or Setting."),
|
|
1527
1580
|
targetingRules: z.array(z.object({
|
|
1528
1581
|
conditions: z.array(z.object({
|
|
@@ -1550,6 +1603,7 @@ So we get a response like this:
|
|
|
1550
1603
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1551
1604
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1552
1605
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1606
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1553
1607
|
}).describe("Represents the value of a Feature Flag or Setting."),
|
|
1554
1608
|
}).nullable().optional(),
|
|
1555
1609
|
})).nullable().optional(),
|
|
@@ -1560,6 +1614,7 @@ So we get a response like this:
|
|
|
1560
1614
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1561
1615
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1562
1616
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1617
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1563
1618
|
}).describe("Represents the value of a Feature Flag or Setting."),
|
|
1564
1619
|
})).nullable().optional().describe("The percentage options from where the evaluation process will choose a value based on the flag's percentage evaluation attribute."),
|
|
1565
1620
|
value: z.object({
|
|
@@ -1567,6 +1622,7 @@ So we get a response like this:
|
|
|
1567
1622
|
stringValue: z.string().nullable().optional().describe("The served value in case of a text Setting."),
|
|
1568
1623
|
intValue: z.number().int().nullable().optional().describe("The served value in case of a whole number Setting."),
|
|
1569
1624
|
doubleValue: z.number().nullable().optional().describe("The served value in case of a decimal number Setting."),
|
|
1625
|
+
predefinedVariationId: z.string().uuid().nullable().optional().describe("The served Variation's identifier."),
|
|
1570
1626
|
}).nullable().optional().describe("Represents the value of a Feature Flag or Setting."),
|
|
1571
1627
|
})).nullable().optional().describe("The targeting rules of the Feature Flag or Setting."),
|
|
1572
1628
|
percentageEvaluationAttribute: z.string().max(1000).nullable().optional().describe("The user attribute used for percentage evaluation. If not set, it defaults to the `Identifier` user object attribute."),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configcat/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"mcpName": "io.github.configcat/mcp-server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "MCP server exposing ConfigCat Public Management API (products, configs, environments, values v1/v2).",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/configcat/mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.5",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@configcat/mcp-server",
|
|
14
|
-
"version": "0.1.
|
|
14
|
+
"version": "0.1.5",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|