touchstone-mcp-tools 1.0.1 → 1.0.2
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.
|
@@ -43,6 +43,14 @@ export declare class WolvesHandler {
|
|
|
43
43
|
progression_parameters?: any[];
|
|
44
44
|
}>;
|
|
45
45
|
}): Promise<ToolResult>;
|
|
46
|
+
updateSubscribers(params: {
|
|
47
|
+
experiment_id: string;
|
|
48
|
+
subscribers: Array<{
|
|
49
|
+
id: string;
|
|
50
|
+
type: string;
|
|
51
|
+
tenantId: string;
|
|
52
|
+
}>;
|
|
53
|
+
}): Promise<ToolResult>;
|
|
46
54
|
getExperiment(params: {
|
|
47
55
|
experiment_id: string;
|
|
48
56
|
}): Promise<ToolResult>;
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { WolvesApiClient } from "../utils/wolves-api.js";
|
|
2
|
+
// Generate 8-character variant ID: 4 lowercase letters + 4 digits
|
|
3
|
+
// Matches ExP-Hub UI convention (e.g., "kifj6658", "tvan3734")
|
|
4
|
+
function generateVariantId() {
|
|
5
|
+
const letters = "abcdefghijklmnopqrstuvwxyz";
|
|
6
|
+
const digits = "0123456789";
|
|
7
|
+
let result = "";
|
|
8
|
+
for (let i = 0; i < 4; i++) {
|
|
9
|
+
result += letters.charAt(Math.floor(Math.random() * letters.length));
|
|
10
|
+
}
|
|
11
|
+
for (let i = 0; i < 4; i++) {
|
|
12
|
+
result += digits.charAt(Math.floor(Math.random() * digits.length));
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
2
16
|
export class WolvesHandler {
|
|
3
17
|
api;
|
|
4
18
|
constructor(api) {
|
|
@@ -39,13 +53,18 @@ export class WolvesHandler {
|
|
|
39
53
|
}
|
|
40
54
|
// Tool 5: create_experiment
|
|
41
55
|
async createExperiment(params) {
|
|
56
|
+
// Auto-generate 8-char variant IDs for variants that don't have one
|
|
57
|
+
const variants = params.variants.map((v) => ({
|
|
58
|
+
...v,
|
|
59
|
+
id: v.id || generateVariantId(),
|
|
60
|
+
}));
|
|
42
61
|
const result = await this.api.createExperiment({
|
|
43
62
|
name: params.name,
|
|
44
63
|
description: params.description,
|
|
45
64
|
experimentation_group: params.experimentation_group,
|
|
46
65
|
assignment_unit_id: params.assignment_unit_id,
|
|
47
66
|
subscribers: params.subscribers,
|
|
48
|
-
variants
|
|
67
|
+
variants,
|
|
49
68
|
metrics: params.metrics,
|
|
50
69
|
progressions: params.progressions,
|
|
51
70
|
});
|
|
@@ -54,7 +73,17 @@ export class WolvesHandler {
|
|
|
54
73
|
message: `Experiment "${result.name}" created (ID: ${result.id})`,
|
|
55
74
|
};
|
|
56
75
|
}
|
|
57
|
-
// Tool 6:
|
|
76
|
+
// Tool 6: update_subscribers
|
|
77
|
+
async updateSubscribers(params) {
|
|
78
|
+
await this.api.updateSubscribers(params.experiment_id, {
|
|
79
|
+
subscribers: params.subscribers,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
data: { experiment_id: params.experiment_id, subscriber_count: params.subscribers.length },
|
|
83
|
+
message: `Updated ${params.subscribers.length} subscriber(s) for experiment "${params.experiment_id}"`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Tool 8: get_experiment
|
|
58
87
|
async getExperiment(params) {
|
|
59
88
|
const result = await this.api.getExperiment(params.experiment_id);
|
|
60
89
|
return {
|
|
@@ -62,7 +91,7 @@ export class WolvesHandler {
|
|
|
62
91
|
message: `Retrieved experiment "${result.name}" (status: ${result.status})`,
|
|
63
92
|
};
|
|
64
93
|
}
|
|
65
|
-
// Tool
|
|
94
|
+
// Tool 8: list_experiments
|
|
66
95
|
async listExperiments(params) {
|
|
67
96
|
const result = await this.api.listExperiments({
|
|
68
97
|
page: params.page,
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"type": "object",
|
|
93
93
|
"required": ["type"],
|
|
94
94
|
"properties": {
|
|
95
|
-
"id": { "type": "string", "description": "Variant ID (
|
|
95
|
+
"id": { "type": "string", "description": "Variant ID. 8-character alphanumeric (4 letters + 4 digits, e.g., 'kifj6658'). Auto-generated if omitted." },
|
|
96
96
|
"type": { "type": "string", "enum": ["control", "treatment"], "description": "Variant type" },
|
|
97
97
|
"description": { "type": "string", "description": "Variant description" }
|
|
98
98
|
}
|
|
@@ -130,6 +130,33 @@
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
|
+
"update_subscribers": {
|
|
134
|
+
"name": "update_subscribers",
|
|
135
|
+
"description": "Update subscribers for an experiment. Subscribers receive notifications about experiment changes. Requires subscriber objects with id, type, and tenantId (obtained from search_subscribers).",
|
|
136
|
+
"inputSchema": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"required": ["experiment_id", "subscribers"],
|
|
139
|
+
"properties": {
|
|
140
|
+
"experiment_id": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"description": "UUID of the experiment to update subscribers for"
|
|
143
|
+
},
|
|
144
|
+
"subscribers": {
|
|
145
|
+
"type": "array",
|
|
146
|
+
"description": "List of subscriber objects. Each subscriber must include id, type, and tenantId from search_subscribers results.",
|
|
147
|
+
"items": {
|
|
148
|
+
"type": "object",
|
|
149
|
+
"required": ["id", "type", "tenantId"],
|
|
150
|
+
"properties": {
|
|
151
|
+
"id": { "type": "string", "description": "Subscriber's user ID (from search_subscribers)" },
|
|
152
|
+
"type": { "type": "string", "description": "Subscriber type (e.g., 'UserAccount')" },
|
|
153
|
+
"tenantId": { "type": "string", "description": "Subscriber's tenant ID (from search_subscribers)" }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
133
160
|
"get_experiment": {
|
|
134
161
|
"name": "get_experiment",
|
|
135
162
|
"description": "Get detailed information about a specific experiment by its ID.",
|
|
@@ -42,6 +42,9 @@ export class WolvesServer {
|
|
|
42
42
|
case "create_experiment":
|
|
43
43
|
result = await this.handler.createExperiment(args);
|
|
44
44
|
break;
|
|
45
|
+
case "update_subscribers":
|
|
46
|
+
result = await this.handler.updateSubscribers(args);
|
|
47
|
+
break;
|
|
45
48
|
case "get_experiment":
|
|
46
49
|
result = await this.handler.getExperiment(args);
|
|
47
50
|
break;
|
|
@@ -44,6 +44,14 @@ export interface SubscriberSearchResult {
|
|
|
44
44
|
type: string;
|
|
45
45
|
tenantId: string;
|
|
46
46
|
}
|
|
47
|
+
export interface SubscriberInput {
|
|
48
|
+
id: string;
|
|
49
|
+
type: string;
|
|
50
|
+
tenantId: string;
|
|
51
|
+
}
|
|
52
|
+
export interface UpdateSubscribersRequest {
|
|
53
|
+
subscribers: SubscriberInput[];
|
|
54
|
+
}
|
|
47
55
|
export interface VariantInput {
|
|
48
56
|
id?: string;
|
|
49
57
|
type: "control" | "treatment";
|
|
@@ -124,6 +132,7 @@ export declare class WolvesApiClient {
|
|
|
124
132
|
listAssignmentUnits(filter?: string): Promise<AssignmentUnitsListResponse>;
|
|
125
133
|
searchSubscribers(search: string, count?: number, fetchUserPhoto?: boolean): Promise<SubscriberSearchResult[]>;
|
|
126
134
|
createExperiment(data: CreateExperimentRequest): Promise<ExperimentDetail>;
|
|
135
|
+
updateSubscribers(experimentId: string, data: UpdateSubscribersRequest): Promise<void>;
|
|
127
136
|
getExperiment(experimentId: string): Promise<ExperimentDetail>;
|
|
128
137
|
listExperiments(params?: {
|
|
129
138
|
page?: number;
|
|
@@ -69,6 +69,9 @@ export class WolvesApiClient {
|
|
|
69
69
|
const response = await this.client.post("/api/experiments/experiments", data);
|
|
70
70
|
return response.data;
|
|
71
71
|
}
|
|
72
|
+
async updateSubscribers(experimentId, data) {
|
|
73
|
+
await this.client.put(`/api/experiments/experiments/${encodeURIComponent(experimentId)}/subscribers`, data);
|
|
74
|
+
}
|
|
72
75
|
async getExperiment(experimentId) {
|
|
73
76
|
const response = await this.client.get(`/api/experiments/experiments/${experimentId}`);
|
|
74
77
|
return response.data;
|