shellward 0.5.13 → 0.5.15
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/mcp-server.js +25 -39
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/mcp-server.ts +23 -40
package/dist/mcp-server.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
// }
|
|
19
19
|
import { ShellWard } from './core/engine.js';
|
|
20
20
|
import { readFileSync } from 'fs';
|
|
21
|
+
import { createInterface } from 'readline';
|
|
21
22
|
import { fileURLToPath } from 'url';
|
|
22
23
|
import { dirname, join } from 'path';
|
|
23
24
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -220,7 +221,7 @@ function handleRequest(req) {
|
|
|
220
221
|
jsonrpc: '2.0',
|
|
221
222
|
id: id ?? null,
|
|
222
223
|
result: {
|
|
223
|
-
protocolVersion: '
|
|
224
|
+
protocolVersion: '2025-03-26',
|
|
224
225
|
capabilities: { tools: {} },
|
|
225
226
|
serverInfo: {
|
|
226
227
|
name: 'shellward',
|
|
@@ -290,48 +291,33 @@ function handleRequest(req) {
|
|
|
290
291
|
}
|
|
291
292
|
}
|
|
292
293
|
// ===== Stdio Transport =====
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
process.stdin
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const
|
|
303
|
-
const
|
|
304
|
-
if (
|
|
305
|
-
|
|
306
|
-
continue;
|
|
307
|
-
}
|
|
308
|
-
const contentLength = parseInt(lengthMatch[1], 10);
|
|
309
|
-
const bodyStart = headerEnd + 4;
|
|
310
|
-
if (rawBuffer.length < bodyStart + contentLength)
|
|
311
|
-
break;
|
|
312
|
-
const body = rawBuffer.slice(bodyStart, bodyStart + contentLength).toString('utf8');
|
|
313
|
-
rawBuffer = rawBuffer.slice(bodyStart + contentLength);
|
|
314
|
-
try {
|
|
315
|
-
const req = JSON.parse(body);
|
|
316
|
-
const res = handleRequest(req);
|
|
317
|
-
if (res) {
|
|
318
|
-
send(res);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
catch {
|
|
322
|
-
send({
|
|
323
|
-
jsonrpc: '2.0',
|
|
324
|
-
id: null,
|
|
325
|
-
error: { code: -32700, message: 'Parse error' },
|
|
326
|
-
});
|
|
294
|
+
// MCP stdio: newline-delimited JSON-RPC messages (no Content-Length framing).
|
|
295
|
+
// Each message is a single JSON object followed by \n.
|
|
296
|
+
// Messages MUST NOT contain embedded newlines.
|
|
297
|
+
const rl = createInterface({ input: process.stdin, terminal: false });
|
|
298
|
+
rl.on('line', (line) => {
|
|
299
|
+
const trimmed = line.trim();
|
|
300
|
+
if (!trimmed)
|
|
301
|
+
return;
|
|
302
|
+
try {
|
|
303
|
+
const req = JSON.parse(trimmed);
|
|
304
|
+
const res = handleRequest(req);
|
|
305
|
+
if (res) {
|
|
306
|
+
send(res);
|
|
327
307
|
}
|
|
328
308
|
}
|
|
309
|
+
catch {
|
|
310
|
+
send({
|
|
311
|
+
jsonrpc: '2.0',
|
|
312
|
+
id: null,
|
|
313
|
+
error: { code: -32700, message: 'Parse error' },
|
|
314
|
+
});
|
|
315
|
+
}
|
|
329
316
|
});
|
|
330
317
|
function send(msg) {
|
|
331
|
-
|
|
332
|
-
const header = `Content-Length: ${Buffer.byteLength(body)}\r\n\r\n`;
|
|
333
|
-
process.stdout.write(header + body);
|
|
318
|
+
process.stdout.write(JSON.stringify(msg) + '\n');
|
|
334
319
|
}
|
|
335
|
-
|
|
320
|
+
rl.on('close', () => process.exit(0));
|
|
321
|
+
process.stdin.on('error', () => process.exit(1));
|
|
336
322
|
// Log to stderr so it doesn't interfere with stdio protocol
|
|
337
323
|
process.stderr.write(`[ShellWard MCP] Server started (mode: ${guard.config.mode}, locale: ${guard.locale})\n`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shellward",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"mcpName": "io.github.jnMetaCode/shellward",
|
|
5
5
|
"description": "AI agent security & MCP security middleware — prompt injection detection, AI firewall, runtime guardrails & data-loss prevention for LLM tool calls. 8-layer defense against data exfiltration & dangerous commands. Zero dependencies. SDK + OpenClaw plugin. Supports LangChain, AutoGPT, Claude Code, Cursor, OpenAI Agents.",
|
|
6
6
|
"keywords": [
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/jnMetaCode/shellward",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.5.
|
|
9
|
+
"version": "0.5.15",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "shellward",
|
|
14
|
-
"version": "0.5.
|
|
14
|
+
"version": "0.5.15",
|
|
15
15
|
"runtime": "node",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
package/src/mcp-server.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { ShellWard } from './core/engine.js'
|
|
21
21
|
import { readFileSync } from 'fs'
|
|
22
|
+
import { createInterface } from 'readline'
|
|
22
23
|
import { fileURLToPath } from 'url'
|
|
23
24
|
import { dirname, join } from 'path'
|
|
24
25
|
|
|
@@ -254,7 +255,7 @@ function handleRequest(req: JsonRpcRequest): JsonRpcResponse | null {
|
|
|
254
255
|
jsonrpc: '2.0',
|
|
255
256
|
id: id ?? null,
|
|
256
257
|
result: {
|
|
257
|
-
protocolVersion: '
|
|
258
|
+
protocolVersion: '2025-03-26',
|
|
258
259
|
capabilities: { tools: {} },
|
|
259
260
|
serverInfo: {
|
|
260
261
|
name: 'shellward',
|
|
@@ -332,55 +333,37 @@ function handleRequest(req: JsonRpcRequest): JsonRpcResponse | null {
|
|
|
332
333
|
}
|
|
333
334
|
|
|
334
335
|
// ===== Stdio Transport =====
|
|
335
|
-
//
|
|
336
|
-
//
|
|
336
|
+
// MCP stdio: newline-delimited JSON-RPC messages (no Content-Length framing).
|
|
337
|
+
// Each message is a single JSON object followed by \n.
|
|
338
|
+
// Messages MUST NOT contain embedded newlines.
|
|
337
339
|
|
|
338
|
-
|
|
340
|
+
const rl = createInterface({ input: process.stdin, terminal: false })
|
|
339
341
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
+
rl.on('line', (line: string) => {
|
|
343
|
+
const trimmed = line.trim()
|
|
344
|
+
if (!trimmed) return
|
|
342
345
|
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const lengthMatch = header.match(/Content-Length:\s*(\d+)/i)
|
|
349
|
-
if (!lengthMatch) {
|
|
350
|
-
rawBuffer = rawBuffer.slice(headerEnd + 4)
|
|
351
|
-
continue
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const contentLength = parseInt(lengthMatch[1], 10)
|
|
355
|
-
const bodyStart = headerEnd + 4
|
|
356
|
-
if (rawBuffer.length < bodyStart + contentLength) break
|
|
357
|
-
|
|
358
|
-
const body = rawBuffer.slice(bodyStart, bodyStart + contentLength).toString('utf8')
|
|
359
|
-
rawBuffer = rawBuffer.slice(bodyStart + contentLength)
|
|
360
|
-
|
|
361
|
-
try {
|
|
362
|
-
const req = JSON.parse(body) as JsonRpcRequest
|
|
363
|
-
const res = handleRequest(req)
|
|
364
|
-
if (res) {
|
|
365
|
-
send(res)
|
|
366
|
-
}
|
|
367
|
-
} catch {
|
|
368
|
-
send({
|
|
369
|
-
jsonrpc: '2.0',
|
|
370
|
-
id: null,
|
|
371
|
-
error: { code: -32700, message: 'Parse error' },
|
|
372
|
-
})
|
|
346
|
+
try {
|
|
347
|
+
const req = JSON.parse(trimmed) as JsonRpcRequest
|
|
348
|
+
const res = handleRequest(req)
|
|
349
|
+
if (res) {
|
|
350
|
+
send(res)
|
|
373
351
|
}
|
|
352
|
+
} catch {
|
|
353
|
+
send({
|
|
354
|
+
jsonrpc: '2.0',
|
|
355
|
+
id: null,
|
|
356
|
+
error: { code: -32700, message: 'Parse error' },
|
|
357
|
+
})
|
|
374
358
|
}
|
|
375
359
|
})
|
|
376
360
|
|
|
377
361
|
function send(msg: JsonRpcResponse) {
|
|
378
|
-
|
|
379
|
-
const header = `Content-Length: ${Buffer.byteLength(body)}\r\n\r\n`
|
|
380
|
-
process.stdout.write(header + body)
|
|
362
|
+
process.stdout.write(JSON.stringify(msg) + '\n')
|
|
381
363
|
}
|
|
382
364
|
|
|
383
|
-
|
|
365
|
+
rl.on('close', () => process.exit(0))
|
|
366
|
+
process.stdin.on('error', () => process.exit(1))
|
|
384
367
|
|
|
385
368
|
// Log to stderr so it doesn't interfere with stdio protocol
|
|
386
369
|
process.stderr.write(`[ShellWard MCP] Server started (mode: ${guard.config.mode}, locale: ${guard.locale})\n`)
|