@mnemonik/cursor-hooks 0.7.7 → 0.7.9
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/hook.js +64 -167
- package/dist/hook.js.map +1 -1
- package/dist/install.d.ts +2 -2
- package/dist/install.js +6 -39
- package/dist/install.js.map +1 -1
- package/dist/lib/behavior.d.ts +2 -4
- package/dist/lib/behavior.js +2 -4
- package/dist/lib/behavior.js.map +1 -1
- package/dist/lib/contextOverflow.js +7 -90
- package/dist/lib/contextOverflow.js.map +1 -1
- package/dist/lib/cursorOutput.js +2 -4
- package/dist/lib/cursorOutput.js.map +1 -1
- package/dist/lib/dedupGuard.d.ts +0 -1
- package/dist/lib/dedupGuard.js +1 -4
- package/dist/lib/dedupGuard.js.map +1 -1
- package/dist/lib/files.d.ts +20 -0
- package/dist/lib/files.js +52 -0
- package/dist/lib/files.js.map +1 -0
- package/dist/lib/http.d.ts +5 -10
- package/dist/lib/http.js +26 -40
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/types.d.ts +11 -12
- package/dist/lib/types.js.map +1 -1
- package/package.json +2 -2
- package/dist/lib/mcpOwnership.d.ts +0 -19
- package/dist/lib/mcpOwnership.js +0 -127
- package/dist/lib/mcpOwnership.js.map +0 -1
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export declare function isCursorMcpToolEvent(tool: string): boolean;
|
|
2
|
-
/** Canonical server-facing name; call only after ownership has been proved. */
|
|
3
|
-
export declare function canonicalMnemonikMcpTool(tool: string): string | null;
|
|
4
|
-
export interface CursorMcpOwnershipInput {
|
|
5
|
-
tool: string;
|
|
6
|
-
command?: string;
|
|
7
|
-
url?: string;
|
|
8
|
-
cwd: string;
|
|
9
|
-
workspaceRoots?: string[];
|
|
10
|
-
hookServer: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Prove that a globally observed Cursor MCP event belongs to Mnemonik.
|
|
14
|
-
* A namespace is only a user-configurable server key, not authentication.
|
|
15
|
-
* Without exact event URL/command metadata, that extracted key must be bound
|
|
16
|
-
* to the configured Mnemonik endpoint in Cursor's MCP config. Missing,
|
|
17
|
-
* unreadable, or conflicting bindings fail closed.
|
|
18
|
-
*/
|
|
19
|
-
export declare function isMnemonikMcpCall(input: CursorMcpOwnershipInput): Promise<boolean>;
|
package/dist/lib/mcpOwnership.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
const BARE_MNEMONIK_TOOLS = new Set(['memory_tools', 'memory_discover', 'session_bootstrap']);
|
|
5
|
-
const CURSOR_NAMESPACED_TOOL = /^(?:MCP:)?(.+)\.(memory_tools|memory_discover|session_bootstrap)$/;
|
|
6
|
-
const CLAUDE_STYLE_NAMESPACED_TOOL = /^mcp__(.+)__(memory_tools|memory_discover|session_bootstrap)$/;
|
|
7
|
-
export function isCursorMcpToolEvent(tool) {
|
|
8
|
-
return tool.startsWith('MCP:') || tool.startsWith('mcp__') || BARE_MNEMONIK_TOOLS.has(tool);
|
|
9
|
-
}
|
|
10
|
-
/** Canonical server-facing name; call only after ownership has been proved. */
|
|
11
|
-
export function canonicalMnemonikMcpTool(tool) {
|
|
12
|
-
if (BARE_MNEMONIK_TOOLS.has(tool))
|
|
13
|
-
return tool;
|
|
14
|
-
const match = CURSOR_NAMESPACED_TOOL.exec(tool) ?? CLAUDE_STYLE_NAMESPACED_TOOL.exec(tool);
|
|
15
|
-
return match?.[2] ?? null;
|
|
16
|
-
}
|
|
17
|
-
function normalizeUrl(raw) {
|
|
18
|
-
try {
|
|
19
|
-
const url = new URL(raw);
|
|
20
|
-
url.hash = '';
|
|
21
|
-
if (url.pathname.length > 1)
|
|
22
|
-
url.pathname = url.pathname.replace(/\/+$/, '');
|
|
23
|
-
return url.toString();
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function expectedMcpUrl(hookServer) {
|
|
30
|
-
return normalizeUrl(`${hookServer.replace(/\/+$/, '')}/mcp`);
|
|
31
|
-
}
|
|
32
|
-
function namespacedServerKey(tool) {
|
|
33
|
-
const match = CURSOR_NAMESPACED_TOOL.exec(tool) ?? CLAUDE_STYLE_NAMESPACED_TOOL.exec(tool);
|
|
34
|
-
return match?.[1]?.trim() || null;
|
|
35
|
-
}
|
|
36
|
-
function definitionTargetsMnemonik(definition, expectedUrl) {
|
|
37
|
-
for (const candidate of [definition.url, definition.serverUrl]) {
|
|
38
|
-
if (typeof candidate === 'string' && normalizeUrl(candidate) === expectedUrl)
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
// Older Cursor installations sometimes use mcp-remote over stdio. Accept
|
|
42
|
-
// that only when the exact expected endpoint is an argument to the known
|
|
43
|
-
// wrapper; a generic command or a coincidental bare tool name proves nothing.
|
|
44
|
-
if (typeof definition.command === 'string' &&
|
|
45
|
-
/^(?:npx(?:\.cmd)?|bunx|pnpx)$/.test(definition.command) &&
|
|
46
|
-
Array.isArray(definition.args) &&
|
|
47
|
-
definition.args.some((arg) => typeof arg === 'string' && /(?:^|\/)mcp-remote(?:@[^/]*)?$/.test(arg)) &&
|
|
48
|
-
definition.args.some((arg) => typeof arg === 'string' && normalizeUrl(arg) === expectedUrl)) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
async function readServerBinding(path, serverKey) {
|
|
54
|
-
try {
|
|
55
|
-
const parsed = JSON.parse(await readFile(path, 'utf8'));
|
|
56
|
-
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
57
|
-
return undefined;
|
|
58
|
-
const mcpServers = parsed.mcpServers;
|
|
59
|
-
if (!mcpServers || typeof mcpServers !== 'object' || Array.isArray(mcpServers)) {
|
|
60
|
-
return undefined;
|
|
61
|
-
}
|
|
62
|
-
if (!Object.prototype.hasOwnProperty.call(mcpServers, serverKey))
|
|
63
|
-
return undefined;
|
|
64
|
-
const definition = mcpServers[serverKey];
|
|
65
|
-
if (!definition || typeof definition !== 'object' || Array.isArray(definition)) {
|
|
66
|
-
return {};
|
|
67
|
-
}
|
|
68
|
-
return definition;
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
async function configuredServerKeyTargetsMnemonik(input, serverKey, expectedUrl) {
|
|
75
|
-
const serverKeys = new Set([serverKey]);
|
|
76
|
-
if (serverKey.startsWith('user-') && serverKey.length > 'user-'.length) {
|
|
77
|
-
// Older Cursor builds exposed their internal `user-<mcp.json key>` id in
|
|
78
|
-
// the command field. Current builds expose the config key itself.
|
|
79
|
-
serverKeys.add(serverKey.slice('user-'.length));
|
|
80
|
-
}
|
|
81
|
-
const roots = new Set([input.cwd, ...(input.workspaceRoots ?? [])]);
|
|
82
|
-
const paths = [...roots].map((root) => join(root, '.cursor', 'mcp.json'));
|
|
83
|
-
paths.push(join(homedir(), '.cursor', 'mcp.json'));
|
|
84
|
-
let found = false;
|
|
85
|
-
for (const path of new Set(paths)) {
|
|
86
|
-
for (const candidateKey of serverKeys) {
|
|
87
|
-
const definition = await readServerBinding(path, candidateKey);
|
|
88
|
-
if (definition === undefined)
|
|
89
|
-
continue;
|
|
90
|
-
found = true;
|
|
91
|
-
// Ambiguous project/user bindings fail closed. Cursor's precedence and
|
|
92
|
-
// payload have regressed more than once; a conflicting shadow key must not
|
|
93
|
-
// authorize forwarding another server's arguments or result.
|
|
94
|
-
if (!definitionTargetsMnemonik(definition, expectedUrl))
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return found;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Prove that a globally observed Cursor MCP event belongs to Mnemonik.
|
|
102
|
-
* A namespace is only a user-configurable server key, not authentication.
|
|
103
|
-
* Without exact event URL/command metadata, that extracted key must be bound
|
|
104
|
-
* to the configured Mnemonik endpoint in Cursor's MCP config. Missing,
|
|
105
|
-
* unreadable, or conflicting bindings fail closed.
|
|
106
|
-
*/
|
|
107
|
-
export async function isMnemonikMcpCall(input) {
|
|
108
|
-
const serverKey = namespacedServerKey(input.tool);
|
|
109
|
-
if (!serverKey && !BARE_MNEMONIK_TOOLS.has(input.tool))
|
|
110
|
-
return false;
|
|
111
|
-
const expectedUrl = expectedMcpUrl(input.hookServer);
|
|
112
|
-
if (!expectedUrl)
|
|
113
|
-
return false;
|
|
114
|
-
// Cursor namespaces tools from a user-configurable server key, not an
|
|
115
|
-
// authenticated identity. When the event supplies stronger server metadata,
|
|
116
|
-
// it must agree even for a namespaced tool. Namespace is a compatibility
|
|
117
|
-
// fallback only for legacy payloads that carry neither field.
|
|
118
|
-
if (input.url !== undefined)
|
|
119
|
-
return normalizeUrl(input.url) === expectedUrl;
|
|
120
|
-
if (input.command) {
|
|
121
|
-
if (normalizeUrl(input.command) === expectedUrl)
|
|
122
|
-
return true;
|
|
123
|
-
return configuredServerKeyTargetsMnemonik(input, input.command, expectedUrl);
|
|
124
|
-
}
|
|
125
|
-
return serverKey ? configuredServerKeyTargetsMnemonik(input, serverKey, expectedUrl) : false;
|
|
126
|
-
}
|
|
127
|
-
//# sourceMappingURL=mcpOwnership.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcpOwnership.js","sourceRoot":"","sources":["../../src/lib/mcpOwnership.ts"],"names":[],"mappings":"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"}
|