signal-relay-mcp 1.0.0

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/src/tools.ts ADDED
@@ -0,0 +1,233 @@
1
+ /**
2
+ * SocioLogic MCP Server - Tool Definitions
3
+ *
4
+ * This file defines all the MCP tools that map to the SocioLogic API endpoints.
5
+ */
6
+
7
+ import { z } from "zod";
8
+
9
+ // ============================================
10
+ // TOOL SCHEMAS
11
+ // ============================================
12
+
13
+ export const ListPersonasSchema = z.object({
14
+ visibility: z.enum(["public", "private", "all"]).default("public")
15
+ .describe("Filter by visibility: 'public' (marketplace), 'private' (user's own), 'all' (both)"),
16
+ category: z.string().optional()
17
+ .describe("Filter by category"),
18
+ fidelity_tier: z.enum(["standard", "enhanced", "premium", "ultra"]).optional()
19
+ .describe("Filter by fidelity tier"),
20
+ search: z.string().optional()
21
+ .describe("Search in name, tagline, description"),
22
+ page: z.number().int().positive().default(1)
23
+ .describe("Page number for pagination"),
24
+ per_page: z.number().int().min(1).max(100).default(20)
25
+ .describe("Results per page (max 100)"),
26
+ });
27
+
28
+ export const GetPersonaSchema = z.object({
29
+ slug: z.string().min(1)
30
+ .describe("The persona's unique slug identifier"),
31
+ });
32
+
33
+ export const CreatePersonaSchema = z.object({
34
+ description: z.string().min(10).max(2000)
35
+ .describe("Natural language description of the persona to create"),
36
+ fidelity_tier: z.enum(["standard", "enhanced", "premium", "ultra"]).default("enhanced")
37
+ .describe("Fidelity tier for the persona (affects depth and consistency)"),
38
+ });
39
+
40
+ export const InterviewPersonaSchema = z.object({
41
+ slug: z.string().min(1)
42
+ .describe("The persona's unique slug identifier"),
43
+ message: z.string().min(1).max(4000)
44
+ .describe("Your message/question to the persona"),
45
+ conversation_id: z.string().uuid().optional()
46
+ .describe("Optional conversation ID to continue an existing conversation"),
47
+ include_memory: z.boolean().default(true)
48
+ .describe("Whether to include persona's semantic memory context"),
49
+ save_conversation: z.boolean().default(true)
50
+ .describe("Whether to save this conversation for future reference"),
51
+ });
52
+
53
+ export const GetPersonaMemoriesSchema = z.object({
54
+ slug: z.string().min(1)
55
+ .describe("The persona's unique slug identifier"),
56
+ query: z.string().optional()
57
+ .describe("Optional semantic search query to filter memories"),
58
+ limit: z.number().int().min(1).max(50).default(10)
59
+ .describe("Maximum number of memories to return"),
60
+ });
61
+
62
+ export const ListCampaignsSchema = z.object({
63
+ status: z.enum(["draft", "running", "completed", "failed"]).optional()
64
+ .describe("Filter by campaign status"),
65
+ limit: z.number().int().min(1).max(100).default(20)
66
+ .describe("Maximum number of campaigns to return"),
67
+ offset: z.number().int().min(0).default(0)
68
+ .describe("Number of campaigns to skip for pagination"),
69
+ include_interviews: z.boolean().default(false)
70
+ .describe("Include interview details in response"),
71
+ });
72
+
73
+ export const GetCampaignSchema = z.object({
74
+ id: z.string().uuid()
75
+ .describe("The campaign's unique ID"),
76
+ });
77
+
78
+ export const CreateCampaignSchema = z.object({
79
+ name: z.string().min(1).max(200)
80
+ .describe("Name for the campaign"),
81
+ description: z.string().max(2000).optional()
82
+ .describe("Description of the campaign's purpose"),
83
+ questions: z.array(z.object({
84
+ id: z.string(),
85
+ text: z.string().min(1).max(1000),
86
+ type: z.enum(["open", "scale", "multiple_choice"]).default("open"),
87
+ required: z.boolean().default(true),
88
+ options: z.array(z.string()).optional(),
89
+ })).min(1).max(20)
90
+ .describe("Research questions to ask personas"),
91
+ persona_brief: z.string().min(10).max(2000).optional()
92
+ .describe("Description for generating new personas (if not using existing)"),
93
+ persona_count: z.number().int().min(1).max(50).default(10)
94
+ .describe("Number of personas to generate (if using persona_brief)"),
95
+ fidelity_tier: z.enum(["standard", "enhanced", "premium", "ultra"]).default("enhanced")
96
+ .describe("Fidelity tier for generated personas"),
97
+ existing_persona_ids: z.array(z.string().uuid()).optional()
98
+ .describe("Use existing personas instead of generating new ones"),
99
+ focus_group_ids: z.array(z.string().uuid()).optional()
100
+ .describe("Use personas from existing focus groups"),
101
+ research_context: z.object({
102
+ subjectName: z.string().min(1).max(200),
103
+ subjectDescription: z.string().min(50).max(2000),
104
+ currentChallenge: z.string().min(20).max(1000),
105
+ areasToExplore: z.array(z.string().max(500)).max(10).optional(),
106
+ knownIssues: z.array(z.string().max(500)).max(10).optional(),
107
+ }).optional()
108
+ .describe("Research context for AI-guided questioning"),
109
+ });
110
+
111
+ export const ExecuteCampaignSchema = z.object({
112
+ id: z.string().uuid()
113
+ .describe("The campaign's unique ID to execute"),
114
+ });
115
+
116
+ export const ExportCampaignSchema = z.object({
117
+ id: z.string().uuid()
118
+ .describe("The campaign's unique ID"),
119
+ format: z.enum(["pdf", "json"]).default("pdf")
120
+ .describe("Export format"),
121
+ });
122
+
123
+ export const ListFocusGroupsSchema = z.object({
124
+ limit: z.number().int().min(1).max(100).default(20)
125
+ .describe("Maximum number of focus groups to return"),
126
+ offset: z.number().int().min(0).default(0)
127
+ .describe("Number of focus groups to skip for pagination"),
128
+ });
129
+
130
+ export const GetFocusGroupSchema = z.object({
131
+ id: z.string().uuid()
132
+ .describe("The focus group's unique ID"),
133
+ });
134
+
135
+ export const CreateFocusGroupSchema = z.object({
136
+ name: z.string().min(1).max(200)
137
+ .describe("Name for the focus group"),
138
+ description: z.string().max(2000).optional()
139
+ .describe("Description of the focus group's purpose"),
140
+ });
141
+
142
+ export const AddPersonasToFocusGroupSchema = z.object({
143
+ focus_group_id: z.string().uuid()
144
+ .describe("The focus group's unique ID"),
145
+ persona_ids: z.array(z.string().uuid()).min(1)
146
+ .describe("Array of persona IDs to add to the focus group"),
147
+ });
148
+
149
+ export const GetCreditsBalanceSchema = z.object({});
150
+
151
+ // ============================================
152
+ // TOOL DEFINITIONS (for MCP)
153
+ // ============================================
154
+
155
+ export const TOOL_DEFINITIONS = [
156
+ {
157
+ name: "sociologic_list_personas",
158
+ description: "List available synthetic personas from the SocioLogic marketplace or your private collection. Use this to discover personas for interviews or campaigns.",
159
+ inputSchema: ListPersonasSchema,
160
+ },
161
+ {
162
+ name: "sociologic_get_persona",
163
+ description: "Get detailed information about a specific persona including demographics, psychographics, and behavioral traits.",
164
+ inputSchema: GetPersonaSchema,
165
+ },
166
+ {
167
+ name: "sociologic_create_persona",
168
+ description: "Create a new synthetic persona from a natural language description. The AI will generate a high-fidelity persona with consistent traits.",
169
+ inputSchema: CreatePersonaSchema,
170
+ },
171
+ {
172
+ name: "sociologic_interview_persona",
173
+ description: "Conduct an adversarial interview with a synthetic persona. Personas are prompted to challenge ideas and reveal unknown unknowns. Supports ongoing conversations.",
174
+ inputSchema: InterviewPersonaSchema,
175
+ },
176
+ {
177
+ name: "sociologic_get_persona_memories",
178
+ description: "Retrieve a persona's semantic memories. Memories are vector-embedded learnings from past interactions that inform future responses.",
179
+ inputSchema: GetPersonaMemoriesSchema,
180
+ },
181
+ {
182
+ name: "sociologic_list_campaigns",
183
+ description: "List your research campaigns. Campaigns are structured multi-persona interview sessions with defined questions.",
184
+ inputSchema: ListCampaignsSchema,
185
+ },
186
+ {
187
+ name: "sociologic_get_campaign",
188
+ description: "Get detailed information about a specific campaign including status, personas, questions, and interview results.",
189
+ inputSchema: GetCampaignSchema,
190
+ },
191
+ {
192
+ name: "sociologic_create_campaign",
193
+ description: "Create a new research campaign. Define questions and either generate new personas or use existing ones. Campaigns enable systematic multi-persona research.",
194
+ inputSchema: CreateCampaignSchema,
195
+ },
196
+ {
197
+ name: "sociologic_execute_campaign",
198
+ description: "Execute a draft campaign. This triggers background interviews with all personas and generates a research report. Long-running operation.",
199
+ inputSchema: ExecuteCampaignSchema,
200
+ },
201
+ {
202
+ name: "sociologic_export_campaign",
203
+ description: "Export a completed campaign's results as PDF or JSON. PDF includes executive summary, persona responses, and synthesized findings.",
204
+ inputSchema: ExportCampaignSchema,
205
+ },
206
+ {
207
+ name: "sociologic_list_focus_groups",
208
+ description: "List your focus groups. Focus groups are collections of personas for cohort-based research.",
209
+ inputSchema: ListFocusGroupsSchema,
210
+ },
211
+ {
212
+ name: "sociologic_get_focus_group",
213
+ description: "Get detailed information about a focus group including its member personas.",
214
+ inputSchema: GetFocusGroupSchema,
215
+ },
216
+ {
217
+ name: "sociologic_create_focus_group",
218
+ description: "Create a new focus group to organize personas for cohort-based research.",
219
+ inputSchema: CreateFocusGroupSchema,
220
+ },
221
+ {
222
+ name: "sociologic_add_personas_to_focus_group",
223
+ description: "Add one or more personas to an existing focus group.",
224
+ inputSchema: AddPersonasToFocusGroupSchema,
225
+ },
226
+ {
227
+ name: "sociologic_get_credits_balance",
228
+ description: "Check your current credits balance. Credits are used for persona interviews and campaign execution.",
229
+ inputSchema: GetCreditsBalanceSchema,
230
+ },
231
+ ] as const;
232
+
233
+ export type ToolName = typeof TOOL_DEFINITIONS[number]["name"];