@hailer/mcp 1.0.29 → 1.1.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.
Files changed (233) hide show
  1. package/.claude/.session-checked +1 -0
  2. package/.claude/agents/agent-ada-skill-builder.md +10 -2
  3. package/.claude/agents/agent-alejandro-function-fields.md +104 -37
  4. package/.claude/agents/agent-bjorn-config-audit.md +41 -21
  5. package/.claude/agents/agent-builder-agent-creator.md +13 -3
  6. package/.claude/agents/agent-code-simplifier.md +53 -0
  7. package/.claude/agents/agent-dmitri-activity-crud.md +126 -11
  8. package/.claude/agents/agent-giuseppe-app-builder.md +212 -22
  9. package/.claude/agents/agent-gunther-mcp-tools.md +7 -36
  10. package/.claude/agents/agent-helga-workflow-config.md +75 -10
  11. package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
  12. package/.claude/agents/agent-ingrid-doc-templates.md +164 -36
  13. package/.claude/agents/agent-ivan-monolith.md +154 -0
  14. package/.claude/agents/agent-kenji-data-reader.md +15 -8
  15. package/.claude/agents/agent-lars-code-inspector.md +56 -8
  16. package/.claude/agents/agent-marco-mockup-builder.md +110 -0
  17. package/.claude/agents/agent-marcus-api-documenter.md +323 -0
  18. package/.claude/agents/agent-marketplace-publisher.md +232 -72
  19. package/.claude/agents/agent-marketplace-reviewer.md +255 -79
  20. package/.claude/agents/agent-permissions-handler.md +208 -0
  21. package/.claude/agents/agent-simple-writer.md +48 -0
  22. package/.claude/agents/agent-svetlana-code-review.md +127 -14
  23. package/.claude/agents/agent-tanya-test-runner.md +333 -0
  24. package/.claude/agents/agent-ui-designer.md +100 -0
  25. package/.claude/agents/agent-viktor-sql-insights.md +19 -6
  26. package/.claude/agents/agent-web-search.md +55 -0
  27. package/.claude/agents/agent-yevgeni-discussions.md +7 -1
  28. package/.claude/agents/agent-zara-zapier.md +159 -0
  29. package/.claude/commands/app-squad.md +135 -0
  30. package/.claude/commands/audit-squad.md +158 -0
  31. package/.claude/commands/autoplan.md +563 -0
  32. package/.claude/commands/cleanup-squad.md +98 -0
  33. package/.claude/commands/config-squad.md +106 -0
  34. package/.claude/commands/crud-squad.md +87 -0
  35. package/.claude/commands/data-squad.md +97 -0
  36. package/.claude/commands/debug-squad.md +303 -0
  37. package/.claude/commands/doc-squad.md +65 -0
  38. package/.claude/commands/handoff.md +137 -0
  39. package/.claude/commands/health.md +49 -0
  40. package/.claude/commands/help.md +2 -1
  41. package/.claude/commands/help:agents.md +96 -16
  42. package/.claude/commands/help:commands.md +55 -11
  43. package/.claude/commands/help:faq.md +16 -1
  44. package/.claude/commands/help:skills.md +93 -0
  45. package/.claude/commands/hotfix-squad.md +112 -0
  46. package/.claude/commands/integration-squad.md +82 -0
  47. package/.claude/commands/janitor-squad.md +167 -0
  48. package/.claude/commands/learn-auto.md +120 -0
  49. package/.claude/commands/learn.md +120 -0
  50. package/.claude/commands/mcp-list.md +27 -0
  51. package/.claude/commands/onboard-squad.md +140 -0
  52. package/.claude/commands/plan-workspace.md +732 -0
  53. package/.claude/commands/prd.md +131 -0
  54. package/.claude/commands/project-status.md +82 -0
  55. package/.claude/commands/publish.md +138 -0
  56. package/.claude/commands/recap.md +69 -0
  57. package/.claude/commands/restore.md +64 -0
  58. package/.claude/commands/review-squad.md +152 -0
  59. package/.claude/commands/save.md +24 -0
  60. package/.claude/commands/stats.md +19 -0
  61. package/.claude/commands/swarm.md +210 -0
  62. package/.claude/commands/tool-builder.md +3 -1
  63. package/.claude/commands/ws-pull.md +1 -1
  64. package/.claude/commands/yolo-off.md +17 -0
  65. package/.claude/commands/yolo.md +82 -0
  66. package/.claude/hooks/_shared-memory.cjs +305 -0
  67. package/.claude/hooks/_utils.cjs +134 -0
  68. package/.claude/hooks/agent-failure-detector.cjs +164 -79
  69. package/.claude/hooks/agent-usage-logger.cjs +204 -0
  70. package/.claude/hooks/app-edit-guard.cjs +20 -4
  71. package/.claude/hooks/auto-learn.cjs +316 -0
  72. package/.claude/hooks/bash-guard.cjs +282 -0
  73. package/.claude/hooks/builder-mode-manager.cjs +183 -54
  74. package/.claude/hooks/bulk-activity-guard.cjs +283 -0
  75. package/.claude/hooks/context-watchdog.cjs +292 -0
  76. package/.claude/hooks/delegation-reminder.cjs +478 -0
  77. package/.claude/hooks/design-system-lint.cjs +283 -0
  78. package/.claude/hooks/post-scaffold-hook.cjs +16 -3
  79. package/.claude/hooks/prompt-guard.cjs +366 -0
  80. package/.claude/hooks/publish-template-guard.cjs +16 -0
  81. package/.claude/hooks/session-start.cjs +35 -0
  82. package/.claude/hooks/shared-memory-writer.cjs +147 -0
  83. package/.claude/hooks/skill-injector.cjs +140 -0
  84. package/.claude/hooks/skill-usage-logger.cjs +258 -0
  85. package/.claude/hooks/src-edit-guard.cjs +16 -1
  86. package/.claude/hooks/sync-marketplace-agents.cjs +53 -8
  87. package/.claude/scripts/yolo-toggle.cjs +142 -0
  88. package/.claude/settings.json +141 -14
  89. package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
  90. package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
  91. package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
  92. package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
  93. package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
  94. package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
  95. package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
  96. package/.claude/skills/agent-structure/SKILL.md +98 -0
  97. package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
  98. package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
  99. package/.claude/skills/delegation-routing/SKILL.md +202 -0
  100. package/.claude/skills/frontend-design/SKILL.md +254 -0
  101. package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
  102. package/.claude/skills/hailer-api-client/SKILL.md +518 -0
  103. package/.claude/skills/hailer-app-builder/SKILL.md +939 -11
  104. package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
  105. package/.claude/skills/hailer-design-system/SKILL.md +235 -0
  106. package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
  107. package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
  108. package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
  109. package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
  110. package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
  111. package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
  112. package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
  113. package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
  114. package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
  115. package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
  116. package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
  117. package/.claude/skills/insight-join-patterns/SKILL.md +3 -0
  118. package/.claude/skills/integration-patterns/SKILL.md +421 -0
  119. package/.claude/skills/json-only-output/SKILL.md +52 -12
  120. package/.claude/skills/lsp-setup/SKILL.md +160 -0
  121. package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
  122. package/.claude/skills/optional-parameters/SKILL.md +32 -23
  123. package/.claude/skills/publish-hailer-app/SKILL.md +76 -12
  124. package/.claude/skills/testing-patterns/SKILL.md +630 -0
  125. package/.claude/skills/tool-builder/SKILL.md +250 -0
  126. package/.claude/skills/tool-parameter-usage/SKILL.md +59 -45
  127. package/.claude/skills/tool-response-verification/SKILL.md +82 -48
  128. package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
  129. package/.env.example +26 -7
  130. package/CLAUDE.md +290 -224
  131. package/dist/CLAUDE.md +370 -0
  132. package/dist/app.d.ts +1 -1
  133. package/dist/app.js +101 -101
  134. package/dist/bot/bot-config.d.ts +26 -0
  135. package/dist/bot/bot-config.js +135 -0
  136. package/dist/bot/bot-manager.d.ts +40 -0
  137. package/dist/bot/bot-manager.js +137 -0
  138. package/dist/bot/bot.d.ts +127 -0
  139. package/dist/bot/bot.js +1328 -0
  140. package/dist/bot/operation-logger.d.ts +28 -0
  141. package/dist/bot/operation-logger.js +132 -0
  142. package/dist/bot/services/conversation-manager.d.ts +60 -0
  143. package/dist/bot/services/conversation-manager.js +246 -0
  144. package/dist/bot/services/index.d.ts +9 -0
  145. package/dist/bot/services/index.js +18 -0
  146. package/dist/bot/services/message-classifier.d.ts +42 -0
  147. package/dist/bot/services/message-classifier.js +228 -0
  148. package/dist/bot/services/message-formatter.d.ts +88 -0
  149. package/dist/bot/services/message-formatter.js +411 -0
  150. package/dist/bot/services/session-logger.d.ts +162 -0
  151. package/dist/bot/services/session-logger.js +724 -0
  152. package/dist/bot/services/token-billing.d.ts +78 -0
  153. package/dist/bot/services/token-billing.js +233 -0
  154. package/dist/bot/services/types.d.ts +169 -0
  155. package/dist/bot/services/types.js +12 -0
  156. package/dist/bot/services/typing-indicator.d.ts +23 -0
  157. package/dist/bot/services/typing-indicator.js +60 -0
  158. package/dist/bot/services/workspace-schema-cache.d.ts +122 -0
  159. package/dist/bot/services/workspace-schema-cache.js +506 -0
  160. package/dist/bot/tool-executor.d.ts +28 -0
  161. package/dist/bot/tool-executor.js +48 -0
  162. package/dist/bot/workspace-overview.d.ts +12 -0
  163. package/dist/bot/workspace-overview.js +94 -0
  164. package/dist/cli.d.ts +1 -8
  165. package/dist/cli.js +1 -253
  166. package/dist/config.d.ts +96 -3
  167. package/dist/config.js +148 -37
  168. package/dist/core.d.ts +5 -0
  169. package/dist/core.js +61 -8
  170. package/dist/lib/discussion-lock.d.ts +42 -0
  171. package/dist/lib/discussion-lock.js +110 -0
  172. package/dist/lib/logger.d.ts +0 -1
  173. package/dist/lib/logger.js +39 -23
  174. package/dist/lib/request-logger.d.ts +77 -0
  175. package/dist/lib/request-logger.js +147 -0
  176. package/dist/mcp/UserContextCache.js +16 -13
  177. package/dist/mcp/hailer-clients.js +18 -17
  178. package/dist/mcp/signal-handler.js +29 -13
  179. package/dist/mcp/tool-registry.d.ts +4 -15
  180. package/dist/mcp/tool-registry.js +94 -32
  181. package/dist/mcp/tools/activity.js +28 -69
  182. package/dist/mcp/tools/app-core.js +9 -4
  183. package/dist/mcp/tools/app-marketplace.js +22 -12
  184. package/dist/mcp/tools/app-member.js +5 -2
  185. package/dist/mcp/tools/app-scaffold.js +32 -18
  186. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  187. package/dist/mcp/tools/bot-config/constants.js +94 -0
  188. package/dist/mcp/tools/bot-config/core.d.ts +253 -0
  189. package/dist/mcp/tools/bot-config/core.js +2456 -0
  190. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  191. package/dist/mcp/tools/bot-config/index.js +59 -0
  192. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  193. package/dist/mcp/tools/bot-config/tools.js +15 -0
  194. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  195. package/dist/mcp/tools/bot-config/types.js +6 -0
  196. package/dist/mcp/tools/discussion.js +107 -77
  197. package/dist/mcp/tools/document.d.ts +11 -0
  198. package/dist/mcp/tools/document.js +741 -0
  199. package/dist/mcp/tools/file.js +5 -2
  200. package/dist/mcp/tools/insight.js +36 -12
  201. package/dist/mcp/tools/investigate.d.ts +9 -0
  202. package/dist/mcp/tools/investigate.js +254 -0
  203. package/dist/mcp/tools/user.d.ts +2 -4
  204. package/dist/mcp/tools/user.js +9 -50
  205. package/dist/mcp/tools/workflow.d.ts +1 -0
  206. package/dist/mcp/tools/workflow.js +164 -52
  207. package/dist/mcp/utils/hailer-api-client.js +26 -17
  208. package/dist/mcp/webhook-handler.d.ts +64 -3
  209. package/dist/mcp/webhook-handler.js +219 -9
  210. package/dist/mcp-server.d.ts +4 -0
  211. package/dist/mcp-server.js +237 -25
  212. package/dist/plugins/bug-fixer/index.d.ts +2 -0
  213. package/dist/plugins/bug-fixer/index.js +18 -0
  214. package/dist/plugins/bug-fixer/tools.d.ts +45 -0
  215. package/dist/plugins/bug-fixer/tools.js +1096 -0
  216. package/package.json +10 -10
  217. package/scripts/test-hal-tools.ts +154 -0
  218. package/.claude/agents/agent-nora-name-functions.md +0 -123
  219. package/.claude/assistant-knowledge.md +0 -23
  220. package/.claude/commands/install-plugin.md +0 -261
  221. package/.claude/commands/list-plugins.md +0 -42
  222. package/.claude/commands/marketplace-setup.md +0 -33
  223. package/.claude/commands/publish-plugin.md +0 -55
  224. package/.claude/commands/uninstall-plugin.md +0 -87
  225. package/.claude/hooks/interactive-mode.cjs +0 -87
  226. package/.claude/hooks/mcp-server-guard.cjs +0 -108
  227. package/.claude/skills/marketplace-publishing.md +0 -155
  228. package/dist/bot/chat-bot.d.ts +0 -31
  229. package/dist/bot/chat-bot.js +0 -357
  230. package/dist/mcp/tools/metrics.d.ts +0 -13
  231. package/dist/mcp/tools/metrics.js +0 -546
  232. package/dist/stdio-server.d.ts +0 -14
  233. package/dist/stdio-server.js +0 -114
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: tool-builder
3
+ description: Patterns for building MCP tools in Hailer MCP server
4
+ version: 1.0.0
5
+ triggers: MCP tool creation, Zod schemas, tool registration, API client usage
6
+ ---
7
+
8
+ # MCP Tool Builder Patterns
9
+
10
+ ## Tool Structure
11
+
12
+ MCP tools live in `src/mcp/tools/` and are registered in `src/app.ts`.
13
+
14
+ ```typescript
15
+ // src/mcp/tools/example.ts
16
+ import { z } from 'zod';
17
+ import { McpTool, ToolContext } from '../types.js';
18
+
19
+ export const myTool: McpTool = {
20
+ name: 'my_tool',
21
+ description: 'What this tool does',
22
+ inputSchema: z.object({
23
+ requiredParam: z.string().describe('Description'),
24
+ optionalParam: z.coerce.number().optional().default(50)
25
+ }),
26
+ annotations: { toolGroup: 'READ' },
27
+ handler: async (args, context: ToolContext) => {
28
+ // Implementation
29
+ }
30
+ };
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Tool Groups
36
+
37
+ | Group | Purpose | Examples |
38
+ |-------|---------|----------|
39
+ | `READ` | Safe reads, no side effects | list_workflows, get_activity |
40
+ | `WRITE` | Create/update data | create_activity, update_activity |
41
+ | `PLAYGROUND` | Admin/testing tools | install_workflow, preview_insight |
42
+ | `NUCLEAR` | Destructive operations | remove_workflow, delete_activity |
43
+
44
+ ---
45
+
46
+ ## Zod Schema Coercion
47
+
48
+ MCP sends all values as strings. Use coercion:
49
+
50
+ ```typescript
51
+ // Numbers
52
+ z.coerce.number().optional().default(50)
53
+
54
+ // Booleans
55
+ z.coerce.boolean().optional().default(true)
56
+
57
+ // Arrays (from JSON string)
58
+ z.preprocess(
59
+ (val) => typeof val === 'string' ? JSON.parse(val) : val,
60
+ z.array(z.string())
61
+ )
62
+
63
+ // Objects (from JSON string)
64
+ z.preprocess(
65
+ (val) => typeof val === 'string' ? JSON.parse(val) : val,
66
+ z.record(z.any())
67
+ )
68
+
69
+ // Optional with default
70
+ z.string().optional().default('default_value')
71
+ ```
72
+
73
+ ---
74
+
75
+ ## API Client Methods
76
+
77
+ Access via `context.hailer`:
78
+
79
+ ```typescript
80
+ // Socket API call
81
+ const result = await context.hailer.request('v3.endpoint.method', [arg1, arg2]);
82
+
83
+ // REST API call
84
+ const result = await context.hailer.callRest({
85
+ endpoint: '/api/v3/something',
86
+ method: 'POST',
87
+ body: { data }
88
+ });
89
+
90
+ // Convenience methods
91
+ const schema = await context.hailer.getWorkflowSchema(workflowId, phaseId);
92
+ const activity = await context.hailer.fetchActivityById(activityId);
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Type Discovery Workflow
98
+
99
+ When you don't know the exact API response shape:
100
+
101
+ 1. **Implement with `any` + logging**
102
+ ```typescript
103
+ handler: async (args, context) => {
104
+ const result = await context.hailer.request('v3.new.endpoint', [args.id]);
105
+ context.logger.debug('API response:', JSON.stringify(result, null, 2));
106
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
107
+ }
108
+ ```
109
+
110
+ 2. **Test the tool** - Call it and check server logs
111
+
112
+ 3. **Update to proper types** - Based on logged output
113
+
114
+ 4. **Test again** - Verify typed version works
115
+
116
+ ---
117
+
118
+ ## Tool Registration
119
+
120
+ After creating a tool, register it in `src/app.ts`:
121
+
122
+ ```typescript
123
+ // In src/app.ts
124
+ import { myTool } from './mcp/tools/example.js';
125
+
126
+ // Add to tools array
127
+ const tools = [
128
+ // ... existing tools
129
+ myTool,
130
+ ];
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Common Patterns
136
+
137
+ ### List endpoint
138
+ ```typescript
139
+ export const listThings: McpTool = {
140
+ name: 'list_things',
141
+ description: 'List all things in workspace',
142
+ inputSchema: z.object({
143
+ limit: z.coerce.number().optional().default(100).describe('Max results')
144
+ }),
145
+ annotations: { toolGroup: 'READ' },
146
+ handler: async (args, context) => {
147
+ const result = await context.hailer.request('v3.thing.list', [
148
+ context.workspaceId,
149
+ { limit: args.limit }
150
+ ]);
151
+ return {
152
+ content: [{
153
+ type: 'text',
154
+ text: JSON.stringify(result, null, 2)
155
+ }]
156
+ };
157
+ }
158
+ };
159
+ ```
160
+
161
+ ### Get by ID endpoint
162
+ ```typescript
163
+ export const getThing: McpTool = {
164
+ name: 'get_thing',
165
+ description: 'Get thing by ID',
166
+ inputSchema: z.object({
167
+ thingId: z.string().describe('Thing UUID')
168
+ }),
169
+ annotations: { toolGroup: 'READ' },
170
+ handler: async (args, context) => {
171
+ const result = await context.hailer.request('v3.thing.get', [args.thingId]);
172
+ return {
173
+ content: [{
174
+ type: 'text',
175
+ text: JSON.stringify(result, null, 2)
176
+ }]
177
+ };
178
+ }
179
+ };
180
+ ```
181
+
182
+ ### Create endpoint
183
+ ```typescript
184
+ export const createThing: McpTool = {
185
+ name: 'create_thing',
186
+ description: 'Create a new thing',
187
+ inputSchema: z.object({
188
+ name: z.string().describe('Thing name'),
189
+ data: z.preprocess(
190
+ (val) => typeof val === 'string' ? JSON.parse(val) : val,
191
+ z.record(z.any())
192
+ ).optional().describe('Additional data as JSON')
193
+ }),
194
+ annotations: { toolGroup: 'WRITE' },
195
+ handler: async (args, context) => {
196
+ const result = await context.hailer.request('v3.thing.create', [{
197
+ workspaceId: context.workspaceId,
198
+ name: args.name,
199
+ ...args.data
200
+ }]);
201
+ return {
202
+ content: [{
203
+ type: 'text',
204
+ text: JSON.stringify({ created: result._id }, null, 2)
205
+ }]
206
+ };
207
+ }
208
+ };
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Edit Mode Guard
214
+
215
+ Before editing MCP server code, enable edit mode:
216
+
217
+ ```bash
218
+ # Enable editing
219
+ node .claude/hooks/src-edit-guard.cjs --on
220
+
221
+ # ... make edits ...
222
+
223
+ # Disable editing
224
+ node .claude/hooks/src-edit-guard.cjs --off
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Build Verification
230
+
231
+ Always verify build passes after changes:
232
+
233
+ ```bash
234
+ npm run build
235
+ ```
236
+
237
+ Tool is only complete when build passes without errors.
238
+
239
+ ---
240
+
241
+ ## Common Mistakes
242
+
243
+ | Wrong | Right |
244
+ |-------|-------|
245
+ | `z.number()` for MCP input | `z.coerce.number()` - values come as strings |
246
+ | `z.boolean()` for MCP input | `z.coerce.boolean()` |
247
+ | `z.array()` directly | `z.preprocess()` wrapper to parse JSON string |
248
+ | Forgetting to register tool | Add to `src/app.ts` tools array |
249
+ | Skipping build check | Always run `npm run build` |
250
+ | Using wrong tool group | READ for queries, WRITE for mutations |
@@ -1,14 +1,19 @@
1
1
  ---
2
2
  name: tool-parameter-usage
3
3
  description: Extract IDs from context and use correct parameter formats for Hailer tools
4
+ version: 1.1.0
4
5
  triggers: Tool validation failed with "Required" error, empty receivedArgs, or field format errors
5
6
  ---
6
7
 
7
- <problem>
8
- LLM calls tools with empty parameters `{}` even when context contains required IDs, or uses wrong parameter names/formats.
9
- </problem>
8
+ # Tool Parameter Usage
9
+
10
+ <purpose>
11
+ Teach correct extraction of IDs from message context and proper parameter formats for Hailer tool calls, preventing empty parameter errors and format mismatches.
12
+ </purpose>
13
+
14
+ <patterns>
15
+ ## Pattern 1: Context Extraction
10
16
 
11
- <context-extraction>
12
17
  The `<incoming>` tag in messages contains critical IDs. ALWAYS extract and use them:
13
18
 
14
19
  ```xml
@@ -20,51 +25,83 @@ The `<incoming>` tag in messages contains critical IDs. ALWAYS extract and use t
20
25
  **Extract before calling tools:**
21
26
  - `activityId` → use for `show_activity_by_id`, `update_activity`
22
27
  - `discussionId` → use for `get_activity_from_discussion`, `add_discussion_message`
23
- </context-extraction>
24
28
 
25
- <correct>
29
+ ## Pattern 2: Single vs Bulk Mode Parameters
30
+
31
+ | Tool | Single mode | Bulk mode |
32
+ |------|-------------|-----------|
33
+ | `create_activity` | Top-level `name`, `phaseId`, `teamId`, `fields` | Inside each `activities[]` item |
34
+ | `update_activity` | `activityId` | `activities[]._id` |
35
+ | `show_activity_by_id` | `activityId` | N/A |
36
+ | `get_activity_from_discussion` | `discussionId` | N/A |
37
+
38
+ **CRITICAL for `create_activity` bulk mode:** `teamId`, `phaseId`, and `fields` must be **inside each activity object** in the `activities[]` array. Top-level values (except `workflowId`) are IGNORED in bulk mode. This causes "Missing team(s)" (code 127) if teamId is only at the top level.
39
+
40
+ ## Pattern 3: Field Value Formats
41
+
42
+ | Field type | Value format |
43
+ |------------|--------------|
44
+ | `numericunit` | Plain number: `78` |
45
+ | `text` | Plain string: `"hello"` |
46
+ | `activitylink` | Activity ID string: `"abc123..."` |
47
+ | `select` | Option key: `"option_key"` |
48
+
49
+ **Never pass objects with `type` metadata** - Hailer API expects plain values.
50
+ </patterns>
51
+
52
+ <examples>
53
+ ## Example 1: Correct - Extracting IDs from Context
54
+
26
55
  ```typescript
27
56
  // Context: <incoming activityId="69384669b7826c5d9ec4e07c" discussionId="69384669b7826c5d9ec4e07d">
28
57
 
29
- // CORRECT - Extract activityId from context
58
+ // CORRECT - Extract activityId from context
30
59
  show_activity_by_id({
31
60
  activityId: "69384669b7826c5d9ec4e07c"
32
61
  });
33
62
 
34
- // CORRECT - Single update mode uses activityId
63
+ // CORRECT - Get activity from discussion
64
+ get_activity_from_discussion({
65
+ discussionId: "69384669b7826c5d9ec4e07d"
66
+ });
67
+ ```
68
+
69
+ ## Example 2: Correct - Single vs Bulk Update Mode
70
+
71
+ ```typescript
72
+ // CORRECT - Single update mode uses activityId
35
73
  update_activity({
36
74
  activityId: "69384669b7826c5d9ec4e07c",
37
75
  fields: { "fieldId123": 78 }
38
76
  });
39
77
 
40
- // CORRECT - Bulk update mode uses _id (NOT activityId)
78
+ // CORRECT - Bulk update mode uses _id (NOT activityId)
41
79
  update_activity({
42
80
  activities: [{
43
81
  _id: "69384669b7826c5d9ec4e07c",
44
82
  fields: { "fieldId123": 78 }
45
83
  }]
46
84
  });
85
+ ```
86
+
87
+ ## Example 3: Correct - Field Value Formats
47
88
 
48
- // ✅ CORRECT - numericunit field = plain number
89
+ ```typescript
90
+ // CORRECT - numericunit field = plain number
49
91
  update_activity({
50
92
  activityId: "69384669b7826c5d9ec4e07c",
51
93
  fields: { "weightFieldId": 78 }
52
94
  });
53
-
54
- // ✅ CORRECT - Get activity from discussion
55
- get_activity_from_discussion({
56
- discussionId: "69384669b7826c5d9ec4e07d"
57
- });
58
95
  ```
59
- </correct>
60
96
 
61
- <wrong>
97
+ ## Example 4: Wrong - Common Errors
98
+
62
99
  ```typescript
63
- // WRONG - Empty parameters (ignoring context)
100
+ // WRONG - Empty parameters (ignoring context)
64
101
  show_activity_by_id({});
65
102
  // Error: activityId: Required, receivedArgs={}
66
103
 
67
- // WRONG - Using activityId in bulk mode (should be _id)
104
+ // WRONG - Using activityId in bulk mode (should be _id)
68
105
  update_activity({
69
106
  activities: [{
70
107
  activityId: "69384669b7826c5d9ec4e07c", // WRONG KEY
@@ -73,7 +110,7 @@ update_activity({
73
110
  });
74
111
  // Error: activities.0._id: Required
75
112
 
76
- // WRONG - Passing object for numericunit field
113
+ // WRONG - Passing object for numericunit field
77
114
  update_activity({
78
115
  activityId: "69384669b7826c5d9ec4e07c",
79
116
  fields: {
@@ -82,31 +119,8 @@ update_activity({
82
119
  });
83
120
  // Error: "Weight" must be a number
84
121
 
85
- // WRONG - Empty list_activities call
122
+ // WRONG - Empty list_activities call
86
123
  list_activities({});
87
124
  // Error: workflowId: Required, phaseId: Required
88
125
  ```
89
- </wrong>
90
-
91
- <fix>
92
- **Before calling ANY tool:**
93
- 1. Check `<incoming>` tag for `activityId` and `discussionId`
94
- 2. Extract these values and pass them to tools
95
-
96
- **Parameter rules:**
97
- | Tool | Single mode | Bulk mode |
98
- |------|-------------|-----------|
99
- | `update_activity` | `activityId` | `activities[].\_id` |
100
- | `show_activity_by_id` | `activityId` | N/A |
101
- | `get_activity_from_discussion` | `discussionId` | N/A |
102
-
103
- **Field value formats:**
104
- | Field type | Value format |
105
- |------------|--------------|
106
- | `numericunit` | Plain number: `78` |
107
- | `text` | Plain string: `"hello"` |
108
- | `activitylink` | Activity ID string: `"abc123..."` |
109
- | `select` | Option key: `"option_key"` |
110
-
111
- **Never pass objects with `type` metadata** - Hailer API expects plain values.
112
- </fix>
126
+ </examples>
@@ -1,58 +1,92 @@
1
1
  ---
2
2
  name: tool-response-verification
3
- description: Ensure agents verify tool execution before claiming success
4
- triggers: Agent returns success without checking tool result
3
+ description: Verify MCP tool execution results before reporting success
4
+ version: 1.0.0
5
+ triggers:
6
+ - MCP tool failure
7
+ - fabricated response
8
+ - tool result verification
9
+ - silent failure
10
+ - disconnected server
5
11
  ---
6
12
 
7
- <problem>
8
- Agent fabricates success response without verifying actual tool execution result.
9
- </problem>
10
-
11
- <correct>
12
- ```typescript
13
- // Call tool
14
- const result = await update_insight({
15
- insightId: "abc123",
16
- public: false
17
- });
18
-
19
- // Verify tool response before returning to orchestrator
20
- if (result.error) {
21
- return {
22
- status: "error",
23
- error: result.error,
24
- summary: "Update failed"
25
- };
13
+ # Tool Response Verification
14
+
15
+ <purpose>
16
+ Ensure agents verify actual tool execution results before reporting success, preventing fabricated responses when MCP servers are disconnected or tools fail silently.
17
+ </purpose>
18
+
19
+ <patterns>
20
+ ## Pattern 1: Always Check Tool Results
21
+
22
+ Every MCP tool call returns a result. Read it before proceeding.
23
+
24
+ ## Pattern 2: Never Assume Success
25
+
26
+ If you didn't see confirmation in the result, it didn't happen.
27
+
28
+ ## Pattern 3: Report Actual Errors
29
+
30
+ If tool returned error, report error status - don't fabricate success.
31
+
32
+ ## Pattern 4: No Fabrication
33
+
34
+ Never claim "created 5 activities" if you didn't see 5 activity IDs returned.
35
+
36
+ ## Pattern 5: Verification Checklist
37
+
38
+ Before returning success:
39
+ - Did the tool return a result (not an error)?
40
+ - Does the result contain expected data (IDs, counts, etc.)?
41
+ - Am I reporting data FROM the result, not data I expected?
42
+
43
+ ## Pattern 6: Detect MCP Connection Errors
44
+
45
+ When an MCP server is offline, tools return empty results, undefined data, or error messages instead of clear failures. This looks like "success" but is actually a connection problem.
46
+
47
+ **Red flags:**
48
+ - Empty array when data is expected (e.g., `workflows: []` for a non-empty workspace)
49
+ - Missing schema fields that should always be present
50
+ - Undefined/null responses from tools that normally return structured data
51
+ - Error messages containing: "connection", "ECONNREFUSED", "timeout", "unavailable", "ENOTFOUND"
52
+
53
+ **What to do:**
54
+ Instead of reporting empty data as success, report: "MCP server appears offline - tool returned empty/error result. Check that the MCP server is running."
55
+
56
+ Return error status, not success:
57
+ ```json
58
+ {
59
+ "status": "error",
60
+ "result": { "tool": "tool_name", "error": "MCP server appears offline" },
61
+ "summary": "Cannot proceed: MCP server not responding"
26
62
  }
63
+ ```
64
+ </patterns>
65
+
66
+ <examples>
67
+ ## Example 1: Correct - Verify Before Reporting
68
+
69
+ ```
70
+ GOOD: Call create_activity → read result → if result.activityId exists → return success
71
+ GOOD: "Created customer with ID abc123" (ID from actual result)
72
+ ```
73
+
74
+ ## Example 2: Wrong - Fabricating Success
27
75
 
28
- return {
29
- status: "success",
30
- result: { updated: true, insight_id: result.id },
31
- summary: "Updated insight"
32
- };
33
76
  ```
34
- </correct>
35
-
36
- <wrong>
37
- ```typescript
38
- // Call tool (that might fail)
39
- update_insight({ insightId: "abc123", public: false });
40
-
41
- // Immediately return success WITHOUT checking tool result
42
- return {
43
- status: "success",
44
- result: { updated: true },
45
- summary: "Updated insight"
46
- };
77
+ BAD: Call create_activity → immediately return {"status": "success", "created": 1}
78
+ BAD: "I created the customer" (without checking result)
47
79
  ```
48
- </wrong>
49
80
 
50
- <fix>
51
- 1. **NEVER assume tool success** - Always capture and check tool response
52
- 2. **Return actual error messages** - If tool fails, return error status with real error message
53
- 3. **Verify before claiming success** - Only return success after confirming tool execution succeeded
54
- 4. **Test error paths** - If unsure about tool behavior, preview/test first
81
+ ## Example 3: Correct - Error Reporting
55
82
 
56
- This is a violation of Rule 1: "NEVER FABRICATE - Must call tools."
57
- Fabricating a success response when tool failed is the same as not calling the tool.
58
- </fix>
83
+ When tools fail, report the actual error:
84
+
85
+ ```json
86
+ {
87
+ "status": "error",
88
+ "result": { "tool": "tool_name", "error": "actual error message" },
89
+ "summary": "Tool failed: brief reason"
90
+ }
91
+ ```
92
+ </examples>