@spilno/herald-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/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # @spilno/herald-mcp
2
+
3
+ Herald MCP - Diplomatic interface to [CEDA](https://getceda.com) (Cognitive Event-Driven Architecture).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx @spilno/herald-mcp
9
+ ```
10
+
11
+ Or install globally:
12
+
13
+ ```bash
14
+ npm install -g @spilno/herald-mcp
15
+ herald-mcp
16
+ ```
17
+
18
+ ## Configuration
19
+
20
+ Set environment variables:
21
+
22
+ | Variable | Required | Description |
23
+ |----------|----------|-------------|
24
+ | `HERALD_API_URL` | Yes | CEDA server URL (e.g., `https://getceda.com`) |
25
+ | `HERALD_API_TOKEN` | No | Bearer token for authentication |
26
+
27
+ ## Tools
28
+
29
+ Herald exposes these MCP tools:
30
+
31
+ - **herald_health** - Check CEDA system status
32
+ - **herald_stats** - Get server statistics and pattern info
33
+ - **herald_predict** - Generate structure prediction from natural language
34
+ - **herald_observe** - Record prediction feedback for learning
35
+
36
+ ## Usage with Claude Desktop
37
+
38
+ Add to `claude_desktop_config.json`:
39
+
40
+ ```json
41
+ {
42
+ "mcpServers": {
43
+ "herald": {
44
+ "command": "npx",
45
+ "args": ["@spilno/herald-mcp"],
46
+ "env": {
47
+ "HERALD_API_URL": "https://getceda.com"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ## Usage with Devin
55
+
56
+ In Devin MCP marketplace:
57
+ - **Server Name**: Herald-CEDA
58
+ - **Transport**: STDIO
59
+ - **Command**: `npx`
60
+ - **Arguments**: `@spilno/herald-mcp`
61
+ - **Environment**: `HERALD_API_URL=https://getceda.com`
62
+
63
+ ## License
64
+
65
+ MIT
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Herald MCP - Diplomatic interface to CEDA ecosystem
4
+ *
5
+ * Herald speaks CEDA. Cognition stays sovereign.
6
+ */
7
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Herald MCP - Diplomatic interface to CEDA ecosystem
4
+ *
5
+ * Herald speaks CEDA. Cognition stays sovereign.
6
+ */
7
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
10
+ // Configuration - all sensitive values from environment only
11
+ const CEDA_API_URL = process.env.HERALD_API_URL;
12
+ const CEDA_API_TOKEN = process.env.HERALD_API_TOKEN; // Bearer token (optional for demo)
13
+ const CEDA_API_USER = process.env.HERALD_API_USER; // Basic auth user (optional)
14
+ const CEDA_API_PASS = process.env.HERALD_API_PASS; // Basic auth pass (optional)
15
+ const DEFAULT_CONTEXT_ID = process.env.HERALD_CONTEXT_ID || "ctx_default";
16
+ // Auth strategy: prefer Bearer token, fallback to Basic auth, allow none for demo
17
+ function getAuthHeader() {
18
+ if (CEDA_API_TOKEN) {
19
+ return `Bearer ${CEDA_API_TOKEN}`;
20
+ }
21
+ if (CEDA_API_USER && CEDA_API_PASS) {
22
+ const basicAuth = Buffer.from(`${CEDA_API_USER}:${CEDA_API_PASS}`).toString("base64");
23
+ return `Basic ${basicAuth}`;
24
+ }
25
+ return null; // No auth - acceptable for local demo
26
+ }
27
+ async function callCedaAPI(endpoint, method = "GET", body) {
28
+ // Validate configuration
29
+ if (!CEDA_API_URL) {
30
+ return {
31
+ success: false,
32
+ error: "HERALD_API_URL not configured. Set environment variable."
33
+ };
34
+ }
35
+ const url = `${CEDA_API_URL}${endpoint}`;
36
+ const headers = {
37
+ "Content-Type": "application/json",
38
+ };
39
+ // Add auth header if configured (optional for demo)
40
+ const authHeader = getAuthHeader();
41
+ if (authHeader) {
42
+ headers["Authorization"] = authHeader;
43
+ }
44
+ try {
45
+ const response = await fetch(url, {
46
+ method,
47
+ headers,
48
+ body: body ? JSON.stringify(body) : undefined,
49
+ });
50
+ if (!response.ok) {
51
+ return { success: false, error: `HTTP ${response.status}: ${response.statusText}` };
52
+ }
53
+ return await response.json();
54
+ }
55
+ catch (error) {
56
+ return { success: false, error: `Connection failed: ${error}` };
57
+ }
58
+ }
59
+ // Create MCP server
60
+ const server = new Server({
61
+ name: "herald",
62
+ version: "1.0.0",
63
+ }, {
64
+ capabilities: {
65
+ tools: {},
66
+ },
67
+ });
68
+ // Tool definitions - aligned with actual CEDA server endpoints
69
+ const tools = [
70
+ {
71
+ name: "herald_health",
72
+ description: "Check Herald and CEDA system status",
73
+ inputSchema: {
74
+ type: "object",
75
+ properties: {},
76
+ },
77
+ },
78
+ {
79
+ name: "herald_stats",
80
+ description: "Get CEDA server statistics and loaded patterns info",
81
+ inputSchema: {
82
+ type: "object",
83
+ properties: {},
84
+ },
85
+ },
86
+ {
87
+ name: "herald_predict",
88
+ description: "Generate non-deterministic structure prediction from signal",
89
+ inputSchema: {
90
+ type: "object",
91
+ properties: {
92
+ signal: {
93
+ type: "string",
94
+ description: "Natural language input (e.g., 'create safety assessment module')",
95
+ },
96
+ context_id: {
97
+ type: "string",
98
+ description: "Context identifier (user/company)",
99
+ },
100
+ context: {
101
+ type: "string",
102
+ description: "Additional context for better prediction",
103
+ },
104
+ session_id: {
105
+ type: "string",
106
+ description: "Optional session for continuity",
107
+ },
108
+ domain: {
109
+ type: "string",
110
+ description: "Optional domain filter (e.g., 'hse')",
111
+ },
112
+ },
113
+ required: ["signal"],
114
+ },
115
+ },
116
+ {
117
+ name: "herald_observe",
118
+ description: "Record prediction outcome for learning",
119
+ inputSchema: {
120
+ type: "object",
121
+ properties: {
122
+ session_id: {
123
+ type: "string",
124
+ description: "Session ID from prediction",
125
+ },
126
+ accepted: {
127
+ type: "boolean",
128
+ description: "Was prediction accepted by user?",
129
+ },
130
+ feedback: {
131
+ type: "string",
132
+ description: "Optional user feedback/comment",
133
+ },
134
+ },
135
+ required: ["session_id", "accepted"],
136
+ },
137
+ },
138
+ ];
139
+ // Handle list tools
140
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
141
+ tools,
142
+ }));
143
+ // Handle tool calls
144
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
145
+ const { name, arguments: args } = request.params;
146
+ switch (name) {
147
+ case "herald_health": {
148
+ // Maps to: GET /health
149
+ const result = await callCedaAPI("/health");
150
+ return {
151
+ content: [
152
+ {
153
+ type: "text",
154
+ text: JSON.stringify(result, null, 2),
155
+ },
156
+ ],
157
+ };
158
+ }
159
+ case "herald_stats": {
160
+ // Maps to: GET /api/stats
161
+ const result = await callCedaAPI("/api/stats");
162
+ return {
163
+ content: [
164
+ {
165
+ type: "text",
166
+ text: JSON.stringify(result, null, 2),
167
+ },
168
+ ],
169
+ };
170
+ }
171
+ case "herald_predict": {
172
+ // Maps to: POST /api/predict
173
+ const params = args;
174
+ // Build context array if additional context provided
175
+ const context = params.context ? [
176
+ {
177
+ type: "user_context",
178
+ value: params.context,
179
+ source: "herald_mcp",
180
+ }
181
+ ] : [];
182
+ const result = await callCedaAPI("/api/predict", "POST", {
183
+ input: params.signal, // CEDA uses 'input' not 'signal'
184
+ context,
185
+ config: {
186
+ enableAutoFix: true,
187
+ maxAutoFixAttempts: 3,
188
+ },
189
+ });
190
+ return {
191
+ content: [
192
+ {
193
+ type: "text",
194
+ text: JSON.stringify(result, null, 2),
195
+ },
196
+ ],
197
+ };
198
+ }
199
+ case "herald_observe": {
200
+ // Maps to: POST /api/feedback
201
+ const params = args;
202
+ const result = await callCedaAPI("/api/feedback", "POST", {
203
+ sessionId: params.session_id, // CEDA uses camelCase
204
+ accepted: params.accepted,
205
+ comment: params.feedback,
206
+ });
207
+ return {
208
+ content: [
209
+ {
210
+ type: "text",
211
+ text: JSON.stringify(result, null, 2),
212
+ },
213
+ ],
214
+ };
215
+ }
216
+ default:
217
+ throw new Error(`Unknown tool: ${name}`);
218
+ }
219
+ });
220
+ // Start server
221
+ async function main() {
222
+ const transport = new StdioServerTransport();
223
+ await server.connect(transport);
224
+ console.error("Herald MCP server running on stdio");
225
+ }
226
+ main().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@spilno/herald-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Herald MCP - Diplomatic interface to CEDA (Cognitive Event-Driven Architecture)",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": "./dist/index.js",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "start": "node dist/index.js",
11
+ "dev": "tsx src/index.ts",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "model-context-protocol",
17
+ "ceda",
18
+ "ai",
19
+ "copilot",
20
+ "herald"
21
+ ],
22
+ "author": "Spilno",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/Spilno-me/ceda.git",
27
+ "directory": "herald-mcp"
28
+ },
29
+ "homepage": "https://getceda.com",
30
+ "dependencies": {
31
+ "@modelcontextprotocol/sdk": "^0.5.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^20.0.0",
35
+ "tsx": "^4.0.0",
36
+ "typescript": "^5.0.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md"
44
+ ]
45
+ }