@jrooig/mcpshield 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.
@@ -0,0 +1,97 @@
1
+ /**
2
+ * JSON-RPC 2.0 & Model Context Protocol (MCP) type definitions.
3
+ *
4
+ * These types model the wire format that MCP-Shield intercepts on stdio:
5
+ * every packet exchanged between an MCP client (e.g. Claude Code) and an
6
+ * MCP server is a JSON-RPC 2.0 message, and MCP layers its own methods
7
+ * (`initialize`, `tools/call`, `resources/read`, ...) on top of it.
8
+ */
9
+ // ---------------------------------------------------------------------------
10
+ // JSON-RPC 2.0 base protocol
11
+ // ---------------------------------------------------------------------------
12
+ export const JSONRPC_VERSION = '2.0';
13
+ /** Standard JSON-RPC 2.0 error codes, plus the code MCP-Shield uses for policy denials. */
14
+ export const JsonRpcErrorCode = {
15
+ ParseError: -32700,
16
+ InvalidRequest: -32600,
17
+ MethodNotFound: -32601,
18
+ InvalidParams: -32602,
19
+ InternalError: -32603,
20
+ /** MCP-Shield policy denial. The spec reserves -32000..-32099 for implementation-defined server errors. */
21
+ AccessDenied: -32003,
22
+ };
23
+ // ---------------------------------------------------------------------------
24
+ // MCP protocol layer
25
+ // ---------------------------------------------------------------------------
26
+ /** MCP methods relevant to interception. Servers may expose more; the firewall matches on these. */
27
+ export const McpMethod = {
28
+ Initialize: 'initialize',
29
+ Initialized: 'notifications/initialized',
30
+ ToolsList: 'tools/list',
31
+ ToolsCall: 'tools/call',
32
+ ResourcesList: 'resources/list',
33
+ ResourcesRead: 'resources/read',
34
+ PromptsList: 'prompts/list',
35
+ PromptsGet: 'prompts/get',
36
+ Ping: 'ping',
37
+ };
38
+ // ---------------------------------------------------------------------------
39
+ // Type guards — parsing untrusted stdio input safely
40
+ // ---------------------------------------------------------------------------
41
+ function isRecord(value) {
42
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
43
+ }
44
+ export function isJsonRpcMessage(value) {
45
+ return isRecord(value) && value['jsonrpc'] === JSONRPC_VERSION;
46
+ }
47
+ export function isJsonRpcRequest(value) {
48
+ return (isJsonRpcMessage(value) &&
49
+ 'method' in value &&
50
+ typeof value.method === 'string' &&
51
+ 'id' in value &&
52
+ (value.id === null ||
53
+ typeof value.id === 'string' ||
54
+ typeof value.id === 'number'));
55
+ }
56
+ export function isJsonRpcNotification(value) {
57
+ return (isJsonRpcMessage(value) &&
58
+ 'method' in value &&
59
+ typeof value.method === 'string' &&
60
+ !('id' in value));
61
+ }
62
+ export function isJsonRpcResponse(value) {
63
+ return isJsonRpcMessage(value) && !('method' in value) && ('result' in value || 'error' in value);
64
+ }
65
+ export function isJsonRpcErrorResponse(value) {
66
+ return isJsonRpcResponse(value) && 'error' in value;
67
+ }
68
+ /** Narrow an intercepted packet down to the tool invocation the firewall must judge. */
69
+ export function isToolCallRequest(value) {
70
+ return (isJsonRpcRequest(value) &&
71
+ value.method === McpMethod.ToolsCall &&
72
+ isRecord(value.params) &&
73
+ typeof value.params['name'] === 'string');
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // Response factories
77
+ // ---------------------------------------------------------------------------
78
+ /** Build the error response MCP-Shield returns to the client when a request is blocked by policy. */
79
+ export function createAccessDeniedResponse(id, ruleName) {
80
+ return {
81
+ jsonrpc: JSONRPC_VERSION,
82
+ id,
83
+ error: {
84
+ code: JsonRpcErrorCode.AccessDenied,
85
+ message: 'Access Denied by Policy',
86
+ data: ruleName ? { rule: ruleName } : undefined,
87
+ },
88
+ };
89
+ }
90
+ export function createErrorResponse(id, code, message, data) {
91
+ return {
92
+ jsonrpc: JSONRPC_VERSION,
93
+ id,
94
+ error: { code, message, data },
95
+ };
96
+ }
97
+ //# sourceMappingURL=mcp.js.map
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@jrooig/mcpshield",
3
+ "publishConfig": { "access": "public" },
4
+ "version": "0.1.0",
5
+ "description": "Zero-trust security proxy and runtime firewall for MCP agents. Intercepts JSON-RPC 2.0 over stdio between MCP clients and servers.",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "bin": {
9
+ "mcp-shield": "dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "prepublishOnly": "npm run build",
14
+ "build:bin": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=cjs --outfile=dist/bundle.cjs && pkg dist/bundle.cjs --targets node18-win-x64,node18-macos-x64,node18-linux-x64 --out-path bin/",
15
+ "typecheck": "tsc --noEmit",
16
+ "test": "npm run build && node --test --test-force-exit \"tests/*.test.mjs\"",
17
+ "start": "node dist/index.js",
18
+ "dev": "node --loader ts-node/esm src/index.ts"
19
+ },
20
+ "keywords": [
21
+ "mcp",
22
+ "model-context-protocol",
23
+ "security",
24
+ "firewall",
25
+ "proxy",
26
+ "json-rpc"
27
+ ],
28
+ "license": "MIT",
29
+ "repository": { "type": "git", "url": "git+https://github.com/jaumerohi2007-cell/mcp-shield.git" },
30
+ "homepage": "https://mcp-shield.dev",
31
+ "bugs": { "url": "https://github.com/jaumerohi2007-cell/mcp-shield/issues" },
32
+ "files": ["dist/**/*.js", "dist/**/*.d.ts", "README.md"],
33
+ "engines": {
34
+ "node": ">=18"
35
+ },
36
+ "dependencies": {
37
+ "@modelcontextprotocol/sdk": "^1.29.0",
38
+ "express": "^5.2.1",
39
+ "socket.io": "^4.8.3"
40
+ },
41
+ "devDependencies": {
42
+ "@types/express": "^5.0.6",
43
+ "@types/node": "^26.1.0",
44
+ "esbuild": "^0.28.1",
45
+ "jsdom": "^29.1.1",
46
+ "pkg": "^5.8.1",
47
+ "socket.io-client": "^4.8.3",
48
+ "ts-node": "^10.9.2",
49
+ "typescript": "^6.0.3"
50
+ }
51
+ }