@memoraone/mcp 0.1.37 → 0.1.39
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/dist/cli.cjs +2311 -515
- package/dist/daemon.cjs +526 -89
- package/dist/index.cjs +525 -88
- package/package.json +11 -11
package/dist/index.cjs
CHANGED
|
@@ -78,7 +78,7 @@ var EnvSchema = import_v4.z.object({
|
|
|
78
78
|
MEMORAONE_AGENT_NAME: import_v4.z.string().min(1).optional(),
|
|
79
79
|
MEMORAONE_AGENT_TYPE: import_v4.z.string().min(1).optional(),
|
|
80
80
|
MEMORAONE_SOURCE: import_v4.z.string().min(1).optional(),
|
|
81
|
-
MEMORAONE_IDE_TYPE: import_v4.z.enum(["cursor", "copilot-vscode", "jetbrains"]).optional(),
|
|
81
|
+
MEMORAONE_IDE_TYPE: import_v4.z.enum(["cursor", "copilot-vscode", "jetbrains", "claude-code", "windsurf", "opencode", "codex"]).optional(),
|
|
82
82
|
MEMORAONE_WORKLOG: import_v4.z.string().min(1).optional(),
|
|
83
83
|
MEMORAONE_HEARTBEAT: import_v4.z.string().min(1).optional(),
|
|
84
84
|
MEMORAONE_HEARTBEAT_INTERVAL_MS: import_v4.z.string().min(1).optional()
|
|
@@ -127,7 +127,9 @@ var config2 = {
|
|
|
127
127
|
devMode: parseBooleanFlag(parsed.data.MEMORAONE_DEV_MODE, false),
|
|
128
128
|
worklogEnabled: parseBooleanFlag(parsed.data.MEMORAONE_WORKLOG, true),
|
|
129
129
|
heartbeatEnabled: parseBooleanFlag(parsed.data.MEMORAONE_HEARTBEAT, true),
|
|
130
|
-
|
|
130
|
+
// Cadence is owned by LOCAL_MCP_HEARTBEAT_INTERVAL_MS in heartbeat.ts (1_000).
|
|
131
|
+
// Env override is accepted for forward-compat but the timer path ignores it.
|
|
132
|
+
heartbeatIntervalMs: Number.parseInt(parsed.data.MEMORAONE_HEARTBEAT_INTERVAL_MS ?? "1000", 10)
|
|
131
133
|
};
|
|
132
134
|
|
|
133
135
|
// src/client/memoraClient.ts
|
|
@@ -1431,7 +1433,15 @@ var HASH_SOCKET_FILENAME_RE = new RegExp(
|
|
|
1431
1433
|
`^mcp-[0-9a-f]{${BINDING_SOCKET_HASH_LENGTH}}\\.sock$`,
|
|
1432
1434
|
"i"
|
|
1433
1435
|
);
|
|
1434
|
-
var IDE_TYPES = [
|
|
1436
|
+
var IDE_TYPES = [
|
|
1437
|
+
"cursor",
|
|
1438
|
+
"copilot-vscode",
|
|
1439
|
+
"jetbrains",
|
|
1440
|
+
"claude-code",
|
|
1441
|
+
"windsurf",
|
|
1442
|
+
"opencode",
|
|
1443
|
+
"codex"
|
|
1444
|
+
];
|
|
1435
1445
|
var IDE_TYPE_SET = new Set(IDE_TYPES);
|
|
1436
1446
|
function parseIdeType(value) {
|
|
1437
1447
|
if (value === void 0 || value.trim() === "" || !IDE_TYPE_SET.has(value)) {
|
|
@@ -1442,16 +1452,19 @@ function parseIdeType(value) {
|
|
|
1442
1452
|
function resolveIdeTypeFromEnv(env2 = process.env) {
|
|
1443
1453
|
return parseIdeType(env2.MEMORAONE_IDE_TYPE);
|
|
1444
1454
|
}
|
|
1445
|
-
function resolveBindingIdeType(env2 = process.env) {
|
|
1455
|
+
function resolveBindingIdeType(env2 = process.env, ideTypeOverride) {
|
|
1456
|
+
if (ideTypeOverride !== void 0) {
|
|
1457
|
+
return ideTypeOverride;
|
|
1458
|
+
}
|
|
1446
1459
|
return resolveIdeTypeFromEnv(env2) ?? "";
|
|
1447
1460
|
}
|
|
1448
|
-
function getBindingSocketFilename(binding, env2 = process.env) {
|
|
1449
|
-
const ideType = resolveBindingIdeType(env2);
|
|
1461
|
+
function getBindingSocketFilename(binding, env2 = process.env, ideTypeOverride) {
|
|
1462
|
+
const ideType = resolveBindingIdeType(env2, ideTypeOverride);
|
|
1450
1463
|
const hash = hashBindingIdentity(binding.repositoryBindingId, binding.workspaceRoot, ideType);
|
|
1451
1464
|
return `mcp-${hash}.sock`;
|
|
1452
1465
|
}
|
|
1453
|
-
function getBindingSocketPath(binding, env2 = process.env) {
|
|
1454
|
-
return path10.join(BASE_DIR, getBindingSocketFilename(binding, env2));
|
|
1466
|
+
function getBindingSocketPath(binding, env2 = process.env, ideTypeOverride) {
|
|
1467
|
+
return path10.join(BASE_DIR, getBindingSocketFilename(binding, env2, ideTypeOverride));
|
|
1455
1468
|
}
|
|
1456
1469
|
|
|
1457
1470
|
// src/initializeBinding.ts
|
|
@@ -1770,8 +1783,79 @@ var logCommandShape = {
|
|
|
1770
1783
|
// src/tools/bindingStatus.ts
|
|
1771
1784
|
var bindingStatusShape = {};
|
|
1772
1785
|
|
|
1773
|
-
// src/tools/
|
|
1786
|
+
// src/tools/listTimeline.ts
|
|
1774
1787
|
var import_v411 = require("zod/v4");
|
|
1788
|
+
var listTimelineDescription = "List timeline events for the project bound to this Local MCP installation.";
|
|
1789
|
+
var listTimelineInputSchema = import_v411.z.object({
|
|
1790
|
+
since: import_v411.z.string().optional(),
|
|
1791
|
+
concept: import_v411.z.string().optional(),
|
|
1792
|
+
kind: import_v411.z.union([import_v411.z.string(), import_v411.z.array(import_v411.z.string())]).optional(),
|
|
1793
|
+
sort: import_v411.z.enum(["newest", "oldest"]).optional(),
|
|
1794
|
+
limit: import_v411.z.number().int().min(1).max(200).optional(),
|
|
1795
|
+
cursor: import_v411.z.string().optional()
|
|
1796
|
+
}).strict();
|
|
1797
|
+
|
|
1798
|
+
// src/tools/listConcepts.ts
|
|
1799
|
+
var import_v412 = require("zod/v4");
|
|
1800
|
+
var listConceptsDescription = "List concepts for the project bound to this Local MCP installation.";
|
|
1801
|
+
var listConceptsInputSchema = import_v412.z.object({
|
|
1802
|
+
q: import_v412.z.string().min(1).optional(),
|
|
1803
|
+
tag: import_v412.z.string().min(1).optional(),
|
|
1804
|
+
parent_id: import_v412.z.string().min(1).optional(),
|
|
1805
|
+
limit: import_v412.z.number().int().min(1).max(200).optional(),
|
|
1806
|
+
cursor: import_v412.z.string().min(1).optional()
|
|
1807
|
+
}).strict();
|
|
1808
|
+
|
|
1809
|
+
// src/tools/getConcept.ts
|
|
1810
|
+
var import_v413 = require("zod/v4");
|
|
1811
|
+
var getConceptDescription = "Get one concept by ID from the project bound to this Local MCP installation.";
|
|
1812
|
+
var getConceptInputSchema = import_v413.z.object({
|
|
1813
|
+
id: import_v413.z.string().trim().min(1)
|
|
1814
|
+
}).strict();
|
|
1815
|
+
|
|
1816
|
+
// src/tools/createConceptVersion.ts
|
|
1817
|
+
var import_v414 = require("zod/v4");
|
|
1818
|
+
var createConceptVersionDescription = "Create a version of a concept in the project bound to this Local MCP installation.";
|
|
1819
|
+
var createConceptVersionInputSchema = import_v414.z.object({
|
|
1820
|
+
id: import_v414.z.string().trim().min(1),
|
|
1821
|
+
value: import_v414.z.unknown(),
|
|
1822
|
+
reason: import_v414.z.string().optional(),
|
|
1823
|
+
confidence: import_v414.z.number().finite().min(0).max(1).optional(),
|
|
1824
|
+
source_ref: import_v414.z.string().optional(),
|
|
1825
|
+
tags: import_v414.z.array(import_v414.z.string()).optional(),
|
|
1826
|
+
parent_id: import_v414.z.union([import_v414.z.string(), import_v414.z.null()]).optional()
|
|
1827
|
+
}).strict();
|
|
1828
|
+
function isJsonValue(value) {
|
|
1829
|
+
if (value === null) return true;
|
|
1830
|
+
if (typeof value === "boolean" || typeof value === "string") return true;
|
|
1831
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
1832
|
+
if (Array.isArray(value)) return value.every(isJsonValue);
|
|
1833
|
+
if (typeof value !== "object") return false;
|
|
1834
|
+
const prototype = Object.getPrototypeOf(value);
|
|
1835
|
+
if (prototype !== Object.prototype && prototype !== null) return false;
|
|
1836
|
+
return Object.values(value).every(isJsonValue);
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
// src/tools/toolInventory.ts
|
|
1840
|
+
var LOCAL_MCP_TOOL_NAMES = [
|
|
1841
|
+
"memora_ask_with_memory",
|
|
1842
|
+
"memora_post_event",
|
|
1843
|
+
"memora_create_fact",
|
|
1844
|
+
"memora_add_personal_context",
|
|
1845
|
+
"memora_get_personal_context",
|
|
1846
|
+
"memora_log_intent",
|
|
1847
|
+
"memora_log_change_summary",
|
|
1848
|
+
"memora_log_tool_result",
|
|
1849
|
+
"memora_log_command",
|
|
1850
|
+
"memora_status",
|
|
1851
|
+
"memora_list_timeline",
|
|
1852
|
+
"memora_list_concepts",
|
|
1853
|
+
"memora_get_concept",
|
|
1854
|
+
"memora_create_concept_version"
|
|
1855
|
+
];
|
|
1856
|
+
|
|
1857
|
+
// src/tools/handlers/postEvent.ts
|
|
1858
|
+
var import_v415 = require("zod/v4");
|
|
1775
1859
|
var crypto4 = __toESM(require("crypto"), 1);
|
|
1776
1860
|
|
|
1777
1861
|
// src/runContext.ts
|
|
@@ -1827,14 +1911,14 @@ function generateRunId() {
|
|
|
1827
1911
|
}
|
|
1828
1912
|
|
|
1829
1913
|
// src/tools/handlers/postEvent.ts
|
|
1830
|
-
var postEventInputSchema =
|
|
1831
|
-
kind:
|
|
1832
|
-
actor:
|
|
1833
|
-
identifier:
|
|
1834
|
-
id:
|
|
1914
|
+
var postEventInputSchema = import_v415.z.object({
|
|
1915
|
+
kind: import_v415.z.string().min(1),
|
|
1916
|
+
actor: import_v415.z.object({
|
|
1917
|
+
identifier: import_v415.z.string().min(1),
|
|
1918
|
+
id: import_v415.z.string().min(1).optional()
|
|
1835
1919
|
}),
|
|
1836
|
-
content:
|
|
1837
|
-
metadata:
|
|
1920
|
+
content: import_v415.z.record(import_v415.z.string(), import_v415.z.any()),
|
|
1921
|
+
metadata: import_v415.z.record(import_v415.z.string(), import_v415.z.any()).optional()
|
|
1838
1922
|
});
|
|
1839
1923
|
function buildPostEventContentFields(content) {
|
|
1840
1924
|
if (typeof content.message === "string") {
|
|
@@ -1906,10 +1990,10 @@ async function handlePostEvent(client, args) {
|
|
|
1906
1990
|
}
|
|
1907
1991
|
|
|
1908
1992
|
// src/tools/handlers/createFact.ts
|
|
1909
|
-
var
|
|
1910
|
-
var createFactInputSchema =
|
|
1911
|
-
content:
|
|
1912
|
-
metadata:
|
|
1993
|
+
var import_v416 = require("zod/v4");
|
|
1994
|
+
var createFactInputSchema = import_v416.z.object({
|
|
1995
|
+
content: import_v416.z.string().min(1),
|
|
1996
|
+
metadata: import_v416.z.record(import_v416.z.string(), import_v416.z.any()).optional()
|
|
1913
1997
|
});
|
|
1914
1998
|
async function handleCreateFact(client, args) {
|
|
1915
1999
|
const parsed2 = createFactInputSchema.parse(args ?? {});
|
|
@@ -1954,13 +2038,13 @@ async function handleCreateFact(client, args) {
|
|
|
1954
2038
|
}
|
|
1955
2039
|
|
|
1956
2040
|
// src/tools/handlers/addPersonalContext.ts
|
|
1957
|
-
var
|
|
1958
|
-
var addPersonalContextInputSchema =
|
|
1959
|
-
content:
|
|
1960
|
-
category:
|
|
1961
|
-
tags:
|
|
1962
|
-
scope_type:
|
|
1963
|
-
scope_id:
|
|
2041
|
+
var import_v417 = require("zod/v4");
|
|
2042
|
+
var addPersonalContextInputSchema = import_v417.z.object({
|
|
2043
|
+
content: import_v417.z.string().min(1),
|
|
2044
|
+
category: import_v417.z.string().optional(),
|
|
2045
|
+
tags: import_v417.z.array(import_v417.z.string()).optional(),
|
|
2046
|
+
scope_type: import_v417.z.enum(["general", "project"]).optional(),
|
|
2047
|
+
scope_id: import_v417.z.string().optional()
|
|
1964
2048
|
});
|
|
1965
2049
|
async function handleAddPersonalContext(client, args) {
|
|
1966
2050
|
const parsed2 = addPersonalContextInputSchema.parse(args ?? {});
|
|
@@ -1996,12 +2080,12 @@ async function handleAddPersonalContext(client, args) {
|
|
|
1996
2080
|
}
|
|
1997
2081
|
|
|
1998
2082
|
// src/tools/handlers/getPersonalContext.ts
|
|
1999
|
-
var
|
|
2000
|
-
var getPersonalContextInputSchema =
|
|
2001
|
-
query:
|
|
2002
|
-
scope_type:
|
|
2003
|
-
scope_id:
|
|
2004
|
-
limit:
|
|
2083
|
+
var import_v418 = require("zod/v4");
|
|
2084
|
+
var getPersonalContextInputSchema = import_v418.z.object({
|
|
2085
|
+
query: import_v418.z.string().optional(),
|
|
2086
|
+
scope_type: import_v418.z.enum(["general", "project"]).optional(),
|
|
2087
|
+
scope_id: import_v418.z.string().optional(),
|
|
2088
|
+
limit: import_v418.z.number().int().positive().optional()
|
|
2005
2089
|
});
|
|
2006
2090
|
function buildPersonalContextPath(parsed2) {
|
|
2007
2091
|
const params = new URLSearchParams();
|
|
@@ -2038,13 +2122,13 @@ async function handleGetPersonalContext(client, args) {
|
|
|
2038
2122
|
}
|
|
2039
2123
|
|
|
2040
2124
|
// src/tools/handlers/askWithMemory.ts
|
|
2041
|
-
var
|
|
2042
|
-
var askWithMemoryInputSchema =
|
|
2043
|
-
question:
|
|
2044
|
-
code_context:
|
|
2045
|
-
file_path:
|
|
2046
|
-
selected_text:
|
|
2047
|
-
language:
|
|
2125
|
+
var import_v419 = require("zod/v4");
|
|
2126
|
+
var askWithMemoryInputSchema = import_v419.z.object({
|
|
2127
|
+
question: import_v419.z.string().min(1),
|
|
2128
|
+
code_context: import_v419.z.object({
|
|
2129
|
+
file_path: import_v419.z.string().optional(),
|
|
2130
|
+
selected_text: import_v419.z.string().optional(),
|
|
2131
|
+
language: import_v419.z.string().optional()
|
|
2048
2132
|
}).optional()
|
|
2049
2133
|
});
|
|
2050
2134
|
function isAskWithMemoryResponse(value) {
|
|
@@ -2080,13 +2164,13 @@ async function handleAskWithMemory(client, args) {
|
|
|
2080
2164
|
}
|
|
2081
2165
|
|
|
2082
2166
|
// src/tools/handlers/logIntent.ts
|
|
2083
|
-
var
|
|
2084
|
-
var logIntentInputSchema =
|
|
2085
|
-
intent:
|
|
2086
|
-
message:
|
|
2087
|
-
context:
|
|
2088
|
-
intent_source:
|
|
2089
|
-
run_id:
|
|
2167
|
+
var import_v420 = require("zod/v4");
|
|
2168
|
+
var logIntentInputSchema = import_v420.z.object({
|
|
2169
|
+
intent: import_v420.z.enum(["task", "decision"]),
|
|
2170
|
+
message: import_v420.z.string().min(1),
|
|
2171
|
+
context: import_v420.z.record(import_v420.z.string(), import_v420.z.any()).optional(),
|
|
2172
|
+
intent_source: import_v420.z.string().optional().default("cursor_chat"),
|
|
2173
|
+
run_id: import_v420.z.string().min(1).optional()
|
|
2090
2174
|
});
|
|
2091
2175
|
async function handleLogIntent(client, args) {
|
|
2092
2176
|
const parsed2 = logIntentInputSchema.parse(args ?? {});
|
|
@@ -2128,18 +2212,18 @@ async function handleLogIntent(client, args) {
|
|
|
2128
2212
|
}
|
|
2129
2213
|
|
|
2130
2214
|
// src/tools/handlers/logChangeSummary.ts
|
|
2131
|
-
var
|
|
2132
|
-
var logChangeSummaryInputSchema =
|
|
2133
|
-
summary:
|
|
2134
|
-
scope:
|
|
2135
|
-
files:
|
|
2136
|
-
stats:
|
|
2137
|
-
files:
|
|
2138
|
-
add:
|
|
2139
|
-
del:
|
|
2215
|
+
var import_v421 = require("zod/v4");
|
|
2216
|
+
var logChangeSummaryInputSchema = import_v421.z.object({
|
|
2217
|
+
summary: import_v421.z.string().min(1),
|
|
2218
|
+
scope: import_v421.z.string().min(1).optional(),
|
|
2219
|
+
files: import_v421.z.array(import_v421.z.string().min(1)).optional(),
|
|
2220
|
+
stats: import_v421.z.object({
|
|
2221
|
+
files: import_v421.z.number().int().nonnegative().optional(),
|
|
2222
|
+
add: import_v421.z.number().int().nonnegative().optional(),
|
|
2223
|
+
del: import_v421.z.number().int().nonnegative().optional()
|
|
2140
2224
|
}).optional(),
|
|
2141
|
-
commit:
|
|
2142
|
-
run_id:
|
|
2225
|
+
commit: import_v421.z.string().min(1).optional(),
|
|
2226
|
+
run_id: import_v421.z.string().min(1).optional()
|
|
2143
2227
|
});
|
|
2144
2228
|
async function handleLogChangeSummary(client, args) {
|
|
2145
2229
|
const parsed2 = logChangeSummaryInputSchema.parse(args ?? {});
|
|
@@ -2174,17 +2258,17 @@ async function handleLogChangeSummary(client, args) {
|
|
|
2174
2258
|
}
|
|
2175
2259
|
|
|
2176
2260
|
// src/tools/handlers/logToolResult.ts
|
|
2177
|
-
var
|
|
2178
|
-
var logToolResultInputSchema =
|
|
2179
|
-
tool:
|
|
2180
|
-
status:
|
|
2181
|
-
summary:
|
|
2182
|
-
run_id:
|
|
2183
|
-
duration_ms:
|
|
2184
|
-
error_code:
|
|
2185
|
-
error_message:
|
|
2186
|
-
error_kind:
|
|
2187
|
-
stats:
|
|
2261
|
+
var import_v422 = require("zod/v4");
|
|
2262
|
+
var logToolResultInputSchema = import_v422.z.object({
|
|
2263
|
+
tool: import_v422.z.string().min(1),
|
|
2264
|
+
status: import_v422.z.enum(["ok", "error", "partial"]),
|
|
2265
|
+
summary: import_v422.z.string().min(1),
|
|
2266
|
+
run_id: import_v422.z.string().min(1).optional(),
|
|
2267
|
+
duration_ms: import_v422.z.number().int().nonnegative().optional(),
|
|
2268
|
+
error_code: import_v422.z.string().min(1).optional(),
|
|
2269
|
+
error_message: import_v422.z.string().min(1).optional(),
|
|
2270
|
+
error_kind: import_v422.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
|
|
2271
|
+
stats: import_v422.z.record(import_v422.z.string(), import_v422.z.any()).optional()
|
|
2188
2272
|
});
|
|
2189
2273
|
async function handleLogToolResult(client, args) {
|
|
2190
2274
|
const parsed2 = logToolResultInputSchema.parse(args ?? {});
|
|
@@ -2222,15 +2306,15 @@ async function handleLogToolResult(client, args) {
|
|
|
2222
2306
|
}
|
|
2223
2307
|
|
|
2224
2308
|
// src/tools/handlers/logCommand.ts
|
|
2225
|
-
var
|
|
2226
|
-
var logCommandInputSchema =
|
|
2227
|
-
cmd:
|
|
2228
|
-
summary:
|
|
2229
|
-
cwd:
|
|
2230
|
-
exit_code:
|
|
2231
|
-
duration_ms:
|
|
2232
|
-
run_id:
|
|
2233
|
-
stats:
|
|
2309
|
+
var import_v423 = require("zod/v4");
|
|
2310
|
+
var logCommandInputSchema = import_v423.z.object({
|
|
2311
|
+
cmd: import_v423.z.string().min(1),
|
|
2312
|
+
summary: import_v423.z.string().min(1),
|
|
2313
|
+
cwd: import_v423.z.string().min(1).optional(),
|
|
2314
|
+
exit_code: import_v423.z.number().int().optional(),
|
|
2315
|
+
duration_ms: import_v423.z.number().int().nonnegative().optional(),
|
|
2316
|
+
run_id: import_v423.z.string().min(1).optional(),
|
|
2317
|
+
stats: import_v423.z.record(import_v423.z.string(), import_v423.z.any()).optional()
|
|
2234
2318
|
});
|
|
2235
2319
|
async function handleLogCommand(client, args) {
|
|
2236
2320
|
const parsed2 = logCommandInputSchema.parse(args ?? {});
|
|
@@ -2265,6 +2349,244 @@ async function handleLogCommand(client, args) {
|
|
|
2265
2349
|
return { ok: true };
|
|
2266
2350
|
}
|
|
2267
2351
|
|
|
2352
|
+
// src/tools/responseProjection.ts
|
|
2353
|
+
var timelineItemKeys = [
|
|
2354
|
+
"id",
|
|
2355
|
+
"ts",
|
|
2356
|
+
"kind",
|
|
2357
|
+
"concept",
|
|
2358
|
+
"old_value",
|
|
2359
|
+
"new_value",
|
|
2360
|
+
"reason",
|
|
2361
|
+
"confidence",
|
|
2362
|
+
"links",
|
|
2363
|
+
"source_ref",
|
|
2364
|
+
"redacted",
|
|
2365
|
+
"redaction_reason",
|
|
2366
|
+
"summary",
|
|
2367
|
+
"consolidated_of"
|
|
2368
|
+
];
|
|
2369
|
+
var conceptVersionKeys = [
|
|
2370
|
+
"version",
|
|
2371
|
+
"ts",
|
|
2372
|
+
"reason",
|
|
2373
|
+
"confidence",
|
|
2374
|
+
"source_ref",
|
|
2375
|
+
"value"
|
|
2376
|
+
];
|
|
2377
|
+
function invalidResponse() {
|
|
2378
|
+
throw new Error("Invalid Memora response");
|
|
2379
|
+
}
|
|
2380
|
+
function isRecord(value) {
|
|
2381
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2382
|
+
}
|
|
2383
|
+
function pickFields(raw, keys) {
|
|
2384
|
+
const result = {};
|
|
2385
|
+
for (const key of keys) {
|
|
2386
|
+
if (Object.prototype.hasOwnProperty.call(raw, key) && raw[key] !== void 0) {
|
|
2387
|
+
result[key] = raw[key];
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
return result;
|
|
2391
|
+
}
|
|
2392
|
+
function pickConceptVersion(raw) {
|
|
2393
|
+
return pickFields(raw, conceptVersionKeys);
|
|
2394
|
+
}
|
|
2395
|
+
function pickConceptItem(raw) {
|
|
2396
|
+
if (typeof raw.id !== "string" || raw.id.trim() === "") invalidResponse();
|
|
2397
|
+
const item = { id: raw.id };
|
|
2398
|
+
if (Object.prototype.hasOwnProperty.call(raw, "tags")) {
|
|
2399
|
+
if (!Array.isArray(raw.tags) || !raw.tags.every((tag) => typeof tag === "string")) {
|
|
2400
|
+
invalidResponse();
|
|
2401
|
+
}
|
|
2402
|
+
item.tags = raw.tags;
|
|
2403
|
+
}
|
|
2404
|
+
if (Object.prototype.hasOwnProperty.call(raw, "parent_id")) {
|
|
2405
|
+
if (raw.parent_id !== null && typeof raw.parent_id !== "string") invalidResponse();
|
|
2406
|
+
item.parent_id = raw.parent_id;
|
|
2407
|
+
}
|
|
2408
|
+
if (Object.prototype.hasOwnProperty.call(raw, "latest")) {
|
|
2409
|
+
if (raw.latest === null) {
|
|
2410
|
+
item.latest = null;
|
|
2411
|
+
} else if (isRecord(raw.latest)) {
|
|
2412
|
+
item.latest = pickConceptVersion(raw.latest);
|
|
2413
|
+
} else {
|
|
2414
|
+
invalidResponse();
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
return item;
|
|
2418
|
+
}
|
|
2419
|
+
function normalizeCursor(raw) {
|
|
2420
|
+
for (const key of ["next_cursor", "nextCursor"]) {
|
|
2421
|
+
if (!Object.prototype.hasOwnProperty.call(raw, key)) continue;
|
|
2422
|
+
const value = raw[key];
|
|
2423
|
+
if (value === null) return null;
|
|
2424
|
+
if (typeof value === "string") return value;
|
|
2425
|
+
invalidResponse();
|
|
2426
|
+
}
|
|
2427
|
+
return null;
|
|
2428
|
+
}
|
|
2429
|
+
function projectTimelineResponse(data) {
|
|
2430
|
+
if (!isRecord(data) || !Array.isArray(data.items) || !isRecord(data.page)) {
|
|
2431
|
+
invalidResponse();
|
|
2432
|
+
}
|
|
2433
|
+
if (typeof data.page.limit !== "number" || !Number.isFinite(data.page.limit) || data.page.sort !== "newest" && data.page.sort !== "oldest") {
|
|
2434
|
+
invalidResponse();
|
|
2435
|
+
}
|
|
2436
|
+
const items = data.items.map((entry) => {
|
|
2437
|
+
if (!isRecord(entry)) invalidResponse();
|
|
2438
|
+
return pickFields(entry, timelineItemKeys);
|
|
2439
|
+
});
|
|
2440
|
+
return {
|
|
2441
|
+
items,
|
|
2442
|
+
page: {
|
|
2443
|
+
limit: data.page.limit,
|
|
2444
|
+
sort: data.page.sort,
|
|
2445
|
+
next_cursor: normalizeCursor(data.page)
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
function projectConceptListResponse(data, requestedLimit) {
|
|
2450
|
+
if (!isRecord(data)) invalidResponse();
|
|
2451
|
+
let entries;
|
|
2452
|
+
if (Object.prototype.hasOwnProperty.call(data, "rows")) {
|
|
2453
|
+
entries = data.rows;
|
|
2454
|
+
} else if (Object.prototype.hasOwnProperty.call(data, "items")) {
|
|
2455
|
+
entries = data.items;
|
|
2456
|
+
} else {
|
|
2457
|
+
invalidResponse();
|
|
2458
|
+
}
|
|
2459
|
+
if (!Array.isArray(entries)) invalidResponse();
|
|
2460
|
+
let cursorSource = data;
|
|
2461
|
+
if (!Object.prototype.hasOwnProperty.call(data, "next_cursor") && !Object.prototype.hasOwnProperty.call(data, "nextCursor") && Object.prototype.hasOwnProperty.call(data, "page")) {
|
|
2462
|
+
if (!isRecord(data.page)) invalidResponse();
|
|
2463
|
+
cursorSource = data.page;
|
|
2464
|
+
}
|
|
2465
|
+
return {
|
|
2466
|
+
items: entries.map((entry) => {
|
|
2467
|
+
if (!isRecord(entry)) invalidResponse();
|
|
2468
|
+
return pickConceptItem(entry);
|
|
2469
|
+
}),
|
|
2470
|
+
page: {
|
|
2471
|
+
limit: requestedLimit ?? 50,
|
|
2472
|
+
next_cursor: normalizeCursor(cursorSource)
|
|
2473
|
+
}
|
|
2474
|
+
};
|
|
2475
|
+
}
|
|
2476
|
+
function projectConceptResponse(data) {
|
|
2477
|
+
if (!isRecord(data)) invalidResponse();
|
|
2478
|
+
const item = pickConceptItem(data);
|
|
2479
|
+
if (!Object.prototype.hasOwnProperty.call(data, "history")) {
|
|
2480
|
+
return { ...item, history: [] };
|
|
2481
|
+
}
|
|
2482
|
+
if (!Array.isArray(data.history)) invalidResponse();
|
|
2483
|
+
const history = data.history.map((entry) => {
|
|
2484
|
+
if (!isRecord(entry)) invalidResponse();
|
|
2485
|
+
return pickConceptVersion(entry);
|
|
2486
|
+
});
|
|
2487
|
+
return { ...item, history };
|
|
2488
|
+
}
|
|
2489
|
+
function projectCreatedConceptVersionResponse(data) {
|
|
2490
|
+
if (!isRecord(data)) invalidResponse();
|
|
2491
|
+
return pickConceptItem(data);
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
// src/tools/handlers/toolRequestError.ts
|
|
2495
|
+
function rethrowToolRequestError(toolName, error) {
|
|
2496
|
+
if (error instanceof SyntaxError) {
|
|
2497
|
+
throw new Error("Invalid Memora response");
|
|
2498
|
+
}
|
|
2499
|
+
if (!(error instanceof MemoraOneHttpError)) throw error;
|
|
2500
|
+
let detail = "request failed";
|
|
2501
|
+
if (error.status === 401) detail = "authentication failed";
|
|
2502
|
+
else if (error.status === 403) detail = "connection unavailable";
|
|
2503
|
+
else if (error.status === 404) detail = "resource not found";
|
|
2504
|
+
else if (error.status === 409) detail = "conflict";
|
|
2505
|
+
else if (error.status >= 500) detail = "backend error";
|
|
2506
|
+
throw new Error(`${toolName} failed: ${error.status} ${detail}`);
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
// src/tools/handlers/listTimeline.ts
|
|
2510
|
+
function buildQuery(input) {
|
|
2511
|
+
const parts = [];
|
|
2512
|
+
const append = (key, value) => {
|
|
2513
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
2514
|
+
};
|
|
2515
|
+
if (input.since !== void 0) append("since", input.since);
|
|
2516
|
+
if (input.concept !== void 0) append("concept", input.concept);
|
|
2517
|
+
if (input.kind !== void 0) {
|
|
2518
|
+
for (const kind of Array.isArray(input.kind) ? input.kind : [input.kind]) {
|
|
2519
|
+
append("kind", kind);
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
if (input.sort !== void 0) append("sort", input.sort);
|
|
2523
|
+
if (input.limit !== void 0) append("limit", String(input.limit));
|
|
2524
|
+
if (input.cursor !== void 0) append("cursor", input.cursor);
|
|
2525
|
+
return parts.length === 0 ? "" : `?${parts.join("&")}`;
|
|
2526
|
+
}
|
|
2527
|
+
async function handleListTimeline(client, args) {
|
|
2528
|
+
const input = listTimelineInputSchema.parse(args ?? {});
|
|
2529
|
+
try {
|
|
2530
|
+
return projectTimelineResponse(await client.get(`/timeline${buildQuery(input)}`));
|
|
2531
|
+
} catch (error) {
|
|
2532
|
+
rethrowToolRequestError("memora_list_timeline", error);
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// src/tools/handlers/listConcepts.ts
|
|
2537
|
+
function buildQuery2(input) {
|
|
2538
|
+
const parts = [];
|
|
2539
|
+
const append = (key, value) => {
|
|
2540
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
2541
|
+
};
|
|
2542
|
+
if (input.q !== void 0) append("q", input.q);
|
|
2543
|
+
if (input.tag !== void 0) append("tag", input.tag);
|
|
2544
|
+
if (input.parent_id !== void 0) append("parent_id", input.parent_id);
|
|
2545
|
+
if (input.limit !== void 0) append("limit", String(input.limit));
|
|
2546
|
+
if (input.cursor !== void 0) append("cursor", input.cursor);
|
|
2547
|
+
return parts.length === 0 ? "" : `?${parts.join("&")}`;
|
|
2548
|
+
}
|
|
2549
|
+
async function handleListConcepts(client, args) {
|
|
2550
|
+
const input = listConceptsInputSchema.parse(args ?? {});
|
|
2551
|
+
try {
|
|
2552
|
+
const data = await client.get(`/concepts${buildQuery2(input)}`);
|
|
2553
|
+
return projectConceptListResponse(data, input.limit);
|
|
2554
|
+
} catch (error) {
|
|
2555
|
+
rethrowToolRequestError("memora_list_concepts", error);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
// src/tools/handlers/getConcept.ts
|
|
2560
|
+
async function handleGetConcept(client, args) {
|
|
2561
|
+
const input = getConceptInputSchema.parse(args ?? {});
|
|
2562
|
+
try {
|
|
2563
|
+
const data = await client.get(`/concepts/${encodeURIComponent(input.id)}`);
|
|
2564
|
+
return projectConceptResponse(data);
|
|
2565
|
+
} catch (error) {
|
|
2566
|
+
rethrowToolRequestError("memora_get_concept", error);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
// src/tools/handlers/createConceptVersion.ts
|
|
2571
|
+
async function handleCreateConceptVersion(client, args) {
|
|
2572
|
+
const input = createConceptVersionInputSchema.parse(args ?? {});
|
|
2573
|
+
if (!isJsonValue(input.value)) {
|
|
2574
|
+
throw new Error("Invalid arguments: value must be a valid JSON value");
|
|
2575
|
+
}
|
|
2576
|
+
const body = { value: input.value };
|
|
2577
|
+
if (input.reason !== void 0) body.reason = input.reason;
|
|
2578
|
+
if (input.confidence !== void 0) body.confidence = input.confidence;
|
|
2579
|
+
if (input.source_ref !== void 0) body.source_ref = input.source_ref;
|
|
2580
|
+
if (input.tags !== void 0) body.tags = input.tags;
|
|
2581
|
+
if (input.parent_id !== void 0) body.parent_id = input.parent_id;
|
|
2582
|
+
try {
|
|
2583
|
+
const path14 = `/concepts/${encodeURIComponent(input.id)}/versions`;
|
|
2584
|
+
return projectCreatedConceptVersionResponse(await client.post(path14, body));
|
|
2585
|
+
} catch (error) {
|
|
2586
|
+
rethrowToolRequestError("memora_create_concept_version", error);
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2268
2590
|
// src/tools/handlers/bindingStatus.ts
|
|
2269
2591
|
function buildBindingStatus(binding, options = {}) {
|
|
2270
2592
|
const status = {
|
|
@@ -2315,8 +2637,9 @@ function isHeartbeatDebugEnabled() {
|
|
|
2315
2637
|
const value = String(process.env.MEMORAONE_DEBUG_HEARTBEAT ?? "").trim().toLowerCase();
|
|
2316
2638
|
return ["1", "true", "yes", "on"].includes(value);
|
|
2317
2639
|
}
|
|
2640
|
+
var LOCAL_MCP_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
2318
2641
|
function resolveHeartbeatIntervalMs() {
|
|
2319
|
-
return
|
|
2642
|
+
return LOCAL_MCP_HEARTBEAT_INTERVAL_MS;
|
|
2320
2643
|
}
|
|
2321
2644
|
function redactSensitiveText(text) {
|
|
2322
2645
|
return text.replace(/mcs_[A-Za-z0-9_-]+/g, "mcs_[redacted]").replace(/mia_[A-Za-z0-9_-]+/g, "mia_[redacted]").replace(/mir_[A-Za-z0-9_-]+/g, "mir_[redacted]").replace(/mcc_[A-Za-z0-9_-]+/g, "mcc_[redacted]").replace(/Bearer\s+\S+/gi, "Bearer [redacted]");
|
|
@@ -2426,6 +2749,7 @@ async function sendProjectHeartbeat(client, ctx) {
|
|
|
2426
2749
|
}
|
|
2427
2750
|
function createDaemonHeartbeat(opts) {
|
|
2428
2751
|
let interval = null;
|
|
2752
|
+
let runGeneration = 0;
|
|
2429
2753
|
let client = null;
|
|
2430
2754
|
let announced = false;
|
|
2431
2755
|
let studioActive = null;
|
|
@@ -2494,21 +2818,24 @@ function createDaemonHeartbeat(opts) {
|
|
|
2494
2818
|
studioActive = true;
|
|
2495
2819
|
}
|
|
2496
2820
|
};
|
|
2497
|
-
const tick = async () => {
|
|
2498
|
-
if (!client) return;
|
|
2821
|
+
const tick = async (generation) => {
|
|
2822
|
+
if (!client || generation !== runGeneration) return;
|
|
2499
2823
|
const outcome = await sendProjectHeartbeat(client, ctx);
|
|
2824
|
+
if (generation !== runGeneration || !interval) return;
|
|
2500
2825
|
applyHeartbeatOutcome(outcome);
|
|
2501
2826
|
};
|
|
2502
2827
|
const beginInterval = () => {
|
|
2503
2828
|
if (interval) return;
|
|
2504
2829
|
const intervalMs = resolveHeartbeatIntervalMs();
|
|
2830
|
+
const generation = runGeneration;
|
|
2505
2831
|
log(
|
|
2506
2832
|
`daemon owns heartbeat for binding=${opts.binding.repositoryBindingId} project=${opts.binding.projectId} ideType=${ctx.ideType ?? "unknown"} interval=${intervalMs}ms`
|
|
2507
2833
|
);
|
|
2508
|
-
void tick();
|
|
2509
2834
|
interval = setInterval(() => {
|
|
2510
|
-
void tick();
|
|
2835
|
+
void tick(generation);
|
|
2511
2836
|
}, intervalMs);
|
|
2837
|
+
interval.unref?.();
|
|
2838
|
+
void tick(generation);
|
|
2512
2839
|
};
|
|
2513
2840
|
const start = async () => {
|
|
2514
2841
|
if (!config2.heartbeatEnabled) {
|
|
@@ -2541,6 +2868,7 @@ function createDaemonHeartbeat(opts) {
|
|
|
2541
2868
|
}
|
|
2542
2869
|
};
|
|
2543
2870
|
const stop = () => {
|
|
2871
|
+
runGeneration += 1;
|
|
2544
2872
|
if (interval) {
|
|
2545
2873
|
clearInterval(interval);
|
|
2546
2874
|
interval = null;
|
|
@@ -2560,7 +2888,7 @@ function createDaemonHeartbeat(opts) {
|
|
|
2560
2888
|
return;
|
|
2561
2889
|
}
|
|
2562
2890
|
if (client && interval) {
|
|
2563
|
-
void tick();
|
|
2891
|
+
void tick(runGeneration);
|
|
2564
2892
|
}
|
|
2565
2893
|
};
|
|
2566
2894
|
const getIdeType = () => ctx.ideType;
|
|
@@ -2580,12 +2908,52 @@ function createDaemonHeartbeat(opts) {
|
|
|
2580
2908
|
}
|
|
2581
2909
|
|
|
2582
2910
|
// src/ideType.ts
|
|
2911
|
+
function mapReliableClientInfoName(name) {
|
|
2912
|
+
if (typeof name !== "string") {
|
|
2913
|
+
return void 0;
|
|
2914
|
+
}
|
|
2915
|
+
const normalized = name.trim().toLowerCase();
|
|
2916
|
+
if (normalized === "") {
|
|
2917
|
+
return void 0;
|
|
2918
|
+
}
|
|
2919
|
+
if (normalized === "claude-code") {
|
|
2920
|
+
return "claude-code";
|
|
2921
|
+
}
|
|
2922
|
+
if (normalized === "devin") {
|
|
2923
|
+
return "windsurf";
|
|
2924
|
+
}
|
|
2925
|
+
if (normalized === "windsurf" || /^windsurf[\s_-].+$/.test(normalized)) {
|
|
2926
|
+
return "windsurf";
|
|
2927
|
+
}
|
|
2928
|
+
return void 0;
|
|
2929
|
+
}
|
|
2930
|
+
function mapReliableHostIdentity(env2) {
|
|
2931
|
+
if (env2.WINDSURF_IDE_TYPE === "windsurf") {
|
|
2932
|
+
return "windsurf";
|
|
2933
|
+
}
|
|
2934
|
+
if (env2.ACP_BACKEND === "windsurf") {
|
|
2935
|
+
return "windsurf";
|
|
2936
|
+
}
|
|
2937
|
+
if (env2.__CFBundleIdentifier === "com.exafunction.windsurf") {
|
|
2938
|
+
return "windsurf";
|
|
2939
|
+
}
|
|
2940
|
+
return void 0;
|
|
2941
|
+
}
|
|
2583
2942
|
function inferIdeType(params, options = {}) {
|
|
2584
2943
|
const env2 = options.env ?? process.env;
|
|
2585
2944
|
const argv = (options.argv ?? process.argv).join(" ").toLowerCase();
|
|
2586
|
-
const
|
|
2587
|
-
|
|
2588
|
-
|
|
2945
|
+
const hasExplicitConfigOption = Object.prototype.hasOwnProperty.call(options, "configIdeType");
|
|
2946
|
+
const explicitHint = hasExplicitConfigOption ? options.configIdeType : resolveIdeTypeFromEnv(env2) ?? config2.ideType;
|
|
2947
|
+
const fromClientInfo = mapReliableClientInfoName(params?.clientInfo?.name);
|
|
2948
|
+
if (fromClientInfo) {
|
|
2949
|
+
return fromClientInfo;
|
|
2950
|
+
}
|
|
2951
|
+
const fromHost = mapReliableHostIdentity(env2);
|
|
2952
|
+
if (fromHost) {
|
|
2953
|
+
return fromHost;
|
|
2954
|
+
}
|
|
2955
|
+
if (explicitHint) {
|
|
2956
|
+
return explicitHint;
|
|
2589
2957
|
}
|
|
2590
2958
|
const clientInfoName = String(params?.clientInfo?.name ?? "").toLowerCase();
|
|
2591
2959
|
const clientInfoVersion = String(params?.clientInfo?.version ?? "").toLowerCase();
|
|
@@ -2742,7 +3110,11 @@ async function main(opts = {}) {
|
|
|
2742
3110
|
`[memoraone-mcp] refreshed stale cached binding ${reconciled.binding.repositoryBindingId}: project=${reconciled.binding.projectId}`
|
|
2743
3111
|
);
|
|
2744
3112
|
try {
|
|
2745
|
-
const socketPath = getBindingSocketPath(
|
|
3113
|
+
const socketPath = getBindingSocketPath(
|
|
3114
|
+
opts.daemonBindingHint,
|
|
3115
|
+
process.env,
|
|
3116
|
+
runtime.ideType ?? ""
|
|
3117
|
+
);
|
|
2746
3118
|
writeBindingSidecar(socketPath, reconciled.binding, runtime.ideType ?? "");
|
|
2747
3119
|
} catch (err) {
|
|
2748
3120
|
console.error(
|
|
@@ -2935,6 +3307,71 @@ async function main(opts = {}) {
|
|
|
2935
3307
|
}
|
|
2936
3308
|
);
|
|
2937
3309
|
registeredToolNames.push("memora_log_command");
|
|
3310
|
+
server.registerTool(
|
|
3311
|
+
"memora_list_timeline",
|
|
3312
|
+
{
|
|
3313
|
+
description: listTimelineDescription,
|
|
3314
|
+
inputSchema: listTimelineInputSchema
|
|
3315
|
+
},
|
|
3316
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3317
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3318
|
+
const result = await handleListTimeline(runtime.client, args);
|
|
3319
|
+
return {
|
|
3320
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3321
|
+
};
|
|
3322
|
+
})
|
|
3323
|
+
);
|
|
3324
|
+
registeredToolNames.push("memora_list_timeline");
|
|
3325
|
+
server.registerTool(
|
|
3326
|
+
"memora_list_concepts",
|
|
3327
|
+
{
|
|
3328
|
+
description: listConceptsDescription,
|
|
3329
|
+
inputSchema: listConceptsInputSchema
|
|
3330
|
+
},
|
|
3331
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3332
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3333
|
+
const result = await handleListConcepts(runtime.client, args);
|
|
3334
|
+
return {
|
|
3335
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3336
|
+
};
|
|
3337
|
+
})
|
|
3338
|
+
);
|
|
3339
|
+
registeredToolNames.push("memora_list_concepts");
|
|
3340
|
+
server.registerTool(
|
|
3341
|
+
"memora_get_concept",
|
|
3342
|
+
{
|
|
3343
|
+
description: getConceptDescription,
|
|
3344
|
+
inputSchema: getConceptInputSchema
|
|
3345
|
+
},
|
|
3346
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3347
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3348
|
+
const result = await handleGetConcept(runtime.client, args);
|
|
3349
|
+
return {
|
|
3350
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3351
|
+
};
|
|
3352
|
+
})
|
|
3353
|
+
);
|
|
3354
|
+
registeredToolNames.push("memora_get_concept");
|
|
3355
|
+
server.registerTool(
|
|
3356
|
+
"memora_create_concept_version",
|
|
3357
|
+
{
|
|
3358
|
+
description: createConceptVersionDescription,
|
|
3359
|
+
inputSchema: createConceptVersionInputSchema
|
|
3360
|
+
},
|
|
3361
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3362
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3363
|
+
const result = await handleCreateConceptVersion(runtime.client, args);
|
|
3364
|
+
return {
|
|
3365
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3366
|
+
};
|
|
3367
|
+
})
|
|
3368
|
+
);
|
|
3369
|
+
registeredToolNames.push("memora_create_concept_version");
|
|
3370
|
+
if (registeredToolNames.length !== LOCAL_MCP_TOOL_NAMES.length || registeredToolNames.some(
|
|
3371
|
+
(name) => !LOCAL_MCP_TOOL_NAMES.includes(name)
|
|
3372
|
+
)) {
|
|
3373
|
+
throw new Error("Local MCP tool registration inventory mismatch");
|
|
3374
|
+
}
|
|
2938
3375
|
server.server.setRequestHandler(
|
|
2939
3376
|
import_types.InitializeRequestSchema,
|
|
2940
3377
|
async (request) => runWithSessionContext(sessionContext, async () => {
|