@noopolis/mneme 0.1.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 +83 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +46 -0
- package/dist/contract/index.d.ts +3 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +2 -0
- package/dist/contract/toolDescriptors.d.ts +14 -0
- package/dist/contract/toolDescriptors.d.ts.map +1 -0
- package/dist/contract/toolDescriptors.js +98 -0
- package/dist/contract/types.d.ts +262 -0
- package/dist/contract/types.d.ts.map +1 -0
- package/dist/contract/types.js +1 -0
- package/dist/identity/ids.d.ts +9 -0
- package/dist/identity/ids.d.ts.map +1 -0
- package/dist/identity/ids.js +25 -0
- package/dist/identity/index.d.ts +3 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +2 -0
- package/dist/identity/scope.d.ts +24 -0
- package/dist/identity/scope.d.ts.map +1 -0
- package/dist/identity/scope.js +123 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/kernel/index.d.ts +3 -0
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +2 -0
- package/dist/kernel/kernel.d.ts +19 -0
- package/dist/kernel/kernel.d.ts.map +1 -0
- package/dist/kernel/kernel.js +318 -0
- package/dist/kernel/support.d.ts +66 -0
- package/dist/kernel/support.d.ts.map +1 -0
- package/dist/kernel/support.js +207 -0
- package/dist/mcp/config.d.ts +23 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +76 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/schemas.d.ts +150 -0
- package/dist/mcp/schemas.d.ts.map +1 -0
- package/dist/mcp/schemas.js +54 -0
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +45 -0
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +1 -0
- package/dist/policy/policy.d.ts +9 -0
- package/dist/policy/policy.d.ts.map +1 -0
- package/dist/policy/policy.js +123 -0
- package/dist/recall/index.d.ts +2 -0
- package/dist/recall/index.d.ts.map +1 -0
- package/dist/recall/index.js +1 -0
- package/dist/recall/recall.d.ts +28 -0
- package/dist/recall/recall.d.ts.map +1 -0
- package/dist/recall/recall.js +178 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/runtime.d.ts +19 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +129 -0
- package/dist/runtime/support.d.ts +52 -0
- package/dist/runtime/support.d.ts.map +1 -0
- package/dist/runtime/support.js +229 -0
- package/dist/store/index.d.ts +3 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +2 -0
- package/dist/store/sqliteIndex.d.ts +38 -0
- package/dist/store/sqliteIndex.d.ts.map +1 -0
- package/dist/store/sqliteIndex.js +270 -0
- package/dist/store/store.d.ts +27 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.js +114 -0
- package/package.json +53 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { canonicalScopeKey, memoryScopeId, sanitizePrincipalQualifier } from "../identity/ids.js";
|
|
2
|
+
const isString = (value) => typeof value === "string";
|
|
3
|
+
const hasText = (value) => isString(value) && value.trim().length > 0;
|
|
4
|
+
export const isPlainObject = (value) => typeof value === "object" && value !== null;
|
|
5
|
+
export const asNumber = (value) => {
|
|
6
|
+
if (typeof value !== "number" || Number.isNaN(value) || value <= 0) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
return Math.floor(value);
|
|
10
|
+
};
|
|
11
|
+
export const isVisibility = (value) => value === "private" || value === "pair" || value === "team" || value === "room" || value === "global" || value === "public" || value === "sealed";
|
|
12
|
+
export const isSensitivity = (value) => value === "normal" || value === "sensitive" || value === "secret";
|
|
13
|
+
export const isSearchArguments = (value) => hasText(value.scope) && hasText(value.query);
|
|
14
|
+
export const isLocateArguments = (value) => hasText(value.query);
|
|
15
|
+
export const isSummarizeArguments = (value) => hasText(value.scope);
|
|
16
|
+
const isTextContent = (value) => isPlainObject(value) && value.kind === "text" && hasText(value.text);
|
|
17
|
+
const isClaimContent = (value) => isPlainObject(value) &&
|
|
18
|
+
value.kind === "claim" &&
|
|
19
|
+
hasText(value.subject) &&
|
|
20
|
+
hasText(value.predicate) &&
|
|
21
|
+
hasText(value.object);
|
|
22
|
+
const isDecisionContent = (value) => isPlainObject(value) &&
|
|
23
|
+
value.kind === "decision" &&
|
|
24
|
+
hasText(value.decision);
|
|
25
|
+
const isArtifactContent = (value) => isPlainObject(value) &&
|
|
26
|
+
value.kind === "artifact" &&
|
|
27
|
+
hasText(value.description);
|
|
28
|
+
const isRelationshipContent = (value) => isPlainObject(value) &&
|
|
29
|
+
value.kind === "relationship" &&
|
|
30
|
+
hasText(value.from) &&
|
|
31
|
+
hasText(value.relation) &&
|
|
32
|
+
hasText(value.to);
|
|
33
|
+
export const isMemoryContent = (value) => {
|
|
34
|
+
if (!isPlainObject(value)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (value.kind === "text") {
|
|
38
|
+
return isTextContent(value);
|
|
39
|
+
}
|
|
40
|
+
if (value.kind === "claim") {
|
|
41
|
+
return isClaimContent(value);
|
|
42
|
+
}
|
|
43
|
+
if (value.kind === "decision") {
|
|
44
|
+
return isDecisionContent(value);
|
|
45
|
+
}
|
|
46
|
+
if (value.kind === "artifact") {
|
|
47
|
+
return isArtifactContent(value);
|
|
48
|
+
}
|
|
49
|
+
if (value.kind === "relationship") {
|
|
50
|
+
return isRelationshipContent(value);
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
};
|
|
54
|
+
export const isRegisterArguments = (value) => isPlainObject(value)
|
|
55
|
+
&& hasText(value.scope)
|
|
56
|
+
&& hasText(value.kind)
|
|
57
|
+
&& hasText(value.visibility)
|
|
58
|
+
&& hasText(value.sensitivity)
|
|
59
|
+
&& hasText(value.source_type)
|
|
60
|
+
&& isVisibility(value.visibility)
|
|
61
|
+
&& isSensitivity(value.sensitivity)
|
|
62
|
+
&& isPlainObject(value.content)
|
|
63
|
+
&& isMemoryContent(value.content)
|
|
64
|
+
&& Array.isArray(value.evidence_event_ids)
|
|
65
|
+
&& value.evidence_event_ids.length > 0
|
|
66
|
+
&& value.evidence_event_ids.every((id) => isString(id));
|
|
67
|
+
export const isForgetArguments = (value) => {
|
|
68
|
+
if (!isPlainObject(value)) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return hasText(value.scope)
|
|
72
|
+
&& Array.isArray(value.event_ids)
|
|
73
|
+
&& value.event_ids.length > 0
|
|
74
|
+
&& value.event_ids.every((id) => isString(id));
|
|
75
|
+
};
|
|
76
|
+
export const makeAudit = (call, sources, startAt) => ({
|
|
77
|
+
request_id: call.request_id,
|
|
78
|
+
requester: call.envelope.principal,
|
|
79
|
+
sources: sources.map((event) => event.principal),
|
|
80
|
+
transport: call.envelope.transport,
|
|
81
|
+
latency_ms: Date.now() - startAt,
|
|
82
|
+
argument_hash: canonicalScopeKey(JSON.stringify(call.arguments))
|
|
83
|
+
});
|
|
84
|
+
export const malformed = (call, tool, error, startAt) => ({
|
|
85
|
+
request_id: call.request_id,
|
|
86
|
+
tool,
|
|
87
|
+
decision: "malformed_request",
|
|
88
|
+
content: [],
|
|
89
|
+
audit: makeAudit(call, [], startAt),
|
|
90
|
+
error
|
|
91
|
+
});
|
|
92
|
+
export const unavailable = (call, tool, error, startAt) => ({
|
|
93
|
+
request_id: call.request_id,
|
|
94
|
+
tool,
|
|
95
|
+
decision: "unavailable",
|
|
96
|
+
content: [],
|
|
97
|
+
audit: makeAudit(call, [], startAt),
|
|
98
|
+
error
|
|
99
|
+
});
|
|
100
|
+
export const eventText = (event) => {
|
|
101
|
+
if (event.content.kind === "text") {
|
|
102
|
+
return event.content.text;
|
|
103
|
+
}
|
|
104
|
+
if (event.content.kind === "claim")
|
|
105
|
+
return `${event.content.subject} ${event.content.predicate} ${event.content.object}`;
|
|
106
|
+
if (event.content.kind === "decision")
|
|
107
|
+
return `${event.content.decision} ${event.content.rationale ?? ""}`.trim();
|
|
108
|
+
if (event.content.kind === "artifact")
|
|
109
|
+
return event.content.description;
|
|
110
|
+
return `${event.content.from} ${event.content.relation} ${event.content.to}`;
|
|
111
|
+
};
|
|
112
|
+
export const resultKind = (kind) => {
|
|
113
|
+
if (kind === "text")
|
|
114
|
+
return "memory";
|
|
115
|
+
if (kind === "decision")
|
|
116
|
+
return "claim";
|
|
117
|
+
return kind;
|
|
118
|
+
};
|
|
119
|
+
export const policyText = (decision, text) => {
|
|
120
|
+
if (decision === "allow_raw")
|
|
121
|
+
return text;
|
|
122
|
+
if (decision === "allow_summary" || decision === "allow_redacted_summary") {
|
|
123
|
+
return text.length > 150 ? `${text.slice(0, 147)}...` : text;
|
|
124
|
+
}
|
|
125
|
+
if (decision === "known_but_private") {
|
|
126
|
+
return "Related private context is available behind policy.";
|
|
127
|
+
}
|
|
128
|
+
if (decision === "locate_only") {
|
|
129
|
+
return "Locate candidates are known, but content is omitted.";
|
|
130
|
+
}
|
|
131
|
+
return "Memory was blocked by policy.";
|
|
132
|
+
};
|
|
133
|
+
export const decide = (decisions) => {
|
|
134
|
+
if (decisions.includes("allow_raw"))
|
|
135
|
+
return "allow_raw";
|
|
136
|
+
if (decisions.includes("allow_summary"))
|
|
137
|
+
return "allow_summary";
|
|
138
|
+
if (decisions.includes("allow_redacted_summary"))
|
|
139
|
+
return "allow_redacted_summary";
|
|
140
|
+
if (decisions.includes("locate_only"))
|
|
141
|
+
return "locate_only";
|
|
142
|
+
if (decisions.includes("known_but_private"))
|
|
143
|
+
return "known_but_private";
|
|
144
|
+
return "deny";
|
|
145
|
+
};
|
|
146
|
+
export const resolveScope = (scopeInput, requester) => {
|
|
147
|
+
const scope = canonicalScopeKey(scopeInput.trim().toLowerCase());
|
|
148
|
+
if (scope === "all") {
|
|
149
|
+
return "all";
|
|
150
|
+
}
|
|
151
|
+
if (scope === "current") {
|
|
152
|
+
return memoryScopeId(requester);
|
|
153
|
+
}
|
|
154
|
+
if (scope === "global") {
|
|
155
|
+
return memoryScopeId({ ...requester, scope: "global" });
|
|
156
|
+
}
|
|
157
|
+
return canonicalScopeKey(scopeInput);
|
|
158
|
+
};
|
|
159
|
+
export const sanitizePrincipal = (principal) => ({
|
|
160
|
+
...principal,
|
|
161
|
+
qualifier: principal.qualifier ? sanitizePrincipalQualifier(principal.qualifier) : undefined
|
|
162
|
+
});
|
|
163
|
+
export const collectTombstones = (events) => {
|
|
164
|
+
const redacted = new Set();
|
|
165
|
+
for (const event of events) {
|
|
166
|
+
if (event.type === "memory.forgotten") {
|
|
167
|
+
for (const id of event.parentEventIds) {
|
|
168
|
+
redacted.add(id);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return redacted;
|
|
173
|
+
};
|
|
174
|
+
export const isRecallableMemoryEvent = (event) => event.type !== "memory.located" &&
|
|
175
|
+
event.type !== "memory.denied" &&
|
|
176
|
+
event.type !== "memory.forgotten";
|
|
177
|
+
export const matchesQuery = (event, query) => {
|
|
178
|
+
const normalized = eventText(event).toLowerCase();
|
|
179
|
+
const tokens = query.toLowerCase()
|
|
180
|
+
.split(/\W+/u)
|
|
181
|
+
.map((value) => value.trim())
|
|
182
|
+
.filter((value) => value.length > 2);
|
|
183
|
+
if (tokens.length === 0) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
return tokens.some((token) => normalized.includes(token));
|
|
187
|
+
};
|
|
188
|
+
export const canExposeEventId = (decision) => decision === "allow_raw" || decision === "allow_summary" || decision === "allow_redacted_summary";
|
|
189
|
+
export const locateCandidateId = (event) => `${event.principal.agentId}|${event.principal.scope}|${event.principal.qualifier ?? ""}`;
|
|
190
|
+
export const hasInvalidV1Envelope = (version) => version !== "mneme.memory.tool.v1";
|
|
191
|
+
export const makeSearchResult = (decision, event) => ({
|
|
192
|
+
kind: resultKind(event.content.kind),
|
|
193
|
+
text: policyText(decision, eventText(event)),
|
|
194
|
+
event_ids: canExposeEventId(decision) ? [event.id] : [],
|
|
195
|
+
scope: event.scope,
|
|
196
|
+
principal: event.principal,
|
|
197
|
+
confidence: 1,
|
|
198
|
+
redactions: decision === "allow_redacted_summary" || decision === "known_but_private" ? ["redacted"] : []
|
|
199
|
+
});
|
|
200
|
+
export const makeLocateResult = (entry) => ({
|
|
201
|
+
kind: "locate",
|
|
202
|
+
event_ids: canExposeEventId(entry.decision) ? entry.eventIds : [],
|
|
203
|
+
scope: entry.scope,
|
|
204
|
+
principal: entry.event.principal,
|
|
205
|
+
confidence: Math.min(1, entry.score / 10),
|
|
206
|
+
redactions: ["content-omitted"]
|
|
207
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MemoryPrincipalRef, MemoryRuntime, MemoryToolExecutionContext } from "../contract/types.js";
|
|
2
|
+
export interface MnemeMcpServerConfig {
|
|
3
|
+
runtimeHomePath: string;
|
|
4
|
+
agentId: string;
|
|
5
|
+
agentScope?: MemoryPrincipalRef["scope"];
|
|
6
|
+
agentQualifier?: string;
|
|
7
|
+
conversationScope?: string;
|
|
8
|
+
audienceKey?: string;
|
|
9
|
+
policyVersion?: string;
|
|
10
|
+
source?: string;
|
|
11
|
+
tokenBudget?: number;
|
|
12
|
+
runtime?: MemoryRuntime;
|
|
13
|
+
}
|
|
14
|
+
export interface ResolvedMnemeMcpConfig extends Required<Pick<MnemeMcpServerConfig, "runtimeHomePath" | "agentId" | "conversationScope" | "audienceKey" | "policyVersion">> {
|
|
15
|
+
principal: MemoryPrincipalRef;
|
|
16
|
+
source?: string;
|
|
17
|
+
tokenBudget?: number;
|
|
18
|
+
runtime: MemoryRuntime;
|
|
19
|
+
}
|
|
20
|
+
export declare const resolveMnemeMcpConfig: (config: MnemeMcpServerConfig) => ResolvedMnemeMcpConfig;
|
|
21
|
+
export declare const createMcpToolContext: (config: ResolvedMnemeMcpConfig, toolName: string) => MemoryToolExecutionContext;
|
|
22
|
+
export declare const parseMnemeMcpArgs: (argv: string[], env?: NodeJS.ProcessEnv) => MnemeMcpServerConfig;
|
|
23
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,0BAA0B,EAC3B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,sBAAuB,SAAQ,QAAQ,CACtD,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,GAAG,SAAS,GAAG,mBAAmB,GAAG,aAAa,GAAG,eAAe,CAAC,CAClH;IACC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,oBAAoB,KAAG,sBAuBpE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,sBAAsB,EAC9B,UAAU,MAAM,KACf,0BAYF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EAAE,EACd,MAAK,MAAM,CAAC,UAAwB,KACnC,oBAwCF,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { memoryScopeId } from "../identity/ids.js";
|
|
2
|
+
import { createMemoryRuntime } from "../runtime/runtime.js";
|
|
3
|
+
export const resolveMnemeMcpConfig = (config) => {
|
|
4
|
+
const principal = {
|
|
5
|
+
agentId: config.agentId,
|
|
6
|
+
scope: config.agentScope ?? "global",
|
|
7
|
+
qualifier: config.agentQualifier
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
runtimeHomePath: config.runtimeHomePath,
|
|
11
|
+
agentId: config.agentId,
|
|
12
|
+
principal,
|
|
13
|
+
conversationScope: config.conversationScope ?? memoryScopeId(principal),
|
|
14
|
+
audienceKey: config.audienceKey ?? config.agentId,
|
|
15
|
+
policyVersion: config.policyVersion ?? "memory-policy.v1",
|
|
16
|
+
source: config.source,
|
|
17
|
+
tokenBudget: config.tokenBudget,
|
|
18
|
+
runtime: config.runtime ?? createMemoryRuntime({
|
|
19
|
+
agentId: config.agentId,
|
|
20
|
+
runtimeHomePath: config.runtimeHomePath,
|
|
21
|
+
source: config.source,
|
|
22
|
+
tokenBudget: config.tokenBudget
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export const createMcpToolContext = (config, toolName) => {
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
return {
|
|
29
|
+
wakeId: `mcp-${now}`,
|
|
30
|
+
threadId: `mcp:${config.audienceKey}`,
|
|
31
|
+
principal: config.principal,
|
|
32
|
+
conversationScope: config.conversationScope,
|
|
33
|
+
audienceKey: config.audienceKey,
|
|
34
|
+
policyVersion: config.policyVersion,
|
|
35
|
+
transport: "mcp",
|
|
36
|
+
nonce: `mcp:${toolName}:${now}`
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export const parseMnemeMcpArgs = (argv, env = process.env) => {
|
|
40
|
+
const values = new Map();
|
|
41
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
42
|
+
const current = argv[index];
|
|
43
|
+
if (!current.startsWith("--")) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const key = current.slice(2);
|
|
47
|
+
const next = argv[index + 1];
|
|
48
|
+
if (!next || next.startsWith("--")) {
|
|
49
|
+
values.set(key, "true");
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
values.set(key, next);
|
|
53
|
+
index += 1;
|
|
54
|
+
}
|
|
55
|
+
const runtimeHomePath = values.get("runtime-home") ?? env.MNEME_RUNTIME_HOME;
|
|
56
|
+
const agentId = values.get("agent-id") ?? env.MNEME_AGENT_ID;
|
|
57
|
+
if (!runtimeHomePath) {
|
|
58
|
+
throw new Error("mneme mcp requires --runtime-home or MNEME_RUNTIME_HOME");
|
|
59
|
+
}
|
|
60
|
+
if (!agentId) {
|
|
61
|
+
throw new Error("mneme mcp requires --agent-id or MNEME_AGENT_ID");
|
|
62
|
+
}
|
|
63
|
+
const tokenBudgetText = values.get("token-budget") ?? env.MNEME_TOKEN_BUDGET;
|
|
64
|
+
const tokenBudget = tokenBudgetText ? Number.parseInt(tokenBudgetText, 10) : undefined;
|
|
65
|
+
return {
|
|
66
|
+
runtimeHomePath,
|
|
67
|
+
agentId,
|
|
68
|
+
agentScope: (values.get("agent-scope") ?? env.MNEME_AGENT_SCOPE),
|
|
69
|
+
agentQualifier: values.get("agent-qualifier") ?? env.MNEME_AGENT_QUALIFIER,
|
|
70
|
+
conversationScope: values.get("conversation-scope") ?? env.MNEME_CONVERSATION_SCOPE,
|
|
71
|
+
audienceKey: values.get("audience-key") ?? env.MNEME_AUDIENCE_KEY,
|
|
72
|
+
policyVersion: values.get("policy-version") ?? env.MNEME_POLICY_VERSION,
|
|
73
|
+
source: values.get("source") ?? env.MNEME_SOURCE,
|
|
74
|
+
tokenBudget: Number.isFinite(tokenBudget) ? tokenBudget : undefined
|
|
75
|
+
};
|
|
76
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
export declare const searchInputSchema: {
|
|
3
|
+
scope: z.ZodString;
|
|
4
|
+
query: z.ZodString;
|
|
5
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
6
|
+
};
|
|
7
|
+
export declare const locateInputSchema: {
|
|
8
|
+
query: z.ZodString;
|
|
9
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
active_scope: z.ZodOptional<z.ZodString>;
|
|
11
|
+
};
|
|
12
|
+
export declare const registerInputSchema: {
|
|
13
|
+
scope: z.ZodString;
|
|
14
|
+
kind: z.ZodString;
|
|
15
|
+
content: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
16
|
+
kind: z.ZodLiteral<"text">;
|
|
17
|
+
text: z.ZodString;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
kind: z.ZodLiteral<"claim">;
|
|
20
|
+
subject: z.ZodString;
|
|
21
|
+
predicate: z.ZodString;
|
|
22
|
+
object: z.ZodString;
|
|
23
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
24
|
+
kind: z.ZodLiteral<"decision">;
|
|
25
|
+
decision: z.ZodString;
|
|
26
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
28
|
+
kind: z.ZodLiteral<"artifact">;
|
|
29
|
+
path: z.ZodOptional<z.ZodString>;
|
|
30
|
+
uri: z.ZodOptional<z.ZodString>;
|
|
31
|
+
description: z.ZodString;
|
|
32
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
33
|
+
kind: z.ZodLiteral<"relationship">;
|
|
34
|
+
from: z.ZodString;
|
|
35
|
+
relation: z.ZodString;
|
|
36
|
+
to: z.ZodString;
|
|
37
|
+
}, z.core.$strip>], "kind">;
|
|
38
|
+
visibility: z.ZodEnum<{
|
|
39
|
+
global: "global";
|
|
40
|
+
team: "team";
|
|
41
|
+
room: "room";
|
|
42
|
+
pair: "pair";
|
|
43
|
+
private: "private";
|
|
44
|
+
public: "public";
|
|
45
|
+
sealed: "sealed";
|
|
46
|
+
}>;
|
|
47
|
+
sensitivity: z.ZodEnum<{
|
|
48
|
+
normal: "normal";
|
|
49
|
+
sensitive: "sensitive";
|
|
50
|
+
secret: "secret";
|
|
51
|
+
}>;
|
|
52
|
+
evidence_event_ids: z.ZodArray<z.ZodString>;
|
|
53
|
+
source_type: z.ZodString;
|
|
54
|
+
confidence: z.ZodOptional<z.ZodNumber>;
|
|
55
|
+
principal: z.ZodOptional<z.ZodObject<{
|
|
56
|
+
agentId: z.ZodString;
|
|
57
|
+
scope: z.ZodEnum<{
|
|
58
|
+
global: "global";
|
|
59
|
+
team: "team";
|
|
60
|
+
room: "room";
|
|
61
|
+
pair: "pair";
|
|
62
|
+
task: "task";
|
|
63
|
+
role: "role";
|
|
64
|
+
artifact: "artifact";
|
|
65
|
+
}>;
|
|
66
|
+
qualifier: z.ZodOptional<z.ZodString>;
|
|
67
|
+
}, z.core.$strip>>;
|
|
68
|
+
};
|
|
69
|
+
export declare const summarizeInputSchema: {
|
|
70
|
+
scope: z.ZodString;
|
|
71
|
+
horizon: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
};
|
|
73
|
+
export declare const forgetInputSchema: {
|
|
74
|
+
scope: z.ZodString;
|
|
75
|
+
event_ids: z.ZodArray<z.ZodString>;
|
|
76
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
77
|
+
};
|
|
78
|
+
export declare const schemaForModelToolName: (name: string) => {
|
|
79
|
+
scope: z.ZodString;
|
|
80
|
+
query: z.ZodString;
|
|
81
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
82
|
+
} | {
|
|
83
|
+
query: z.ZodString;
|
|
84
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
85
|
+
active_scope: z.ZodOptional<z.ZodString>;
|
|
86
|
+
} | {
|
|
87
|
+
scope: z.ZodString;
|
|
88
|
+
kind: z.ZodString;
|
|
89
|
+
content: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
90
|
+
kind: z.ZodLiteral<"text">;
|
|
91
|
+
text: z.ZodString;
|
|
92
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
93
|
+
kind: z.ZodLiteral<"claim">;
|
|
94
|
+
subject: z.ZodString;
|
|
95
|
+
predicate: z.ZodString;
|
|
96
|
+
object: z.ZodString;
|
|
97
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
98
|
+
kind: z.ZodLiteral<"decision">;
|
|
99
|
+
decision: z.ZodString;
|
|
100
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
101
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
102
|
+
kind: z.ZodLiteral<"artifact">;
|
|
103
|
+
path: z.ZodOptional<z.ZodString>;
|
|
104
|
+
uri: z.ZodOptional<z.ZodString>;
|
|
105
|
+
description: z.ZodString;
|
|
106
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
107
|
+
kind: z.ZodLiteral<"relationship">;
|
|
108
|
+
from: z.ZodString;
|
|
109
|
+
relation: z.ZodString;
|
|
110
|
+
to: z.ZodString;
|
|
111
|
+
}, z.core.$strip>], "kind">;
|
|
112
|
+
visibility: z.ZodEnum<{
|
|
113
|
+
global: "global";
|
|
114
|
+
team: "team";
|
|
115
|
+
room: "room";
|
|
116
|
+
pair: "pair";
|
|
117
|
+
private: "private";
|
|
118
|
+
public: "public";
|
|
119
|
+
sealed: "sealed";
|
|
120
|
+
}>;
|
|
121
|
+
sensitivity: z.ZodEnum<{
|
|
122
|
+
normal: "normal";
|
|
123
|
+
sensitive: "sensitive";
|
|
124
|
+
secret: "secret";
|
|
125
|
+
}>;
|
|
126
|
+
evidence_event_ids: z.ZodArray<z.ZodString>;
|
|
127
|
+
source_type: z.ZodString;
|
|
128
|
+
confidence: z.ZodOptional<z.ZodNumber>;
|
|
129
|
+
principal: z.ZodOptional<z.ZodObject<{
|
|
130
|
+
agentId: z.ZodString;
|
|
131
|
+
scope: z.ZodEnum<{
|
|
132
|
+
global: "global";
|
|
133
|
+
team: "team";
|
|
134
|
+
room: "room";
|
|
135
|
+
pair: "pair";
|
|
136
|
+
task: "task";
|
|
137
|
+
role: "role";
|
|
138
|
+
artifact: "artifact";
|
|
139
|
+
}>;
|
|
140
|
+
qualifier: z.ZodOptional<z.ZodString>;
|
|
141
|
+
}, z.core.$strip>>;
|
|
142
|
+
} | {
|
|
143
|
+
scope: z.ZodString;
|
|
144
|
+
horizon: z.ZodOptional<z.ZodNumber>;
|
|
145
|
+
} | {
|
|
146
|
+
scope: z.ZodString;
|
|
147
|
+
event_ids: z.ZodArray<z.ZodString>;
|
|
148
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/mcp/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAC;AAgBF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAU/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMlD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
export const searchInputSchema = {
|
|
3
|
+
scope: z.string().describe("Scope alias or canonical scope id. Use current, global, or all when appropriate."),
|
|
4
|
+
query: z.string().describe("Search query."),
|
|
5
|
+
limit: z.number().optional().describe("Maximum result count.")
|
|
6
|
+
};
|
|
7
|
+
export const locateInputSchema = {
|
|
8
|
+
query: z.string().describe("What to locate in memory."),
|
|
9
|
+
limit: z.number().optional().describe("Maximum candidate count."),
|
|
10
|
+
active_scope: z.string().optional().describe("Optional active scope hint.")
|
|
11
|
+
};
|
|
12
|
+
const memoryContentSchema = z.discriminatedUnion("kind", [
|
|
13
|
+
z.object({ kind: z.literal("text"), text: z.string() }),
|
|
14
|
+
z.object({ kind: z.literal("claim"), subject: z.string(), predicate: z.string(), object: z.string() }),
|
|
15
|
+
z.object({ kind: z.literal("decision"), decision: z.string(), rationale: z.string().optional() }),
|
|
16
|
+
z.object({ kind: z.literal("artifact"), path: z.string().optional(), uri: z.string().optional(), description: z.string() }),
|
|
17
|
+
z.object({ kind: z.literal("relationship"), from: z.string(), relation: z.string(), to: z.string() })
|
|
18
|
+
]);
|
|
19
|
+
const principalSchema = z.object({
|
|
20
|
+
agentId: z.string(),
|
|
21
|
+
scope: z.enum(["global", "team", "room", "pair", "task", "role", "artifact"]),
|
|
22
|
+
qualifier: z.string().optional()
|
|
23
|
+
});
|
|
24
|
+
export const registerInputSchema = {
|
|
25
|
+
scope: z.string().describe("Scope alias or canonical scope id where the memory belongs."),
|
|
26
|
+
kind: z.string().describe("Memory content kind."),
|
|
27
|
+
content: memoryContentSchema.describe("Structured memory content."),
|
|
28
|
+
visibility: z.enum(["private", "pair", "team", "room", "global", "public", "sealed"]),
|
|
29
|
+
sensitivity: z.enum(["normal", "sensitive", "secret"]),
|
|
30
|
+
evidence_event_ids: z.array(z.string()).min(1).describe("Event ids that justify the memory."),
|
|
31
|
+
source_type: z.string().describe("Source label for the registered memory."),
|
|
32
|
+
confidence: z.number().optional().describe("Confidence from 0 to 1."),
|
|
33
|
+
principal: principalSchema.optional().describe("Optional principal override for the stored memory.")
|
|
34
|
+
};
|
|
35
|
+
export const summarizeInputSchema = {
|
|
36
|
+
scope: z.string().describe("Scope alias or canonical scope id to summarize."),
|
|
37
|
+
horizon: z.number().optional().describe("Approximate number of recent memories to include.")
|
|
38
|
+
};
|
|
39
|
+
export const forgetInputSchema = {
|
|
40
|
+
scope: z.string().describe("Scope alias or canonical scope id for the tombstone."),
|
|
41
|
+
event_ids: z.array(z.string()).min(1).describe("Memory event ids to tombstone."),
|
|
42
|
+
reason: z.string().optional().describe("Why these memories should be forgotten.")
|
|
43
|
+
};
|
|
44
|
+
export const schemaForModelToolName = (name) => {
|
|
45
|
+
if (name === "memory_search")
|
|
46
|
+
return searchInputSchema;
|
|
47
|
+
if (name === "memory_locate")
|
|
48
|
+
return locateInputSchema;
|
|
49
|
+
if (name === "memory_register")
|
|
50
|
+
return registerInputSchema;
|
|
51
|
+
if (name === "memory_summarize")
|
|
52
|
+
return summarizeInputSchema;
|
|
53
|
+
return forgetInputSchema;
|
|
54
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type MnemeMcpServerConfig } from "./config.js";
|
|
3
|
+
export declare const createMnemeMcpServer: (config: MnemeMcpServerConfig) => McpServer;
|
|
4
|
+
export declare const connectMnemeMcpStdio: (config: MnemeMcpServerConfig) => Promise<McpServer>;
|
|
5
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAqBrB,eAAO,MAAM,oBAAoB,GAAI,QAAQ,oBAAoB,KAAG,SA2BnE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,QAAQ,oBAAoB,KAAG,OAAO,CAAC,SAAS,CAI1F,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createMemoryToolDescriptors } from "../contract/toolDescriptors.js";
|
|
4
|
+
import { createMcpToolContext, resolveMnemeMcpConfig } from "./config.js";
|
|
5
|
+
import { schemaForModelToolName } from "./schemas.js";
|
|
6
|
+
const annotationsFor = (name) => {
|
|
7
|
+
if (name === "memory_search" || name === "memory_locate") {
|
|
8
|
+
return { readOnlyHint: true, openWorldHint: false };
|
|
9
|
+
}
|
|
10
|
+
if (name === "memory_forget") {
|
|
11
|
+
return { destructiveHint: true, openWorldHint: false };
|
|
12
|
+
}
|
|
13
|
+
return { openWorldHint: false };
|
|
14
|
+
};
|
|
15
|
+
const toolResult = (result) => ({
|
|
16
|
+
content: [{
|
|
17
|
+
type: "text",
|
|
18
|
+
text: JSON.stringify(result, null, 2)
|
|
19
|
+
}],
|
|
20
|
+
structuredContent: result
|
|
21
|
+
});
|
|
22
|
+
export const createMnemeMcpServer = (config) => {
|
|
23
|
+
const resolved = resolveMnemeMcpConfig(config);
|
|
24
|
+
const server = new McpServer({
|
|
25
|
+
name: "mneme",
|
|
26
|
+
version: "0.1.0"
|
|
27
|
+
});
|
|
28
|
+
for (const descriptor of createMemoryToolDescriptors(resolved.runtime.kernel)) {
|
|
29
|
+
server.registerTool(descriptor.modelName, {
|
|
30
|
+
title: descriptor.label,
|
|
31
|
+
description: descriptor.description,
|
|
32
|
+
inputSchema: schemaForModelToolName(descriptor.modelName),
|
|
33
|
+
annotations: annotationsFor(descriptor.modelName)
|
|
34
|
+
}, async (args) => {
|
|
35
|
+
const result = await descriptor.invoke(args, createMcpToolContext(resolved, descriptor.modelName));
|
|
36
|
+
return toolResult(result);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return server;
|
|
40
|
+
};
|
|
41
|
+
export const connectMnemeMcpStdio = async (config) => {
|
|
42
|
+
const server = createMnemeMcpServer(config);
|
|
43
|
+
await server.connect(new StdioServerTransport());
|
|
44
|
+
return server;
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./policy.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MemoryDecision, MemoryPolicyInput, MemoryPrincipalRef } from "../contract/types.js";
|
|
2
|
+
export declare const memoryPolicy: ({ request, candidate }: MemoryPolicyInput) => {
|
|
3
|
+
decision: MemoryDecision;
|
|
4
|
+
reason: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const memoryPriority: (request: MemoryPrincipalRef, candidate: MemoryPrincipalRef) => number;
|
|
7
|
+
export declare const shouldRecordDecisionEvent: (decision: MemoryDecision) => boolean;
|
|
8
|
+
export declare const principalKey: (principal: MemoryPrincipalRef) => string;
|
|
9
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/policy/policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAGjB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAuD9B,eAAO,MAAM,YAAY,GAAI,wBAAwB,iBAAiB,KAAG;IACvE,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAgGhB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,kBAAkB,EAAE,WAAW,kBAAkB,KAAG,MACzD,CAAC;AAEpC,eAAO,MAAM,yBAAyB,GAAI,UAAU,cAAc,KAAG,OACX,CAAC;AAE3D,eAAO,MAAM,YAAY,2CAAwB,CAAC"}
|