@socketsecurity/mcp 0.0.16 → 0.0.18

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/package.json CHANGED
@@ -1,68 +1,103 @@
1
1
  {
2
2
  "name": "@socketsecurity/mcp",
3
- "version": "0.0.16",
4
- "type": "module",
5
- "main": "./index.js",
3
+ "version": "0.0.18",
4
+ "description": "Socket MCP server for scanning dependencies",
5
+ "keywords": [],
6
+ "author": "Alexandros Kapravelos",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/SocketDev/socket-mcp"
10
+ },
6
11
  "bin": {
7
- "socket-mcp": "./index.js"
12
+ "socket-mcp": "./dist/index.cjs"
13
+ },
14
+ "files": [
15
+ "CHANGELOG.md",
16
+ "dist/index.cjs",
17
+ "dist/index.d.ts",
18
+ "hooks/socket-gate",
19
+ "package.json"
20
+ ],
21
+ "type": "module",
22
+ "main": "./dist/index.cjs",
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "provenance": true
26
+ },
27
+ "devDependencies": {
28
+ "@anthropic-ai/mcpb": "^1.2.0",
29
+ "@modelcontextprotocol/sdk": "1.26.0",
30
+ "@redwoodjs/agent-ci": "0.16.2",
31
+ "@sinclair/typebox": "0.34.49",
32
+ "@socketregistry/packageurl-js": "1.4.2",
33
+ "@socketregistry/packageurl-js-stable": "npm:@socketregistry/packageurl-js@1.4.2",
34
+ "@socketsecurity/lib": "npm:@socketsecurity/lib@6.0.7",
35
+ "@socketsecurity/lib-stable": "npm:@socketsecurity/lib@6.0.7",
36
+ "@socketsecurity/sdk": "4.0.1",
37
+ "@socketsecurity/sdk-stable": "npm:@socketsecurity/sdk@4.0.1",
38
+ "@types/node": "^24.12.4",
39
+ "@types/shell-quote": "1.7.5",
40
+ "@typescript/native-preview": "7.0.0-dev.20260510.1",
41
+ "@vitest/coverage-v8": "4.1.6",
42
+ "nock": "14.0.15",
43
+ "npm-run-all2": "^8.0.4",
44
+ "oxfmt": "0.48.0",
45
+ "oxlint": "1.63.0",
46
+ "rolldown": "1.0.3",
47
+ "shell-quote": "1.8.4",
48
+ "taze": "19.11.0",
49
+ "untracked": "1.6.1",
50
+ "vitest": "4.1.6"
8
51
  },
9
52
  "engines": {
10
53
  "node": ">=22.0.0",
11
- "npm": ">= 10"
54
+ "npm": ">=11.16.0"
55
+ },
56
+ "allowScripts": {
57
+ "cpu-features": false,
58
+ "esbuild": true,
59
+ "protobufjs": false,
60
+ "ssh2": false
61
+ },
62
+ "npm-run-all2": {
63
+ "nodeRun": true
12
64
  },
13
65
  "scripts": {
14
- "prepublishOnly": "npm run build",
15
- "postpublish": "npm run clean",
16
- "test": "run-s test:*",
17
- "test:lint": "eslint .",
18
- "test:tsc": "tsc",
19
- "test:node-test": "c8 node --experimental-strip-types --test --test-reporter spec",
66
+ "test": "node scripts/fleet/test.mts",
67
+ "test:e2e": "vitest run --config .config/repo/vitest.config.mts test/server.e2e.ts",
68
+ "cover": "node scripts/fleet/cover.mts",
69
+ "test:tsc": "tsgo --noEmit -p tsconfig.json",
70
+ "lint": "node scripts/fleet/lint.mts",
71
+ "lint:all": "node scripts/fleet/lint.mts --all",
72
+ "format": "oxfmt -c .config/fleet/oxfmtrc.json --write .",
73
+ "format:check": "oxfmt -c .config/fleet/oxfmtrc.json --check .",
74
+ "check": "node scripts/fleet/check.mts",
75
+ "check:all": "node scripts/fleet/check.mts --all",
76
+ "fix": "node scripts/fleet/fix.mts",
77
+ "fix:all": "node scripts/fleet/fix.mts --all",
78
+ "update": "node scripts/fleet/update.mts",
20
79
  "build": "npm run clean && run-s build:*",
21
- "build:types": "tsc -p tsconfig.declaration.json",
22
- "build:permissions": "chmod +x ./index.js && (chmod +x ./mock-client/*.js 2>/dev/null || true)",
80
+ "build:bundle": "node scripts/build.mts",
81
+ "build:types": "tsgo -p tsconfig.dts.json",
82
+ "build:permissions": "chmod +x ./dist/index.cjs",
23
83
  "build-mcpb": "run-s build build-mcpb:*",
24
- "build-mcpb:versions_match": "node --experimental-strip-types scripts/check-versions.ts",
25
- "build-mcpb:validate": "npx mcpb validate ./",
84
+ "build-mcpb:versions_match": "node scripts/check-versions.ts",
85
+ "build-mcpb:validate": "mcpb validate ./",
26
86
  "build-mcpb:ensure-deps": "npm install --production --ignore-scripts",
27
- "build-mcpb:mcpb-pack": "npx mcpb pack ./",
28
- "clean": "./scripts/clean.sh",
29
- "debug-stdio": "node --experimental-strip-types ./mock-client/debug-client.ts",
30
- "debug-sdk": "node --experimental-strip-types ./mock-client/stdio-client.ts",
31
- "debug-http": "node --experimental-strip-types ./mock-client/http-client.ts",
32
- "server-stdio": "SOCKET_API_KEY=${SOCKET_API_KEY} node --experimental-strip-types ./index.ts",
33
- "server-http": "MCP_HTTP_MODE=true SOCKET_API_KEY=${SOCKET_API_KEY} node --experimental-strip-types ./index.ts"
34
- },
35
- "keywords": [],
36
- "files": [
37
- "package.json",
38
- "package-lock.json",
39
- "index.js",
40
- "index.d.ts",
41
- "index.d.ts.map",
42
- "mock-client/**/*.js",
43
- "mock-client/**/*.d.ts*"
44
- ],
45
- "author": "Alexandros Kapravelos",
46
- "description": "Socket MCP server for scanning dependencies",
47
- "repository": {
48
- "type": "git",
49
- "url": "https://github.com/SocketDev/socket-mcp"
50
- },
51
- "dependencies": {
52
- "@anthropic-ai/mcpb": "^1.1.0",
53
- "@modelcontextprotocol/sdk": "^1.18.0",
54
- "pino": "^10.0.0",
55
- "pino-pretty": "^13.0.0",
56
- "semver": "^7.7.2",
57
- "zod": "^3.24.4"
58
- },
59
- "devDependencies": {
60
- "@types/node": "^24.0.7",
61
- "@types/semver": "^7.7.0",
62
- "@types/triple-beam": "^1.3.5",
63
- "c8": "^10.0.0",
64
- "neostandard": "^0.12.0",
65
- "npm-run-all2": "^8.0.1",
66
- "typescript": "~5.9.2"
87
+ "build-mcpb:mcpb-pack": "mcpb pack ./",
88
+ "clean": "bash ./scripts/clean.sh",
89
+ "debug-stdio": "node ./mock-client/debug-client.ts",
90
+ "debug-sdk": "node ./mock-client/stdio-client.ts",
91
+ "debug-http": "node ./mock-client/http-client.ts",
92
+ "server-stdio": "SOCKET_API_TOKEN=${SOCKET_API_TOKEN:-${SOCKET_API_KEY}} node ./index.ts",
93
+ "server-stdio:debug": "SOCKET_DEBUG=1 SOCKET_API_TOKEN=${SOCKET_API_TOKEN:-${SOCKET_API_KEY}} node ./index.ts",
94
+ "server-http": "MCP_HTTP_MODE=true SOCKET_API_TOKEN=${SOCKET_API_TOKEN:-${SOCKET_API_KEY}} node ./index.ts",
95
+ "server-http:debug": "SOCKET_DEBUG=1 MCP_HTTP_MODE=true SOCKET_API_TOKEN=${SOCKET_API_TOKEN:-${SOCKET_API_KEY}} node ./index.ts",
96
+ "check:paths": "node scripts/fleet/check-paths.mts",
97
+ "security": "node scripts/fleet/security.mts",
98
+ "setup-security-tools": "node .claude/hooks/fleet/setup-security-tools/install.mts",
99
+ "lockstep": "node scripts/fleet/lockstep.mts",
100
+ "lockstep:emit-schema": "node scripts/fleet/lockstep-emit-schema.mts",
101
+ "ci:local": "agent-ci run --all"
67
102
  }
68
- }
103
+ }
package/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env -S node --experimental-strip-types
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":""}
package/index.js DELETED
@@ -1,353 +0,0 @@
1
- #!/usr/bin/env -S node --experimental-strip-types
2
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
- import { z } from 'zod';
6
- import pino from 'pino';
7
- import readline from 'readline';
8
- import { join } from 'path';
9
- import { readFileSync } from 'fs';
10
- import { tmpdir } from 'os';
11
- import { createServer } from 'http';
12
- const __dirname = import.meta.dirname;
13
- const packageJson = JSON.parse(readFileSync(join(__dirname, './package.json'), 'utf8'));
14
- const VERSION = packageJson.version || '0.0.1';
15
- const logger = pino({
16
- level: 'info',
17
- transport: {
18
- targets: [
19
- {
20
- target: 'pino/file',
21
- options: { destination: join(tmpdir(), 'socket-mcp-error.log') },
22
- level: 'error'
23
- },
24
- {
25
- target: 'pino/file',
26
- options: { destination: join(tmpdir(), 'socket-mcp.log') },
27
- level: 'info'
28
- }
29
- ]
30
- }
31
- });
32
- const SOCKET_API_URL = process.env['SOCKET_DEBUG'] === 'true'
33
- ? 'http://localhost:8866/v0/purl?alerts=false&compact=false&fixable=false&licenseattrib=false&licensedetails=false'
34
- : 'https://api.socket.dev/v0/purl?alerts=false&compact=false&fixable=false&licenseattrib=false&licensedetails=false';
35
- async function getApiKeyInteractively() {
36
- const rl = readline.createInterface({
37
- input: process.stdin,
38
- output: process.stderr
39
- });
40
- const apiKey = await new Promise((resolve) => {
41
- rl.question('Please enter your Socket API key: ', (answer) => {
42
- rl.close();
43
- resolve(answer);
44
- });
45
- });
46
- if (!apiKey) {
47
- logger.error('No API key provided');
48
- process.exit(1);
49
- }
50
- return apiKey;
51
- }
52
- let SOCKET_API_KEY = process.env['SOCKET_API_KEY'] || '';
53
- function buildSocketHeaders() {
54
- return {
55
- 'user-agent': `socket-mcp/${VERSION}`,
56
- accept: 'application/x-ndjson',
57
- 'content-type': 'application/json',
58
- authorization: `Bearer ${SOCKET_API_KEY}`
59
- };
60
- }
61
- const server = new McpServer({
62
- name: 'socket',
63
- version: VERSION,
64
- });
65
- server.registerTool('depscore', {
66
- title: 'Dependency Score Tool',
67
- description: "Get the dependency score of packages with the `depscore` tool from Socket. Use 'unknown' for version if not known. Use this tool to scan dependencies for their quality and security on existing code or when code is generated. Stop generating code and ask the user how to proceed when any of the scores are low. When checking dependencies, make sure to also check the imports in the code, not just the manifest files (pyproject.toml, package.json, etc).",
68
- inputSchema: z.object({
69
- packages: z.array(z.object({
70
- ecosystem: z.string().describe('The package ecosystem (e.g., npm, pypi)').default('npm'),
71
- depname: z.string().describe('The name of the dependency'),
72
- version: z.string().describe("The version of the dependency, use 'unknown' if not known").default('unknown'),
73
- })).describe('Array of packages to check'),
74
- }),
75
- annotations: {
76
- readOnlyHint: true,
77
- },
78
- }, async ({ packages }) => {
79
- logger.info(`Received request for ${packages.length} packages`);
80
- const components = packages.map(pkg => {
81
- const cleanedVersion = (pkg.version ?? 'unknown').replace(/[\^~]/g, '');
82
- const ecosystem = pkg.ecosystem ?? 'npm';
83
- let purl;
84
- if (cleanedVersion === '1.0.0' || cleanedVersion === 'unknown' || !cleanedVersion) {
85
- purl = `pkg:${ecosystem}/${pkg.depname}`;
86
- }
87
- else {
88
- logger.info(`Using version ${cleanedVersion} for ${pkg.depname}`);
89
- purl = `pkg:${ecosystem}/${pkg.depname}@${cleanedVersion}`;
90
- }
91
- return { purl };
92
- });
93
- try {
94
- const response = await fetch(SOCKET_API_URL, {
95
- method: 'POST',
96
- headers: buildSocketHeaders(),
97
- body: JSON.stringify({ components })
98
- });
99
- const responseText = await response.text();
100
- if (response.status !== 200) {
101
- const errorMsg = `Error processing packages: [${response.status}] ${responseText}`;
102
- logger.error(errorMsg);
103
- return {
104
- content: [{ type: 'text', text: errorMsg }],
105
- isError: true
106
- };
107
- }
108
- else if (!responseText.trim()) {
109
- const errorMsg = 'No packages were found.';
110
- logger.error(errorMsg);
111
- return {
112
- content: [{ type: 'text', text: errorMsg }],
113
- isError: true
114
- };
115
- }
116
- try {
117
- const results = [];
118
- if ((response.headers.get('content-type') || '').includes('x-ndjson')) {
119
- const jsonLines = responseText.split('\n')
120
- .filter(line => line.trim())
121
- .map(line => JSON.parse(line));
122
- if (!jsonLines.length) {
123
- const errorMsg = 'No valid JSON objects found in NDJSON response';
124
- return {
125
- content: [{ type: 'text', text: errorMsg }],
126
- isError: true
127
- };
128
- }
129
- for (const jsonData of jsonLines) {
130
- const purl = `pkg:${jsonData.type || 'unknown'}/${jsonData.name || 'unknown'}@${jsonData.version || 'unknown'}`;
131
- if (jsonData.score && jsonData.score.overall !== undefined) {
132
- const scoreEntries = Object.entries(jsonData.score)
133
- .filter(([key]) => key !== 'overall' && key !== 'uuid')
134
- .map(([key, value]) => {
135
- const numValue = Number(value);
136
- const displayValue = numValue <= 1 ? Math.round(numValue * 100) : numValue;
137
- return `${key}: ${displayValue}`;
138
- })
139
- .join(', ');
140
- results.push(`${purl}: ${scoreEntries}`);
141
- }
142
- else {
143
- results.push(`${purl}: No score found`);
144
- }
145
- }
146
- }
147
- else {
148
- const jsonData = JSON.parse(responseText);
149
- const purl = `pkg:${jsonData.type || 'unknown'}/${jsonData.name || 'unknown'}@${jsonData.version || 'unknown'}`;
150
- if (jsonData.score && jsonData.score.overall !== undefined) {
151
- const scoreEntries = Object.entries(jsonData.score)
152
- .filter(([key]) => key !== 'overall' && key !== 'uuid')
153
- .map(([key, value]) => {
154
- const numValue = Number(value);
155
- const displayValue = numValue <= 1 ? Math.round(numValue * 100) : numValue;
156
- return `${key}: ${displayValue}`;
157
- })
158
- .join(', ');
159
- results.push(`${purl}: ${scoreEntries}`);
160
- }
161
- else {
162
- results.push(`${purl}: No score found`);
163
- }
164
- }
165
- return {
166
- content: [
167
- {
168
- type: 'text',
169
- text: results.length > 0
170
- ? `Dependency scores:\n${results.join('\n')}`
171
- : 'No scores found for the provided packages'
172
- }
173
- ]
174
- };
175
- }
176
- catch (e) {
177
- const error = e;
178
- const errorMsg = `JSON parsing error: ${error.message} -- Response: ${responseText}`;
179
- logger.error(errorMsg);
180
- return {
181
- content: [{ type: 'text', text: 'Error parsing response from Socket API' }],
182
- isError: true
183
- };
184
- }
185
- }
186
- catch (e) {
187
- const error = e;
188
- const errorMsg = `Error processing packages: ${error.message}`;
189
- logger.error(errorMsg);
190
- return {
191
- content: [{ type: 'text', text: 'Error connecting to Socket API' }],
192
- isError: true
193
- };
194
- }
195
- });
196
- const useHttp = process.env['MCP_HTTP_MODE'] === 'true' || process.argv.includes('--http');
197
- const port = parseInt(process.env['MCP_PORT'] || '3000', 10);
198
- if (!SOCKET_API_KEY) {
199
- if (useHttp) {
200
- logger.error('SOCKET_API_KEY environment variable is not set');
201
- SOCKET_API_KEY = await getApiKeyInteractively();
202
- }
203
- else {
204
- logger.error('SOCKET_API_KEY environment variable is required in stdio mode');
205
- logger.error('Please set the SOCKET_API_KEY environment variable and try again');
206
- process.exit(1);
207
- }
208
- }
209
- if (useHttp) {
210
- logger.info(`Starting HTTP server on port ${port}`);
211
- let httpTransport = null;
212
- const httpServer = createServer(async (req, res) => {
213
- let url;
214
- try {
215
- url = new URL(req.url, `http://localhost:${port}`);
216
- }
217
- catch (error) {
218
- logger.warn(`Invalid URL in request: ${req.url} - ${error}`);
219
- res.writeHead(400, { 'Content-Type': 'application/json' });
220
- res.end(JSON.stringify({
221
- jsonrpc: '2.0',
222
- error: { code: -32000, message: 'Bad Request: Invalid URL' },
223
- id: null
224
- }));
225
- return;
226
- }
227
- if (url.pathname === '/health') {
228
- res.writeHead(200, { 'Content-Type': 'application/json' });
229
- res.end(JSON.stringify({
230
- status: 'healthy',
231
- service: 'socket-mcp',
232
- version: VERSION,
233
- timestamp: new Date().toISOString()
234
- }));
235
- return;
236
- }
237
- const origin = req.headers.origin;
238
- const isLocalhostOrigin = (originUrl) => {
239
- try {
240
- const url = new URL(originUrl);
241
- return url.hostname === 'localhost' || url.hostname === '127.0.0.1';
242
- }
243
- catch {
244
- return false;
245
- }
246
- };
247
- const allowedOrigins = [
248
- 'https://mcp.socket.dev',
249
- 'https://mcp.socket-staging.dev'
250
- ];
251
- const host = req.headers.host || '';
252
- const allowedHosts = allowedOrigins.map(o => new URL(o).hostname);
253
- const isAllowedHost = host === `localhost:${port}` ||
254
- host === `127.0.0.1:${port}` ||
255
- host === 'localhost' ||
256
- host === '127.0.0.1' ||
257
- allowedHosts.includes(host);
258
- const isValidOrigin = origin
259
- ? (isLocalhostOrigin(origin) || allowedOrigins.includes(origin))
260
- : isAllowedHost;
261
- if (!isValidOrigin) {
262
- logger.warn(`Rejected request from invalid origin: ${origin || 'missing'} (host: ${host})`);
263
- res.writeHead(403, { 'Content-Type': 'application/json' });
264
- res.end(JSON.stringify({
265
- jsonrpc: '2.0',
266
- error: { code: -32000, message: 'Forbidden: Invalid origin' },
267
- id: null
268
- }));
269
- return;
270
- }
271
- if (origin) {
272
- res.setHeader('Access-Control-Allow-Origin', origin);
273
- res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
274
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Accept');
275
- }
276
- if (req.method === 'OPTIONS') {
277
- res.writeHead(200);
278
- res.end();
279
- return;
280
- }
281
- if (url.pathname === '/') {
282
- if (req.method === 'POST') {
283
- let body = '';
284
- req.on('data', chunk => (body += chunk));
285
- req.on('end', async () => {
286
- try {
287
- const jsonData = JSON.parse(body);
288
- if (jsonData && jsonData.method === 'initialize') {
289
- const clientInfo = jsonData.params?.clientInfo;
290
- logger.info(`Client connected: ${clientInfo?.name || 'unknown'} v${clientInfo?.version || 'unknown'} from ${origin || host}`);
291
- if (httpTransport) {
292
- try {
293
- httpTransport.close();
294
- }
295
- catch { }
296
- }
297
- httpTransport = new StreamableHTTPServerTransport({
298
- sessionIdGenerator: undefined,
299
- enableJsonResponse: true
300
- });
301
- await server.connect(httpTransport);
302
- await httpTransport.handleRequest(req, res, jsonData);
303
- return;
304
- }
305
- if (!httpTransport) {
306
- httpTransport = new StreamableHTTPServerTransport({
307
- sessionIdGenerator: undefined,
308
- enableJsonResponse: true
309
- });
310
- await server.connect(httpTransport);
311
- }
312
- await httpTransport.handleRequest(req, res, jsonData);
313
- }
314
- catch (error) {
315
- logger.error(`Error processing POST request: ${error}`);
316
- if (!res.headersSent) {
317
- res.writeHead(500);
318
- res.end(JSON.stringify({
319
- jsonrpc: '2.0',
320
- error: { code: -32603, message: 'Internal server error' },
321
- id: null
322
- }));
323
- }
324
- }
325
- });
326
- }
327
- else {
328
- res.writeHead(405);
329
- res.end('Method not allowed');
330
- }
331
- }
332
- else {
333
- res.writeHead(404);
334
- res.end('Not found');
335
- }
336
- });
337
- httpServer.listen(port, () => {
338
- logger.info(`Socket MCP HTTP server version ${VERSION} started successfully on port ${port}`);
339
- logger.info(`Connect to: http://localhost:${port}/`);
340
- });
341
- }
342
- else {
343
- logger.info('Starting in stdio mode');
344
- const transport = new StdioServerTransport();
345
- server.connect(transport)
346
- .then(() => {
347
- logger.info(`Socket MCP server version ${VERSION} started successfully`);
348
- })
349
- .catch((error) => {
350
- logger.error(`Failed to start Socket MCP server: ${error.message}`);
351
- process.exit(1);
352
- });
353
- }
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node --experimental-strip-types
2
- export {};
3
- //# sourceMappingURL=debug-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"debug-client.d.ts","sourceRoot":"","sources":["debug-client.ts"],"names":[],"mappings":""}
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env node --experimental-strip-types
2
- import { spawn } from 'child_process';
3
- import readline from 'readline';
4
- import { join } from 'path';
5
- class SimpleJSONRPCClient {
6
- process;
7
- rl;
8
- requestId = 1;
9
- pendingRequests = new Map();
10
- constructor(command, args = [], env = {}) {
11
- this.process = spawn(command, args, {
12
- stdio: ['pipe', 'pipe', 'pipe'],
13
- env: { ...process.env, ...env }
14
- });
15
- this.rl = readline.createInterface({
16
- input: this.process.stdout,
17
- crlfDelay: Infinity
18
- });
19
- this.rl.on('line', (line) => {
20
- try {
21
- const response = JSON.parse(line);
22
- if (response.id && this.pendingRequests.has(response.id)) {
23
- const { resolve, reject } = this.pendingRequests.get(response.id);
24
- this.pendingRequests.delete(response.id);
25
- if (response.error) {
26
- reject(response.error);
27
- }
28
- else {
29
- resolve(response.result);
30
- }
31
- }
32
- else if (response.method) {
33
- console.log('Notification:', response);
34
- }
35
- }
36
- catch (e) {
37
- console.error('Failed to parse response:', line);
38
- }
39
- });
40
- this.process.stderr.on('data', (data) => {
41
- console.error('Server stderr:', data.toString());
42
- });
43
- }
44
- async sendRequest(method, params = {}) {
45
- const id = this.requestId++;
46
- const request = {
47
- jsonrpc: '2.0',
48
- id,
49
- method,
50
- params
51
- };
52
- return new Promise((resolve, reject) => {
53
- this.pendingRequests.set(id, { resolve, reject });
54
- this.process.stdin.write(JSON.stringify(request) + '\n');
55
- });
56
- }
57
- close() {
58
- this.rl.close();
59
- this.process.kill();
60
- }
61
- }
62
- async function main() {
63
- const apiKey = process.env['SOCKET_API_KEY'];
64
- if (!apiKey) {
65
- console.error('Error: SOCKET_API_KEY environment variable is required');
66
- process.exit(1);
67
- }
68
- console.log('Starting MCP server debug client...');
69
- const serverPath = join(import.meta.dirname, '..', 'index.ts');
70
- console.log(`Using server script: ${serverPath}`);
71
- const client = new SimpleJSONRPCClient('node', ['--experimental-strip-types', serverPath], {
72
- SOCKET_API_KEY: apiKey
73
- });
74
- try {
75
- console.log('\n1. Initializing connection...');
76
- const initResult = await client.sendRequest('initialize', {
77
- protocolVersion: '0.1.0',
78
- capabilities: {},
79
- clientInfo: {
80
- name: 'debug-client',
81
- version: '1.0.0'
82
- }
83
- });
84
- console.log('Initialize response:', JSON.stringify(initResult, null, 2));
85
- console.log('\n2. Listing available tools...');
86
- const toolsResult = await client.sendRequest('tools/list', {});
87
- console.log('Available tools:', JSON.stringify(toolsResult, null, 2));
88
- console.log('\n3. Calling depscore tool...');
89
- const depscoreResult = await client.sendRequest('tools/call', {
90
- name: 'depscore',
91
- arguments: {
92
- packages: [
93
- { depname: 'express', ecosystem: 'npm', version: '5.0.1' },
94
- { depname: 'lodash', ecosystem: 'npm', version: '4.17.21' },
95
- { depname: 'react', ecosystem: 'npm', version: '18.2.0' },
96
- { depname: 'flask', ecosystem: 'pypi', version: '2.3.2' },
97
- { depname: 'unknown-package', ecosystem: 'npm', version: 'unknown' }
98
- ]
99
- }
100
- });
101
- console.log('Depscore result:', JSON.stringify(depscoreResult, null, 2));
102
- console.log('\n4. Testing with minimal input (default to npm)...');
103
- const minimalResult = await client.sendRequest('tools/call', {
104
- name: 'depscore',
105
- arguments: {
106
- packages: [
107
- { depname: 'axios' },
108
- { depname: 'typescript' }
109
- ]
110
- }
111
- });
112
- console.log('Minimal input result:', JSON.stringify(minimalResult, null, 2));
113
- console.log('\n5. Testing error handling (empty packages)...');
114
- try {
115
- await client.sendRequest('tools/call', {
116
- name: 'depscore',
117
- arguments: {
118
- packages: []
119
- }
120
- });
121
- }
122
- catch (error) {
123
- console.log('Expected error:', error);
124
- }
125
- console.log('\nDebug session complete!');
126
- }
127
- catch (error) {
128
- console.error('Client error:', error);
129
- }
130
- finally {
131
- client.close();
132
- }
133
- }
134
- main().catch(console.error);
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node --experimental-strip-types
2
- export {};
3
- //# sourceMappingURL=http-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["http-client.ts"],"names":[],"mappings":""}