Skip to content

Commit fec7a4e

Browse files
Skiipy11claude
andcommitted
v1.0.2: Qdrant timeout, webhook warnings, npm metadata, docs polish
- Add configurable Qdrant request timeout (QDRANT_TIMEOUT_MS, default 10s) - Surface structured store failures as warnings in webhook response - Expand npm keywords and description for discoverability - Add brain_consolidate/brain_stats examples and troubleshooting to README - Add CI step to validate MCP server entrypoint - Add CHANGELOG.md shipped with npm package - Align version across package.json and MCP server registration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4630248 commit fec7a4e

7 files changed

Lines changed: 103 additions & 11 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ jobs:
2525

2626
- name: Run tests
2727
run: cd api && npm test
28+
29+
- name: Validate MCP server entrypoint
30+
run: cd mcp-server && timeout 5 node src/index.js 2>&1 || true
31+
env:
32+
BRAIN_API_KEY: test-key

api/src/routes/webhook.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ webhookRouter.post('/n8n', async (req, res) => {
7878
});
7979

8080
// Store as event in structured database
81+
const warnings = [];
8182
if (isStoreAvailable()) try {
8283
await createEvent({
8384
content,
@@ -91,6 +92,7 @@ webhookRouter.post('/n8n', async (req, res) => {
9192
});
9293
} catch (e) {
9394
console.error('[webhook:n8n] Store write failed:', e.message);
95+
warnings.push(`Structured store write failed: ${e.message}`);
9496
}
9597

9698
// If workflow errored, also update status
@@ -104,10 +106,13 @@ webhookRouter.post('/n8n', async (req, res) => {
104106
});
105107
} catch (e) {
106108
console.error('[webhook:n8n] Status update failed:', e.message);
109+
warnings.push(`Status update failed: ${e.message}`);
107110
}
108111
}
109112

110-
res.status(201).json({ id: pointId, content });
113+
const response = { id: pointId, content };
114+
if (warnings.length > 0) response.warnings = warnings;
115+
res.status(201).json(response);
111116
} catch (err) {
112117
console.error('[webhook:n8n] Error:', err.message);
113118
res.status(500).json({ error: err.message });

api/src/services/qdrant.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,29 @@ const COLLECTION = 'shared_memories';
88
const DECAY_FACTOR = parseFloat(process.env.DECAY_FACTOR) || 0.98;
99
const DECAY_TYPES = ['fact', 'status']; // events and decisions are historical — don't decay
1010

11+
const QDRANT_TIMEOUT_MS = parseInt(process.env.QDRANT_TIMEOUT_MS) || 10000;
12+
1113
async function qdrantRequest(path, options = {}) {
1214
const headers = { 'Content-Type': 'application/json' };
1315
if (QDRANT_API_KEY) headers['api-key'] = QDRANT_API_KEY;
1416

15-
const res = await fetch(`${QDRANT_URL}${path}`, { ...options, headers: { ...headers, ...options.headers } });
16-
if (!res.ok) {
17-
const body = await res.text();
18-
throw new Error(`Qdrant ${options.method || 'GET'} ${path} failed: ${res.status} ${body}`);
17+
const controller = new AbortController();
18+
const timeout = setTimeout(() => controller.abort(), QDRANT_TIMEOUT_MS);
19+
try {
20+
const res = await fetch(`${QDRANT_URL}${path}`, { ...options, headers: { ...headers, ...options.headers }, signal: controller.signal });
21+
if (!res.ok) {
22+
const body = await res.text();
23+
throw new Error(`Qdrant ${options.method || 'GET'} ${path} failed: ${res.status} ${body}`);
24+
}
25+
return res.json();
26+
} catch (err) {
27+
if (err.name === 'AbortError') {
28+
throw new Error(`Qdrant request timed out after ${QDRANT_TIMEOUT_MS}ms: ${options.method || 'GET'} ${path}`);
29+
}
30+
throw err;
31+
} finally {
32+
clearTimeout(timeout);
1933
}
20-
return res.json();
2134
}
2235

2336
export async function initQdrant() {

mcp-server/CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Changelog
2+
3+
## 1.0.2
4+
5+
- Expanded npm keywords for better discoverability
6+
- Improved package description
7+
- Added Qdrant request timeout (default 10s, configurable via `QDRANT_TIMEOUT_MS`)
8+
- Webhook now surfaces structured store warnings instead of silently swallowing errors
9+
- Added troubleshooting section to README
10+
- Added `brain_consolidate` and `brain_stats` usage examples to README
11+
- CI now validates MCP server entrypoint
12+
- Version alignment between package.json and MCP server registration
13+
14+
## 1.0.1
15+
16+
- Initial npm publish with README
17+
18+
## 1.0.0
19+
20+
- Initial release

mcp-server/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,43 @@ Stores a fact that any other agent (n8n, OpenClaw, Cursor) can retrieve later.
9696
| `status` | Update-in-place by `subject` | Current state of a system or workflow |
9797
| `decision` | Append-only | Choices made and why |
9898

99+
## More Usage Examples
100+
101+
Check memory health:
102+
103+
```
104+
brain_stats
105+
```
106+
107+
Returns total count, active vs superseded, consolidated, and breakdown by type.
108+
109+
Trigger memory consolidation:
110+
111+
```
112+
brain_consolidate action="run"
113+
```
114+
115+
An LLM analyzes unconsolidated memories — merging duplicates, flagging contradictions, discovering connections, and generating insights.
116+
117+
Check consolidation status:
118+
119+
```
120+
brain_consolidate action="status"
121+
```
122+
123+
Returns whether consolidation is running, when it last ran, and which LLM is configured.
124+
125+
## Troubleshooting
126+
127+
| Problem | Solution |
128+
|---------|----------|
129+
| `BRAIN_API_KEY environment variable is required` | Set `BRAIN_API_KEY` in your MCP config `env` block |
130+
| `API ... 401 Unauthorized` | API key doesn't match the one in your Memory API `.env` |
131+
| `API ... ECONNREFUSED` | Memory API isn't running — run `docker compose up -d` |
132+
| `fetch failed` / timeout | Check `BRAIN_API_URL` points to the correct host and port |
133+
| Tool calls return empty results | Verify Qdrant is running and has data — use `brain_stats` to check |
134+
| `Qdrant request timed out` | Qdrant is slow or unreachable — check connectivity, increase `QDRANT_TIMEOUT_MS` |
135+
99136
## Full Documentation
100137

101138
See the [main repository](https://github.com/ZenSystemAI/multi-agent-memory) for the complete API reference, adapter docs (Bash CLI, n8n, OpenClaw), deployment guide, and architecture overview.

mcp-server/package.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
11
{
22
"name": "@zensystemai/multi-agent-memory-mcp",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"type": "module",
5-
"description": "MCP server for Multi-Agent Memory - cross-agent persistent memory system",
5+
"description": "Persistent semantic memory across AI agents — credential scrubbing, auto-consolidation, multi-backend storage (Qdrant + SQLite/Postgres/Baserow)",
66
"main": "src/index.js",
77
"bin": {
88
"multi-agent-memory-mcp": "src/index.js"
99
},
1010
"files": [
11-
"src/"
11+
"src/",
12+
"CHANGELOG.md"
1213
],
1314
"scripts": {
1415
"start": "node src/index.js"
1516
},
1617
"keywords": [
1718
"mcp",
19+
"mcp-server",
1820
"memory",
1921
"ai",
2022
"agent",
2123
"multi-agent",
22-
"llm"
24+
"llm",
25+
"semantic-search",
26+
"persistent-memory",
27+
"cross-agent",
28+
"knowledge-base",
29+
"qdrant",
30+
"embeddings",
31+
"credential-scrubbing"
2332
],
33+
"publishConfig": {
34+
"access": "public"
35+
},
2436
"author": "ZenSystem",
2537
"license": "MIT",
2638
"repository": {

mcp-server/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ async function apiRequest(path, options = {}) {
3636
}
3737

3838
const server = new Server(
39-
{ name: 'shared-brain', version: '1.0.0' },
39+
{ name: 'shared-brain', version: '1.0.2' },
4040
{ capabilities: { tools: {} } }
4141
);
4242

0 commit comments

Comments
 (0)