@spilno/herald-mcp 1.18.0 → 1.20.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/README.md CHANGED
@@ -1,13 +1,24 @@
1
1
  # @spilno/herald-mcp
2
2
 
3
- Herald MCP - AI-native interface to [CEDA](https://getceda.com) (Cognitive Event-Driven Architecture).
3
+ > AI-native interface to [CEDA](https://getceda.com) pattern memory for AI agents.
4
4
 
5
- **Dual-mode**: Natural chat for humans, MCP for AI agents.
5
+ Herald bridges AI agents and CEDA's cognitive pattern memory. Your AI remembers what worked.
6
+
7
+ ## Why Herald?
8
+
9
+ AI agents start fresh each session. Herald gives them memory:
10
+
11
+ | Without Herald | With Herald |
12
+ |----------------|-------------|
13
+ | AI forgets past sessions | Patterns persist across sessions |
14
+ | Same mistakes repeated | Antipatterns prevent failures |
15
+ | Generic responses | Context-aware predictions |
16
+ | No learning curve | Knowledge compounds |
6
17
 
7
18
  ## Quick Start
8
19
 
9
20
  ```bash
10
- # Initialize Herald MCP config for Claude Desktop
21
+ # One command setup for Claude Desktop
11
22
  npx @spilno/herald-mcp init
12
23
 
13
24
  # Or install globally
@@ -15,17 +26,53 @@ npm install -g @spilno/herald-mcp
15
26
  herald-mcp init
16
27
  ```
17
28
 
18
- That's it. Herald is now configured for Claude Desktop.
29
+ Done. Herald is now available to Claude.
30
+
31
+ ## Core Tools
32
+
33
+ | Tool | Purpose |
34
+ |------|---------|
35
+ | `herald_predict` | Generate structure from natural language |
36
+ | `herald_refine` | Refine predictions with feedback |
37
+ | `herald_patterns` | Query what worked before |
38
+ | `herald_reflect` | Capture patterns and antipatterns |
39
+ | `herald_feedback` | Reinforce helpful patterns |
19
40
 
20
- ## Init Command (New in v1.4.0)
41
+ ### Pattern Memory
21
42
 
22
- The `init` command creates `.claude/settings.json` with Herald MCP configuration:
43
+ ```
44
+ AI: herald_patterns()
45
+ → Returns: patterns that worked, antipatterns to avoid
46
+
47
+ AI: herald_predict("create safety assessment module")
48
+ → Returns: structured prediction based on accumulated patterns
49
+
50
+ User: "That worked well"
51
+ AI: herald_reflect(feeling="success", insight="field grouping approach")
52
+ → Pattern captured, weight increased
53
+ ```
54
+
55
+ ## Session Flow
23
56
 
24
57
  ```bash
25
- npx @spilno/herald-mcp init
58
+ # Start a session
59
+ herald-mcp predict "create incident report module"
60
+
61
+ # Refine iteratively
62
+ herald-mcp refine "add witness section"
63
+ herald-mcp refine "require photos for severity > 3"
64
+
65
+ # Accept when satisfied
66
+ herald-mcp observe yes
67
+
68
+ # Resume anytime
69
+ herald-mcp resume
26
70
  ```
27
71
 
28
- This creates:
72
+ ## Configuration
73
+
74
+ ### Claude Desktop / Claude Code
75
+
29
76
  ```json
30
77
  {
31
78
  "mcpServers": {
@@ -40,140 +87,110 @@ This creates:
40
87
  }
41
88
  ```
42
89
 
43
- Options:
44
- - `--help, -h` - Show help
45
- - `--force, -f` - Overwrite existing settings.json
46
-
47
- ## Chat Mode (Natural Conversation)
90
+ ### Environment Variables
48
91
 
49
- ```bash
50
- export HERALD_API_URL=https://getceda.com
51
- herald-mcp chat
52
- ```
92
+ | Variable | Required | Description |
93
+ |----------|----------|-------------|
94
+ | `HERALD_API_URL` | Yes | CEDA server (default: https://getceda.com) |
95
+ | `HERALD_COMPANY` | No | Multi-tenant company context |
96
+ | `HERALD_PROJECT` | No | Project context |
97
+ | `HERALD_USER` | No | User context |
53
98
 
54
- ```
55
- You: I need a safety assessment module for construction sites
56
- Herald: I've designed a Safety Assessment module with 4 sections...
99
+ ## Multi-Tenant Isolation
57
100
 
58
- You: Add OSHA compliance fields
59
- Herald: Done. Added compliance checklist to Risk Evaluation...
101
+ Patterns are isolated by context:
60
102
 
61
- You: Looks good, let's use it
62
- Herald: Great! Module accepted and saved.
63
103
  ```
64
-
65
- ## Command Mode (Structured)
66
-
67
- ```bash
68
- herald-mcp predict "create safety assessment"
69
- herald-mcp refine "add OSHA compliance"
70
- herald-mcp resume
71
- herald-mcp observe yes
72
- herald-mcp new
73
- herald-mcp health
74
- herald-mcp stats
104
+ Company A patterns → Only visible to Company A
105
+ Project X patterns → Only visible to Project X users
75
106
  ```
76
107
 
77
- ## Session Persistence
78
-
79
- Sessions saved to `~/.herald/session` - resume anytime:
80
-
108
+ Set context via environment or headers:
81
109
  ```bash
82
- # Start today
83
- herald-mcp predict "create incident report module"
84
-
85
- # Continue tomorrow
86
- herald-mcp resume
87
- herald-mcp refine "add witness statements section"
110
+ export HERALD_COMPANY=acme
111
+ export HERALD_PROJECT=safety-modules
88
112
  ```
89
113
 
90
- ## Environment Variables
114
+ ## Herald Context Sync
91
115
 
92
- | Variable | Required | Description |
93
- |----------|----------|-------------|
94
- | `HERALD_API_URL` | Yes | CEDA server URL |
95
- | `HERALD_API_TOKEN` | No | Bearer token for auth |
96
- | `HERALD_COMPANY` | No | Multi-tenant company context |
97
- | `HERALD_PROJECT` | No | Multi-tenant project context |
98
- | `HERALD_VAULT` | No | Offspring vault ID (spilno, goprint, disrupt) |
99
- | `HERALD_OFFSPRING_CLOUD` | No | Set to "true" for cloud mode |
100
- | `AEGIS_OFFSPRING_PATH` | No | Local path to offspring status files |
101
-
102
- ## Herald Context Sync (v1.3.0+)
103
-
104
- Herald instances can communicate across contexts, sharing insights and synchronizing status:
105
-
106
- ### Tools
116
+ Herald instances share insights across contexts:
107
117
 
108
118
  | Tool | Purpose |
109
119
  |------|---------|
110
- | `herald_context_status` | Read status from Herald contexts across domains |
111
- | `herald_share_insight` | Share a pattern insight with another context |
112
- | `herald_query_insights` | Query accumulated insights on a topic |
120
+ | `herald_context_status` | Check status of Herald instances |
121
+ | `herald_share_insight` | Share pattern to other contexts |
122
+ | `herald_query_insights` | Query shared insights |
123
+ | `herald_sync` | Flush local buffer to cloud |
113
124
 
114
- ### Local Mode (Default)
125
+ ## Chat Mode
115
126
 
116
- ```bash
117
- # Context files in local directory
118
- export AEGIS_OFFSPRING_PATH=~/Documents/aegis_ceda/_offspring
119
- export HERALD_VAULT=spilno # Which context this Herald serves
127
+ For humans who prefer conversation:
120
128
 
121
- herald-mcp # MCP mode uses local files
129
+ ```bash
130
+ herald-mcp chat
122
131
  ```
123
132
 
124
- ### Cloud Mode
133
+ ```
134
+ You: I need a permit-to-work module
135
+ Herald: I've designed a Permit-to-Work module with 5 sections...
125
136
 
126
- ```bash
127
- # Use CEDA API for context synchronization
128
- export HERALD_API_URL=https://getceda.com
129
- export HERALD_OFFSPRING_CLOUD=true
130
- export HERALD_VAULT=spilno
137
+ You: Add gas testing checklist
138
+ Herald: Added gas testing to Pre-Work Safety section...
131
139
 
132
- herald-mcp # MCP mode calls CEDA API
140
+ You: Perfect
141
+ Herald: Module accepted and saved.
133
142
  ```
134
143
 
135
- ### Herald-to-Herald Protocol
144
+ ## Command Reference
136
145
 
137
- ```
138
- POST /api/herald/heartbeat # Herald reports its context status
139
- GET /api/herald/contexts # Herald discovers sibling contexts
140
- POST /api/herald/insight # Herald shares an insight
141
- GET /api/herald/insights # Herald queries shared insights
146
+ ```bash
147
+ herald-mcp init # Setup for Claude Desktop
148
+ herald-mcp chat # Interactive conversation mode
149
+ herald-mcp predict <signal> # Generate prediction
150
+ herald-mcp refine <signal> # Refine current prediction
151
+ herald-mcp resume # Resume last session
152
+ herald-mcp observe <yes|no> # Accept or reject prediction
153
+ herald-mcp new # Start fresh session
154
+ herald-mcp health # Check CEDA connection
155
+ herald-mcp stats # Show loaded patterns
142
156
  ```
143
157
 
144
- ## MCP Mode (for AI Agents)
158
+ ## Architecture
145
159
 
146
- When piped, Herald speaks JSON-RPC for Claude, Devin, and other AI agents.
160
+ ```
161
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
162
+ │ AI Agent │────▶│ Herald │────▶│ CEDA │
163
+ │ (Claude/ │ │ (MCP) │ │ (Pattern │
164
+ │ Devin/etc) │◀────│ │◀────│ Memory) │
165
+ └─────────────┘ └─────────────┘ └─────────────┘
166
+
167
+ ┌──────┴──────┐
168
+ │ Patterns │
169
+ │ Antipatterns│
170
+ │ Feedback │
171
+ └─────────────┘
172
+ ```
147
173
 
148
- ### Claude Code (~/.claude.json)
174
+ ## What is CEDA?
149
175
 
150
- ```json
151
- {
152
- "mcpServers": {
153
- "herald": {
154
- "command": "npx",
155
- "args": ["@spilno/herald-mcp"],
156
- "env": {
157
- "HERALD_API_URL": "https://getceda.com"
158
- }
159
- }
160
- }
161
- }
162
- ```
176
+ CEDA (Cognitive Event-Driven Architecture) is pattern memory for AI:
163
177
 
164
- ### Devin MCP Marketplace
178
+ - **Patterns**: Approaches that worked (weighted by effectiveness)
179
+ - **Antipatterns**: Approaches that failed (avoided in predictions)
180
+ - **Feedback loop**: Patterns strengthen or decay based on outcomes
165
181
 
166
- - **Server Name**: Herald-CEDA
167
- - **Command**: `npx @spilno/herald-mcp`
168
- - **Environment**: `HERALD_API_URL=https://getceda.com`
182
+ Unlike RAG (retrieves content), CEDA retrieves **what worked**.
169
183
 
170
- ## Architecture
184
+ ## Links
171
185
 
172
- ```
173
- Human ←→ Herald (Claude voice) ←→ CEDA (cognition)
174
- Agent ←→ Herald (JSON-RPC) ←→ CEDA
175
- ```
186
+ - **CEDA**: https://getceda.com
187
+ - **Documentation**: https://getceda.com/docs
188
+ - **GitHub**: https://github.com/Spilno-me/ceda
176
189
 
177
190
  ## License
178
191
 
179
192
  MIT
193
+
194
+ ---
195
+
196
+ *Herald v1.20.0 — Pattern memory for AI agents*
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CEDA-64: Unit tests for Herald MCP Command Extensions
3
+ *
4
+ * Tests the 3 new command extension tools:
5
+ * - herald_session_reflections
6
+ * - herald_pattern_feedback
7
+ * - herald_share_scoped
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=command-extensions.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-extensions.spec.d.ts","sourceRoot":"","sources":["../src/command-extensions.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * CEDA-64: Unit tests for Herald MCP Command Extensions
3
+ *
4
+ * Tests the 3 new command extension tools:
5
+ * - herald_session_reflections
6
+ * - herald_pattern_feedback
7
+ * - herald_share_scoped
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ describe('CEDA-64: Herald Command Extensions', () => {
12
+ const indexPath = path.join(process.cwd(), 'src', 'index.ts');
13
+ let indexContent;
14
+ beforeAll(() => {
15
+ indexContent = fs.readFileSync(indexPath, 'utf-8');
16
+ });
17
+ describe('Tool definitions', () => {
18
+ it('should have herald_session_reflections tool defined', () => {
19
+ expect(indexContent).toContain('name: "herald_session_reflections"');
20
+ expect(indexContent).toContain('Get summary of reflections captured during this MCP session');
21
+ });
22
+ it('should have herald_pattern_feedback tool defined', () => {
23
+ expect(indexContent).toContain('name: "herald_pattern_feedback"');
24
+ expect(indexContent).toContain('Provide feedback on whether a learned pattern/antipattern helped');
25
+ });
26
+ it('should have herald_share_scoped tool defined', () => {
27
+ expect(indexContent).toContain('name: "herald_share_scoped"');
28
+ expect(indexContent).toContain('Share an insight with other Herald contexts using scope control');
29
+ });
30
+ });
31
+ describe('Tool input schemas', () => {
32
+ it('herald_session_reflections should have no required properties', () => {
33
+ // Check that the tool has empty properties (no required inputs)
34
+ expect(indexContent).toMatch(/herald_session_reflections[\s\S]*?inputSchema[\s\S]*?properties:\s*\{\}/);
35
+ });
36
+ it('herald_pattern_feedback should have pattern_id, pattern_text, and outcome properties', () => {
37
+ expect(indexContent).toMatch(/herald_pattern_feedback[\s\S]*?pattern_id.*ID of the pattern/);
38
+ expect(indexContent).toMatch(/herald_pattern_feedback[\s\S]*?pattern_text.*Alternative.*pattern text to match/);
39
+ expect(indexContent).toMatch(/herald_pattern_feedback[\s\S]*?outcome.*helped.*didnt_help/);
40
+ expect(indexContent).toMatch(/herald_pattern_feedback[\s\S]*?required.*outcome/);
41
+ });
42
+ it('herald_share_scoped should have insight, scope, and topic properties', () => {
43
+ expect(indexContent).toContain('name: "herald_share_scoped"');
44
+ expect(indexContent).toContain('"parent", "siblings", "all"');
45
+ expect(indexContent).toContain('Optional topic category for the insight');
46
+ expect(indexContent).toContain('required: ["insight", "scope"]');
47
+ });
48
+ });
49
+ describe('Tool handlers', () => {
50
+ it('herald_session_reflections handler should call getSessionReflectionsSummary', () => {
51
+ expect(indexContent).toContain('case "herald_session_reflections"');
52
+ expect(indexContent).toMatch(/case "herald_session_reflections"[\s\S]*?getSessionReflectionsSummary/);
53
+ });
54
+ it('herald_pattern_feedback handler should POST to /api/herald/feedback endpoint', () => {
55
+ expect(indexContent).toContain('case "herald_pattern_feedback"');
56
+ expect(indexContent).toMatch(/case "herald_pattern_feedback"[\s\S]*?\/api\/herald\/feedback.*POST/);
57
+ });
58
+ it('herald_share_scoped handler should POST to /api/herald/share endpoint', () => {
59
+ expect(indexContent).toContain('case "herald_share_scoped"');
60
+ expect(indexContent).toMatch(/case "herald_share_scoped"[\s\S]*?\/api\/herald\/share.*POST/);
61
+ });
62
+ });
63
+ describe('Session reflection tracking', () => {
64
+ it('should have SessionReflection interface defined', () => {
65
+ expect(indexContent).toContain('interface SessionReflection');
66
+ expect(indexContent).toMatch(/SessionReflection[\s\S]*?id:\s*string/);
67
+ expect(indexContent).toMatch(/SessionReflection[\s\S]*?session:\s*string/);
68
+ expect(indexContent).toMatch(/SessionReflection[\s\S]*?feeling:\s*"stuck"\s*\|\s*"success"/);
69
+ expect(indexContent).toMatch(/SessionReflection[\s\S]*?insight:\s*string/);
70
+ expect(indexContent).toMatch(/SessionReflection[\s\S]*?method:\s*"direct"\s*\|\s*"simulation"/);
71
+ expect(indexContent).toMatch(/SessionReflection[\s\S]*?timestamp:\s*string/);
72
+ });
73
+ it('should have sessionReflections array defined', () => {
74
+ expect(indexContent).toContain('const sessionReflections: SessionReflection[] = []');
75
+ });
76
+ it('should have addSessionReflection function defined', () => {
77
+ expect(indexContent).toContain('function addSessionReflection');
78
+ });
79
+ it('should have getSessionReflectionsSummary function defined', () => {
80
+ expect(indexContent).toContain('function getSessionReflectionsSummary');
81
+ });
82
+ it('herald_reflect should track reflections locally', () => {
83
+ expect(indexContent).toMatch(/case "herald_reflect"[\s\S]*?addSessionReflection/);
84
+ });
85
+ it('herald_simulate should track reflections locally', () => {
86
+ expect(indexContent).toMatch(/case "herald_simulate"[\s\S]*?addSessionReflection/);
87
+ });
88
+ });
89
+ describe('Version', () => {
90
+ it('should be version 1.19.0 in index.ts', () => {
91
+ expect(indexContent).toContain('const VERSION = "1.19.0"');
92
+ });
93
+ it('should have matching version in package.json', () => {
94
+ const packagePath = path.join(process.cwd(), 'package.json');
95
+ const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
96
+ expect(packageJson.version).toBe('1.19.0');
97
+ });
98
+ });
99
+ describe('CEDA-64 comment markers', () => {
100
+ it('should have CEDA-64 comment in tool definitions', () => {
101
+ expect(indexContent).toContain('// CEDA-64: Herald Command Extensions');
102
+ });
103
+ it('should have CEDA-64 comment in session reflection tracking', () => {
104
+ expect(indexContent).toContain('// CEDA-64: Session reflection tracking');
105
+ });
106
+ it('should have CEDA-64 comment in tool handlers', () => {
107
+ expect(indexContent).toContain('// CEDA-64: Herald Command Extensions - Handlers');
108
+ });
109
+ it('should have CEDA-64 comment in herald_reflect handler', () => {
110
+ expect(indexContent).toMatch(/case "herald_reflect"[\s\S]*?CEDA-64: Track reflection locally/);
111
+ });
112
+ it('should have CEDA-64 comment in herald_simulate handler', () => {
113
+ expect(indexContent).toMatch(/case "herald_simulate"[\s\S]*?CEDA-64: Track reflection locally/);
114
+ });
115
+ });
116
+ });
117
+ //# sourceMappingURL=command-extensions.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-extensions.spec.js","sourceRoot":"","sources":["../src/command-extensions.spec.ts"],"names":[],"mappings":"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"}