@jmtrin/kevin-mcp 1.4.0 → 1.5.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/dist/server.js +2 -13
- package/dist/tools/read.js +0 -56
- package/dist/tools/write.js +2 -14
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -12,7 +12,7 @@ import { resolveEnv } from "@jmtrin/kevin-core";
|
|
|
12
12
|
import { resolveMcpIdentity, readSettingOverride } from "./identity.js";
|
|
13
13
|
import { createReadTools } from "./tools/read.js";
|
|
14
14
|
import { createWriteTools } from "./tools/write.js";
|
|
15
|
-
const KEVIN_VERSION = "1.
|
|
15
|
+
const KEVIN_VERSION = "1.5.0";
|
|
16
16
|
const { values } = parseArgs({
|
|
17
17
|
options: {
|
|
18
18
|
help: { type: "boolean", default: false },
|
|
@@ -132,18 +132,7 @@ const registry = [
|
|
|
132
132
|
];
|
|
133
133
|
// Register with MCP server
|
|
134
134
|
for (const tool of registry) {
|
|
135
|
-
|
|
136
|
-
// For compatibility, we register with empty zod object via SDK's internal conversion
|
|
137
|
-
// Use any to bypass typing
|
|
138
|
-
server.registerTool(tool.name, { description: tool.description, inputSchema: tool.inputSchema }, async (args) => {
|
|
139
|
-
// Wrap already does metrics; but ping needs manual wrap? Use tool.handler directly with wrapper already applied for read/write tools.
|
|
140
|
-
// For ping, apply wrap
|
|
141
|
-
if (tool.name === "ping") {
|
|
142
|
-
const w = wrap("mcp.read", tool.handler);
|
|
143
|
-
return await w(args);
|
|
144
|
-
}
|
|
145
|
-
return await tool.handler(args).then((r) => ({ content: [{ type: "text", text: JSON.stringify(r) }] }));
|
|
146
|
-
});
|
|
135
|
+
server.registerTool(tool.name, { description: tool.description, inputSchema: tool.inputSchema }, wrap("mcp.read", tool.handler));
|
|
147
136
|
}
|
|
148
137
|
const transport = new StdioServerTransport();
|
|
149
138
|
await server.connect(transport);
|
package/dist/tools/read.js
CHANGED
|
@@ -20,14 +20,6 @@ export function createReadTools(opts) {
|
|
|
20
20
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
21
21
|
if (mismatch)
|
|
22
22
|
return mismatch;
|
|
23
|
-
try {
|
|
24
|
-
metrics.incr("mcp_requests_total", 1);
|
|
25
|
-
}
|
|
26
|
-
catch { }
|
|
27
|
-
try {
|
|
28
|
-
metrics.incr("mcp_reads_served", 1);
|
|
29
|
-
}
|
|
30
|
-
catch { }
|
|
31
23
|
const svc = memService();
|
|
32
24
|
const memories = svc.query({
|
|
33
25
|
text: args.query,
|
|
@@ -50,14 +42,6 @@ export function createReadTools(opts) {
|
|
|
50
42
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
51
43
|
if (mismatch)
|
|
52
44
|
return mismatch;
|
|
53
|
-
try {
|
|
54
|
-
metrics.incr("mcp_requests_total", 1);
|
|
55
|
-
}
|
|
56
|
-
catch { }
|
|
57
|
-
try {
|
|
58
|
-
metrics.incr("mcp_reads_served", 1);
|
|
59
|
-
}
|
|
60
|
-
catch { }
|
|
61
45
|
const svc = memService();
|
|
62
46
|
const mem = svc.getById(args.id);
|
|
63
47
|
if (!mem)
|
|
@@ -73,14 +57,6 @@ export function createReadTools(opts) {
|
|
|
73
57
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
74
58
|
if (mismatch)
|
|
75
59
|
return mismatch;
|
|
76
|
-
try {
|
|
77
|
-
metrics.incr("mcp_requests_total", 1);
|
|
78
|
-
}
|
|
79
|
-
catch { }
|
|
80
|
-
try {
|
|
81
|
-
metrics.incr("mcp_reads_served", 1);
|
|
82
|
-
}
|
|
83
|
-
catch { }
|
|
84
60
|
const svc = memService();
|
|
85
61
|
const memories = svc.getRelevant({
|
|
86
62
|
query: args.query,
|
|
@@ -108,14 +84,6 @@ export function createReadTools(opts) {
|
|
|
108
84
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
109
85
|
if (mismatch)
|
|
110
86
|
return mismatch;
|
|
111
|
-
try {
|
|
112
|
-
metrics.incr("mcp_requests_total", 1);
|
|
113
|
-
}
|
|
114
|
-
catch { }
|
|
115
|
-
try {
|
|
116
|
-
metrics.incr("mcp_reads_served", 1);
|
|
117
|
-
}
|
|
118
|
-
catch { }
|
|
119
87
|
const res = kevinWhy(store, args.query);
|
|
120
88
|
if (!res)
|
|
121
89
|
return { error: "not_found", query: args.query, provenance: buildProvenance(identity) };
|
|
@@ -128,14 +96,6 @@ export function createReadTools(opts) {
|
|
|
128
96
|
inputSchema: {},
|
|
129
97
|
handler: async (args) => {
|
|
130
98
|
// status bypasses mismatch but reports both
|
|
131
|
-
try {
|
|
132
|
-
metrics.incr("mcp_requests_total", 1);
|
|
133
|
-
}
|
|
134
|
-
catch { }
|
|
135
|
-
try {
|
|
136
|
-
metrics.incr("mcp_reads_served", 1);
|
|
137
|
-
}
|
|
138
|
-
catch { }
|
|
139
99
|
const requested = args.repo_id ?? null;
|
|
140
100
|
const mismatch = requested ? assertScope(identity.repoId, requested) : null;
|
|
141
101
|
const memCount = store.prepare("SELECT COUNT(*) as c FROM memories").get().c;
|
|
@@ -174,14 +134,6 @@ export function createReadTools(opts) {
|
|
|
174
134
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
175
135
|
if (mismatch)
|
|
176
136
|
return mismatch;
|
|
177
|
-
try {
|
|
178
|
-
metrics.incr("mcp_requests_total", 1);
|
|
179
|
-
}
|
|
180
|
-
catch { }
|
|
181
|
-
try {
|
|
182
|
-
metrics.incr("mcp_reads_served", 1);
|
|
183
|
-
}
|
|
184
|
-
catch { }
|
|
185
137
|
const svc = memService();
|
|
186
138
|
const memories = svc.getRelevant({ query: args.query, maxTokens: 2500, scope: "all" });
|
|
187
139
|
return { dry_run: true, results: memories.map((m) => ({ id: m.id, type: m.type, scope: m.scope })), provenance: buildProvenance(identity) };
|
|
@@ -195,14 +147,6 @@ export function createReadTools(opts) {
|
|
|
195
147
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
196
148
|
if (mismatch)
|
|
197
149
|
return mismatch;
|
|
198
|
-
try {
|
|
199
|
-
metrics.incr("mcp_requests_total", 1);
|
|
200
|
-
}
|
|
201
|
-
catch { }
|
|
202
|
-
try {
|
|
203
|
-
metrics.incr("mcp_reads_served", 1);
|
|
204
|
-
}
|
|
205
|
-
catch { }
|
|
206
150
|
const fb = new Feedback(store, metrics);
|
|
207
151
|
try {
|
|
208
152
|
const id = fb.record({ memoryId: args.id, verdict: args.verdict, sessionId: `mcp:${Date.now()}` });
|
package/dist/tools/write.js
CHANGED
|
@@ -31,10 +31,6 @@ export function createWriteTools(opts) {
|
|
|
31
31
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
32
32
|
if (mismatch)
|
|
33
33
|
return mismatch;
|
|
34
|
-
try {
|
|
35
|
-
metrics.incr("mcp_requests_total", 1);
|
|
36
|
-
}
|
|
37
|
-
catch { }
|
|
38
34
|
if (!isWriteEnabled()) {
|
|
39
35
|
try {
|
|
40
36
|
metrics.incr("mcp_writes_refused", 1);
|
|
@@ -44,7 +40,7 @@ export function createWriteTools(opts) {
|
|
|
44
40
|
}
|
|
45
41
|
const svc = new MemoryService(store, metrics, identity.repoId);
|
|
46
42
|
try {
|
|
47
|
-
const
|
|
43
|
+
const id = svc.save({
|
|
48
44
|
type: args.type,
|
|
49
45
|
content: args.content,
|
|
50
46
|
scope: args.scope ?? "project",
|
|
@@ -53,7 +49,7 @@ export function createWriteTools(opts) {
|
|
|
53
49
|
metrics.incr("mcp_writes_accepted", 1);
|
|
54
50
|
}
|
|
55
51
|
catch { }
|
|
56
|
-
return { id
|
|
52
|
+
return { id, provenance: buildProvenance(identity) };
|
|
57
53
|
}
|
|
58
54
|
catch (e) {
|
|
59
55
|
try {
|
|
@@ -72,10 +68,6 @@ export function createWriteTools(opts) {
|
|
|
72
68
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
73
69
|
if (mismatch)
|
|
74
70
|
return mismatch;
|
|
75
|
-
try {
|
|
76
|
-
metrics.incr("mcp_requests_total", 1);
|
|
77
|
-
}
|
|
78
|
-
catch { }
|
|
79
71
|
if (!isWriteEnabled() || !isApproveEnabled()) {
|
|
80
72
|
try {
|
|
81
73
|
metrics.incr("mcp_writes_refused", 1);
|
|
@@ -111,10 +103,6 @@ export function createWriteTools(opts) {
|
|
|
111
103
|
const mismatch = assertScope(identity.repoId, args.repo_id);
|
|
112
104
|
if (mismatch)
|
|
113
105
|
return mismatch;
|
|
114
|
-
try {
|
|
115
|
-
metrics.incr("mcp_requests_total", 1);
|
|
116
|
-
}
|
|
117
|
-
catch { }
|
|
118
106
|
if (!isWriteEnabled() || !isApproveEnabled()) {
|
|
119
107
|
try {
|
|
120
108
|
metrics.incr("mcp_writes_refused", 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmtrin/kevin-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Kevin MCP — stdio bridge for any MCP harness (Bridge)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"prepublishOnly": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@jmtrin/kevin-core": "1.
|
|
26
|
+
"@jmtrin/kevin-core": "1.5.0",
|
|
27
27
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
28
28
|
"zod": "^3.25.0"
|
|
29
29
|
},
|