@hailer/mcp 0.0.1
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/.claude/commands/tool-builder.md +37 -0
- package/.claude/commands/ws-pull.md +44 -0
- package/.claude/settings.json +8 -0
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/activity-api/SKILL.md +96 -0
- package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
- package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
- package/.claude/skills/agent-building/SKILL.md +243 -0
- package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
- package/.claude/skills/agent-building/references/code-examples.md +587 -0
- package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
- package/.claude/skills/app-api/SKILL.md +219 -0
- package/.claude/skills/app-api/references/app-endpoints.md +759 -0
- package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
- package/.claude/skills/create-app-skill/SKILL.md +1101 -0
- package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
- package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
- package/.claude/skills/hailer-api/SKILL.md +283 -0
- package/.claude/skills/hailer-api/references/activities.md +620 -0
- package/.claude/skills/hailer-api/references/authentication.md +216 -0
- package/.claude/skills/hailer-api/references/datasets.md +437 -0
- package/.claude/skills/hailer-api/references/files.md +301 -0
- package/.claude/skills/hailer-api/references/insights.md +469 -0
- package/.claude/skills/hailer-api/references/workflows.md +720 -0
- package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
- package/.claude/skills/insight-api/SKILL.md +185 -0
- package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
- package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
- package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
- package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
- package/.claude/skills/local-first-skill/SKILL.md +570 -0
- package/.claude/skills/mcp-tools/SKILL.md +419 -0
- package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
- package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
- package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
- package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
- package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
- package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
- package/.claude/skills/remove-app-skill/SKILL.md +985 -0
- package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
- package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
- package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
- package/.claude/skills/skill-testing/README.md +137 -0
- package/.claude/skills/skill-testing/SKILL.md +348 -0
- package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
- package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
- package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
- package/.claude/skills/tool-builder/SKILL.md +328 -0
- package/.claude/skills/update-app-skill/SKILL.md +970 -0
- package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
- package/.env.example +81 -0
- package/.mcp.json +13 -0
- package/README.md +297 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5 -0
- package/dist/client/adaptive-documentation-bot.d.ts +108 -0
- package/dist/client/adaptive-documentation-bot.js +475 -0
- package/dist/client/adaptive-documentation-types.d.ts +66 -0
- package/dist/client/adaptive-documentation-types.js +9 -0
- package/dist/client/agent-activity-bot.d.ts +51 -0
- package/dist/client/agent-activity-bot.js +166 -0
- package/dist/client/agent-tracker.d.ts +499 -0
- package/dist/client/agent-tracker.js +659 -0
- package/dist/client/description-updater.d.ts +56 -0
- package/dist/client/description-updater.js +259 -0
- package/dist/client/log-parser.d.ts +72 -0
- package/dist/client/log-parser.js +387 -0
- package/dist/client/mcp-client.d.ts +50 -0
- package/dist/client/mcp-client.js +532 -0
- package/dist/client/message-processor.d.ts +35 -0
- package/dist/client/message-processor.js +352 -0
- package/dist/client/multi-bot-manager.d.ts +24 -0
- package/dist/client/multi-bot-manager.js +74 -0
- package/dist/client/providers/anthropic-provider.d.ts +19 -0
- package/dist/client/providers/anthropic-provider.js +631 -0
- package/dist/client/providers/llm-provider.d.ts +47 -0
- package/dist/client/providers/llm-provider.js +367 -0
- package/dist/client/providers/openai-provider.d.ts +23 -0
- package/dist/client/providers/openai-provider.js +621 -0
- package/dist/client/simple-llm-caller.d.ts +19 -0
- package/dist/client/simple-llm-caller.js +100 -0
- package/dist/client/skill-generator.d.ts +81 -0
- package/dist/client/skill-generator.js +386 -0
- package/dist/client/test-adaptive-bot.d.ts +9 -0
- package/dist/client/test-adaptive-bot.js +82 -0
- package/dist/client/token-pricing.d.ts +38 -0
- package/dist/client/token-pricing.js +127 -0
- package/dist/client/token-tracker.d.ts +232 -0
- package/dist/client/token-tracker.js +457 -0
- package/dist/client/token-usage-bot.d.ts +53 -0
- package/dist/client/token-usage-bot.js +153 -0
- package/dist/client/tool-executor.d.ts +69 -0
- package/dist/client/tool-executor.js +159 -0
- package/dist/client/tool-schema-loader.d.ts +60 -0
- package/dist/client/tool-schema-loader.js +178 -0
- package/dist/client/types.d.ts +69 -0
- package/dist/client/types.js +7 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.js +296 -0
- package/dist/core.d.ts +26 -0
- package/dist/core.js +147 -0
- package/dist/lib/context-manager.d.ts +111 -0
- package/dist/lib/context-manager.js +431 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +277 -0
- package/dist/lib/materialize.d.ts +3 -0
- package/dist/lib/materialize.js +101 -0
- package/dist/lib/normalizedName.d.ts +7 -0
- package/dist/lib/normalizedName.js +48 -0
- package/dist/lib/prompt-length-manager.d.ts +81 -0
- package/dist/lib/prompt-length-manager.js +457 -0
- package/dist/lib/terminal-prompt.d.ts +9 -0
- package/dist/lib/terminal-prompt.js +108 -0
- package/dist/mcp/UserContextCache.d.ts +56 -0
- package/dist/mcp/UserContextCache.js +163 -0
- package/dist/mcp/auth.d.ts +2 -0
- package/dist/mcp/auth.js +29 -0
- package/dist/mcp/hailer-clients.d.ts +42 -0
- package/dist/mcp/hailer-clients.js +246 -0
- package/dist/mcp/signal-handler.d.ts +45 -0
- package/dist/mcp/signal-handler.js +317 -0
- package/dist/mcp/tool-registry.d.ts +100 -0
- package/dist/mcp/tool-registry.js +306 -0
- package/dist/mcp/tools/activity.d.ts +15 -0
- package/dist/mcp/tools/activity.js +955 -0
- package/dist/mcp/tools/app.d.ts +20 -0
- package/dist/mcp/tools/app.js +1488 -0
- package/dist/mcp/tools/discussion.d.ts +19 -0
- package/dist/mcp/tools/discussion.js +950 -0
- package/dist/mcp/tools/file.d.ts +15 -0
- package/dist/mcp/tools/file.js +119 -0
- package/dist/mcp/tools/insight.d.ts +17 -0
- package/dist/mcp/tools/insight.js +806 -0
- package/dist/mcp/tools/skill.d.ts +10 -0
- package/dist/mcp/tools/skill.js +279 -0
- package/dist/mcp/tools/user.d.ts +10 -0
- package/dist/mcp/tools/user.js +108 -0
- package/dist/mcp/tools/workflow-template.d.ts +19 -0
- package/dist/mcp/tools/workflow-template.js +822 -0
- package/dist/mcp/tools/workflow.d.ts +18 -0
- package/dist/mcp/tools/workflow.js +1362 -0
- package/dist/mcp/utils/api-errors.d.ts +45 -0
- package/dist/mcp/utils/api-errors.js +160 -0
- package/dist/mcp/utils/data-transformers.d.ts +102 -0
- package/dist/mcp/utils/data-transformers.js +194 -0
- package/dist/mcp/utils/file-upload.d.ts +33 -0
- package/dist/mcp/utils/file-upload.js +148 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
- package/dist/mcp/utils/hailer-api-client.js +323 -0
- package/dist/mcp/utils/index.d.ts +13 -0
- package/dist/mcp/utils/index.js +39 -0
- package/dist/mcp/utils/logger.d.ts +42 -0
- package/dist/mcp/utils/logger.js +103 -0
- package/dist/mcp/utils/types.d.ts +286 -0
- package/dist/mcp/utils/types.js +7 -0
- package/dist/mcp/workspace-cache.d.ts +42 -0
- package/dist/mcp/workspace-cache.js +97 -0
- package/dist/mcp-server.d.ts +42 -0
- package/dist/mcp-server.js +280 -0
- package/package.json +56 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: MCP Tools
|
|
3
|
+
description: Complete technical reference for building Hailer MCP tools - API endpoints, data structures, implementation patterns, and working code examples.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MCP Tools Skill
|
|
7
|
+
|
|
8
|
+
This skill provides comprehensive technical documentation for building MCP tools that integrate with the Hailer API. Use this when implementing new tools or debugging existing integrations.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
Invoke this skill when:
|
|
13
|
+
- Building a new MCP tool for Hailer integration
|
|
14
|
+
- Debugging API calls or data structures
|
|
15
|
+
- Understanding endpoint signatures and request formats
|
|
16
|
+
- Implementing filters, pagination, or complex queries
|
|
17
|
+
- Working with workflow schemas or activity structures
|
|
18
|
+
|
|
19
|
+
## Quick Reference
|
|
20
|
+
|
|
21
|
+
### API Configuration
|
|
22
|
+
|
|
23
|
+
- **Base URL**: `https://api.hailer.local.gd`
|
|
24
|
+
- **Authentication**: `hlrkey` header with auth token
|
|
25
|
+
- **Request Format**: Most endpoints expect JSON array as body: `[...args]`
|
|
26
|
+
- **API Versions**: v2 (init), v3 (activities, discussions), mixed usage
|
|
27
|
+
- **Protocol**: Socket.io via `@hailer/cli` package + REST endpoints
|
|
28
|
+
|
|
29
|
+
### Key Implementation Principles
|
|
30
|
+
|
|
31
|
+
1. **Use UserContext**: All tools receive UserContext with client connections
|
|
32
|
+
2. **Stateless Tools**: Tools are static methods, no instance state
|
|
33
|
+
3. **Connection Pooling**: Reuse connections from global pool
|
|
34
|
+
4. **returnFlat Mode**: Use `returnFlat: true` for cleaner field access via keys
|
|
35
|
+
5. **Error Handling**: Always wrap in try/catch, return user-friendly messages
|
|
36
|
+
|
|
37
|
+
## Documentation Structure
|
|
38
|
+
|
|
39
|
+
### [API Endpoints](references/api-endpoints.md)
|
|
40
|
+
Complete reference for all working Hailer API endpoints with exact request/response formats:
|
|
41
|
+
- Activity operations (list, create, update)
|
|
42
|
+
- Discussion messages (fetch, send, pagination)
|
|
43
|
+
- Workflow operations
|
|
44
|
+
- Socket.io methods
|
|
45
|
+
- Filter operators and query syntax
|
|
46
|
+
|
|
47
|
+
### [Data Structures](references/data-structures.md)
|
|
48
|
+
Detailed schemas for Hailer data types:
|
|
49
|
+
- Workflow structure (processes, fields, phases)
|
|
50
|
+
- Activity structure (with/without returnFlat)
|
|
51
|
+
- Field types (text, activitylink, date, etc.)
|
|
52
|
+
- ActivityLink relationships
|
|
53
|
+
- Phase transitions
|
|
54
|
+
|
|
55
|
+
### [Implementation Patterns](references/implementation-patterns.md)
|
|
56
|
+
Step-by-step guides for common tasks:
|
|
57
|
+
- Adding new API endpoints
|
|
58
|
+
- Creating MCP tools
|
|
59
|
+
- Implementing filters and pagination
|
|
60
|
+
- Handling socket.io connections
|
|
61
|
+
- Error handling best practices
|
|
62
|
+
- Testing and debugging tools
|
|
63
|
+
|
|
64
|
+
## Common Code Patterns
|
|
65
|
+
|
|
66
|
+
### Complete Tool Structure (2024 Pattern)
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// In ReadTools.ts, WriteTools.ts, or PlaygroundTools.ts
|
|
70
|
+
import { z } from 'zod';
|
|
71
|
+
import { UserContext, McpResponse } from '../types';
|
|
72
|
+
|
|
73
|
+
export class ReadTools {
|
|
74
|
+
/**
|
|
75
|
+
* Register all tools - called by GlobalToolRegistry
|
|
76
|
+
*/
|
|
77
|
+
static getTools() {
|
|
78
|
+
return [
|
|
79
|
+
{
|
|
80
|
+
name: 'list_activities',
|
|
81
|
+
description: ReadTools.getListActivitiesDescription(),
|
|
82
|
+
validationSchema: ReadTools.getListActivitiesSchema(),
|
|
83
|
+
handler: ReadTools.listActivities
|
|
84
|
+
}
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Tool description
|
|
90
|
+
*/
|
|
91
|
+
private static getListActivitiesDescription(): string {
|
|
92
|
+
return `📋 List activities in a workflow phase with filtering.
|
|
93
|
+
|
|
94
|
+
**Example:**
|
|
95
|
+
\`\`\`javascript
|
|
96
|
+
list_activities({
|
|
97
|
+
workflowId: "6756e099410306cab03a7dfb",
|
|
98
|
+
phaseId: "6756e0bd410306cab03a7fa7",
|
|
99
|
+
fields: ["name", "status"],
|
|
100
|
+
limit: 50
|
|
101
|
+
})
|
|
102
|
+
\`\`\``;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Zod schema with type coercion for MCP clients
|
|
107
|
+
*/
|
|
108
|
+
private static getListActivitiesSchema() {
|
|
109
|
+
return z.object({
|
|
110
|
+
workflowId: z.string().describe("Workflow ID to list activities from"),
|
|
111
|
+
phaseId: z.string().describe("Phase ID to filter activities"),
|
|
112
|
+
|
|
113
|
+
// CRITICAL: Use z.coerce for numbers (MCP clients send as strings)
|
|
114
|
+
limit: z.coerce.number().optional().default(50)
|
|
115
|
+
.describe("Maximum number of activities to return"),
|
|
116
|
+
page: z.coerce.number().optional().default(0)
|
|
117
|
+
.describe("Page number for pagination (0-based)"),
|
|
118
|
+
|
|
119
|
+
// CRITICAL: Use z.coerce for booleans (MCP clients send "false" as string)
|
|
120
|
+
includeStats: z.coerce.boolean().optional().default(true)
|
|
121
|
+
.describe("Include total count and pagination metadata"),
|
|
122
|
+
|
|
123
|
+
// CRITICAL: Use z.preprocess for arrays (MCP clients send JSON strings)
|
|
124
|
+
fields: z.preprocess(
|
|
125
|
+
(val) => {
|
|
126
|
+
if (typeof val === 'string') {
|
|
127
|
+
try {
|
|
128
|
+
return JSON.parse(val);
|
|
129
|
+
} catch {
|
|
130
|
+
return val;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return val;
|
|
134
|
+
},
|
|
135
|
+
z.array(z.string()).optional()
|
|
136
|
+
).describe("Array of field IDs to return")
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Static handler method
|
|
142
|
+
*/
|
|
143
|
+
static async listActivities(args: Record<string, unknown>, context: UserContext): Promise<McpResponse> {
|
|
144
|
+
// Args already validated by GlobalToolRegistry
|
|
145
|
+
const validatedArgs = args as {
|
|
146
|
+
workflowId: string;
|
|
147
|
+
phaseId: string;
|
|
148
|
+
limit?: number;
|
|
149
|
+
page?: number;
|
|
150
|
+
includeStats?: boolean;
|
|
151
|
+
fields?: string[];
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
// Use context.client.baseUrl instead of hardcoded URL
|
|
156
|
+
const apiClient = new HailerApiClient(context.client, context.client.baseUrl);
|
|
157
|
+
|
|
158
|
+
const activities = await apiClient.listActivities(
|
|
159
|
+
validatedArgs.workflowId,
|
|
160
|
+
{
|
|
161
|
+
phaseId: validatedArgs.phaseId,
|
|
162
|
+
limit: validatedArgs.limit,
|
|
163
|
+
returnFlat: true
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
content: [{
|
|
169
|
+
type: "text",
|
|
170
|
+
text: formatActivitiesResponse(activities)
|
|
171
|
+
}]
|
|
172
|
+
};
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return {
|
|
175
|
+
content: [{
|
|
176
|
+
type: "text",
|
|
177
|
+
text: `❌ **Error listing activities**\n\n${error.message}`
|
|
178
|
+
}]
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Calling Hailer API
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// In hailer-api.ts
|
|
189
|
+
export async function listActivities(
|
|
190
|
+
client: HailerClient,
|
|
191
|
+
workflowId: string,
|
|
192
|
+
options: ActivityListOptions = {}
|
|
193
|
+
): Promise<any> {
|
|
194
|
+
const { phaseId, limit = 50, returnFlat = true } = options;
|
|
195
|
+
|
|
196
|
+
const response = await fetch(
|
|
197
|
+
`${client.baseUrl}/v3/activity/list`,
|
|
198
|
+
{
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: {
|
|
201
|
+
'Content-Type': 'application/json',
|
|
202
|
+
'hlrkey': client.authToken
|
|
203
|
+
},
|
|
204
|
+
body: JSON.stringify([
|
|
205
|
+
{ processId: workflowId, phaseId },
|
|
206
|
+
{ limit, page: 1, returnFlat }
|
|
207
|
+
])
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
if (!response.ok) {
|
|
212
|
+
throw new Error(`API error: ${response.statusText}`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return response.json();
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Tool Registration (GlobalToolRegistry)
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// In GlobalToolRegistry.ts
|
|
223
|
+
import { z } from 'zod';
|
|
224
|
+
|
|
225
|
+
export class GlobalToolRegistry {
|
|
226
|
+
private tools = new Map<string, {
|
|
227
|
+
name: string;
|
|
228
|
+
description: string;
|
|
229
|
+
validationSchema: any; // Zod schema
|
|
230
|
+
handler: ToolHandler;
|
|
231
|
+
group: ToolGroup;
|
|
232
|
+
}>();
|
|
233
|
+
|
|
234
|
+
private constructor() {
|
|
235
|
+
// Register tools from each class
|
|
236
|
+
this.registerToolsFromClass(ReadTools.getTools(), 'read');
|
|
237
|
+
this.registerToolsFromClass(WriteTools.getTools(), 'write');
|
|
238
|
+
this.registerToolsFromClass(PlaygroundTools.getTools(), 'playground');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Register tools from a tool class
|
|
243
|
+
*/
|
|
244
|
+
private registerToolsFromClass(toolRegs: Array<{
|
|
245
|
+
name: string;
|
|
246
|
+
description: string;
|
|
247
|
+
validationSchema: any;
|
|
248
|
+
handler: ToolHandler;
|
|
249
|
+
}>, group: ToolGroup): void {
|
|
250
|
+
for (const toolReg of toolRegs) {
|
|
251
|
+
this.tools.set(toolReg.name, {
|
|
252
|
+
name: toolReg.name,
|
|
253
|
+
description: toolReg.description,
|
|
254
|
+
validationSchema: toolReg.validationSchema,
|
|
255
|
+
handler: toolReg.handler,
|
|
256
|
+
group: group
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Execute tool with centralized Zod validation
|
|
263
|
+
*/
|
|
264
|
+
async executeTool(toolName: string, args: any, context: UserContext): Promise<McpResponse> {
|
|
265
|
+
const tool = this.tools.get(toolName);
|
|
266
|
+
if (!tool) {
|
|
267
|
+
throw new Error(`Tool not found: ${toolName}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// CENTRALIZED VALIDATION with Zod
|
|
271
|
+
try {
|
|
272
|
+
const validatedArgs = tool.validationSchema.parse(args);
|
|
273
|
+
return await tool.handler(validatedArgs, context);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
if (error instanceof z.ZodError) {
|
|
276
|
+
const errorDetails = error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
277
|
+
return {
|
|
278
|
+
content: [{
|
|
279
|
+
type: "text",
|
|
280
|
+
text: `❌ **Validation Error for \`${toolName}\`**\n\n**Errors:** ${errorDetails}`
|
|
281
|
+
}]
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
throw error;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Type Coercion Patterns (CRITICAL for MCP Compatibility)
|
|
291
|
+
|
|
292
|
+
### Boolean Parameters
|
|
293
|
+
**Problem:** MCP clients send `"false"` as a string, not boolean `false`
|
|
294
|
+
**Solution:** Use `z.coerce.boolean()`
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
enabled: z.coerce.boolean().optional().default(true)
|
|
298
|
+
.describe("Enable feature")
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Numeric Parameters
|
|
302
|
+
**Problem:** MCP clients send `"123"` as a string, not number `123`
|
|
303
|
+
**Solution:** Use `z.coerce.number()`
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
limit: z.coerce.number().optional().default(50)
|
|
307
|
+
.describe("Maximum results")
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Array Parameters
|
|
311
|
+
**Problem:** MCP clients send `'["field1","field2"]'` as JSON string
|
|
312
|
+
**Solution:** Use `z.preprocess()` to parse JSON strings
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
fields: z.preprocess(
|
|
316
|
+
(val) => {
|
|
317
|
+
if (typeof val === 'string') {
|
|
318
|
+
try {
|
|
319
|
+
return JSON.parse(val);
|
|
320
|
+
} catch {
|
|
321
|
+
return val;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return val;
|
|
325
|
+
},
|
|
326
|
+
z.array(z.string()).optional()
|
|
327
|
+
).describe("Array of field IDs")
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Object Parameters
|
|
331
|
+
**Problem:** MCP clients send configuration objects as JSON strings
|
|
332
|
+
**Solution:** Use `z.preprocess()` to parse JSON strings
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
configuration: z.preprocess(
|
|
336
|
+
(val) => {
|
|
337
|
+
if (typeof val === 'string') {
|
|
338
|
+
try {
|
|
339
|
+
return JSON.parse(val);
|
|
340
|
+
} catch {
|
|
341
|
+
return val;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return val;
|
|
345
|
+
},
|
|
346
|
+
z.record(z.any()).optional()
|
|
347
|
+
).describe("Configuration object")
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## API URL Pattern (CRITICAL for Environment Support)
|
|
351
|
+
|
|
352
|
+
**Always use `context.client.baseUrl` instead of hardcoded URLs:**
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
// ❌ WRONG - hardcoded production URL
|
|
356
|
+
const apiClient = new HailerApiClient(context.client, 'https://api.hailer.com');
|
|
357
|
+
|
|
358
|
+
// ✅ CORRECT - uses client's configured URL (local/staging/production)
|
|
359
|
+
const apiClient = new HailerApiClient(context.client, context.client.baseUrl);
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Working Endpoint Summary
|
|
363
|
+
|
|
364
|
+
### V3 Activity Endpoints
|
|
365
|
+
- `POST /v3/activity/list` - List activities with advanced filtering
|
|
366
|
+
- `POST /v3/activity/createMany` - Create activities (batch)
|
|
367
|
+
- `POST /v3/activity/updateMany` - Update activities (batch)
|
|
368
|
+
|
|
369
|
+
### V3 Discussion Endpoints
|
|
370
|
+
- `POST /v3/discussion/message/latest` - Fetch latest messages
|
|
371
|
+
- `POST /v3/discussion/message/previous` - Fetch older messages (pagination)
|
|
372
|
+
- `POST /api/messenger/send` - Send message to discussion
|
|
373
|
+
|
|
374
|
+
### V2 Endpoints
|
|
375
|
+
- `POST /v2/core/init` - Workspace initialization
|
|
376
|
+
- `POST /v2/search/global` - Global search
|
|
377
|
+
|
|
378
|
+
### Socket.io Methods
|
|
379
|
+
- `activities.follow` - Follow/unfollow activity (joins/leaves discussion)
|
|
380
|
+
- `messenger.leave_discussion` - Leave any discussion
|
|
381
|
+
|
|
382
|
+
## Filter Operators (v3 API)
|
|
383
|
+
|
|
384
|
+
- `textSearch` - Partial text search in field
|
|
385
|
+
- `equalTo` / `notEqualTo` - Exact matching
|
|
386
|
+
- `contains` - Partial text matching
|
|
387
|
+
- `greaterThan` / `lessThan` / `greaterThanOrEqual` / `lessThanOrEqual` - Numeric comparisons
|
|
388
|
+
- `between` - Range filter for dates/numbers [start, end]
|
|
389
|
+
|
|
390
|
+
## Example: Activity List with Filters
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// Filter activities by company and date range
|
|
394
|
+
const activities = await listActivities(client, workflowId, {
|
|
395
|
+
filters: {
|
|
396
|
+
and: [
|
|
397
|
+
{ "field-id-company": { equalTo: "company-id" } },
|
|
398
|
+
{ "field-id-created": { between: ["1717200000000", "1719791999000"] } }
|
|
399
|
+
]
|
|
400
|
+
},
|
|
401
|
+
returnFlat: true,
|
|
402
|
+
limit: 100
|
|
403
|
+
});
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Next Steps
|
|
407
|
+
|
|
408
|
+
For detailed information on any topic:
|
|
409
|
+
1. Check [API Endpoints](references/api-endpoints.md) for exact endpoint signatures
|
|
410
|
+
2. Review [Data Structures](references/data-structures.md) for schema details
|
|
411
|
+
3. Follow [Implementation Patterns](references/implementation-patterns.md) for step-by-step guides
|
|
412
|
+
|
|
413
|
+
## TODO - Research Needed
|
|
414
|
+
|
|
415
|
+
- Activity comments (add_comment endpoint)
|
|
416
|
+
- Cross-workspace search API endpoint
|
|
417
|
+
- Proper permission requirements for write operations
|
|
418
|
+
- File upload/download endpoints
|
|
419
|
+
- Workflow automation triggers
|