@socketsecurity/mcp 0.0.12 → 0.0.14

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/index.js CHANGED
@@ -50,46 +50,50 @@ async function getApiKeyInteractively() {
50
50
  return apiKey;
51
51
  }
52
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
+ }
53
61
  const server = new McpServer({
54
62
  name: 'socket',
55
63
  version: VERSION,
56
- description: 'Socket MCP server',
57
- capabilities: {
58
- resources: {},
59
- tools: {},
60
- streaming: {}
61
- },
62
64
  });
63
- server.tool('depscore', "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).", {
64
- packages: z.array(z.object({
65
- ecosystem: z.string().describe('The package ecosystem (e.g., npm, pypi)').default('npm'),
66
- depname: z.string().describe('The name of the dependency'),
67
- version: z.string().describe("The version of the dependency, use 'unknown' if not known").default('unknown'),
68
- })).describe('Array of packages to check'),
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
+ },
69
78
  }, async ({ packages }) => {
70
79
  logger.info(`Received request for ${packages.length} packages`);
71
- const SOCKET_HEADERS = {
72
- 'user-agent': `socket-mcp/${VERSION}`,
73
- accept: 'application/x-ndjson',
74
- 'content-type': 'application/json',
75
- authorization: `Bearer ${SOCKET_API_KEY}`
76
- };
77
80
  const components = packages.map(pkg => {
78
- const cleanedVersion = pkg.version.replace(/[\^~]/g, '');
81
+ const cleanedVersion = (pkg.version ?? 'unknown').replace(/[\^~]/g, '');
82
+ const ecosystem = pkg.ecosystem ?? 'npm';
79
83
  let purl;
80
84
  if (cleanedVersion === '1.0.0' || cleanedVersion === 'unknown' || !cleanedVersion) {
81
- purl = `pkg:${pkg.ecosystem}/${pkg.depname}`;
85
+ purl = `pkg:${ecosystem}/${pkg.depname}`;
82
86
  }
83
87
  else {
84
88
  logger.info(`Using version ${cleanedVersion} for ${pkg.depname}`);
85
- purl = `pkg:${pkg.ecosystem}/${pkg.depname}@${cleanedVersion}`;
89
+ purl = `pkg:${ecosystem}/${pkg.depname}@${cleanedVersion}`;
86
90
  }
87
91
  return { purl };
88
92
  });
89
93
  try {
90
94
  const response = await fetch(SOCKET_API_URL, {
91
95
  method: 'POST',
92
- headers: SOCKET_HEADERS,
96
+ headers: buildSocketHeaders(),
93
97
  body: JSON.stringify({ components })
94
98
  });
95
99
  const responseText = await response.text();
@@ -154,6 +158,9 @@ server.tool('depscore', "Get the dependency score of packages with the `depscore
154
158
  .join(', ');
155
159
  results.push(`${purl}: ${scoreEntries}`);
156
160
  }
161
+ else {
162
+ results.push(`${purl}: No score found`);
163
+ }
157
164
  }
158
165
  return {
159
166
  content: [
@@ -203,37 +210,6 @@ if (useHttp) {
203
210
  logger.info(`Starting HTTP server on port ${port}`);
204
211
  let httpTransport = null;
205
212
  const httpServer = createServer(async (req, res) => {
206
- const origin = req.headers.origin;
207
- const allowedOrigins = [
208
- 'http://localhost:3000',
209
- 'http://127.0.0.1:3000',
210
- 'https://mcp.socket.dev',
211
- 'https://mcp.socket-staging.dev'
212
- ];
213
- const isValidOrigin = !origin || allowedOrigins.includes(origin);
214
- if (origin && !isValidOrigin) {
215
- logger.warn(`Rejected request from invalid origin: ${origin}`);
216
- res.writeHead(403, { 'Content-Type': 'application/json' });
217
- res.end(JSON.stringify({
218
- jsonrpc: '2.0',
219
- error: { code: -32000, message: 'Forbidden: Invalid origin' },
220
- id: null
221
- }));
222
- return;
223
- }
224
- if (origin && isValidOrigin) {
225
- res.setHeader('Access-Control-Allow-Origin', origin);
226
- }
227
- else {
228
- res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
229
- }
230
- res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
231
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Accept');
232
- if (req.method === 'OPTIONS') {
233
- res.writeHead(200);
234
- res.end();
235
- return;
236
- }
237
213
  let url;
238
214
  try {
239
215
  url = new URL(req.url, `http://localhost:${port}`);
@@ -258,6 +234,32 @@ if (useHttp) {
258
234
  }));
259
235
  return;
260
236
  }
237
+ const origin = req.headers.origin;
238
+ const allowedOrigins = [
239
+ 'http://localhost:3000',
240
+ 'http://127.0.0.1:3000',
241
+ 'https://mcp.socket.dev',
242
+ 'https://mcp.socket-staging.dev'
243
+ ];
244
+ const isValidOrigin = origin && allowedOrigins.includes(origin);
245
+ if (!isValidOrigin) {
246
+ logger.warn(`Rejected request from invalid origin: ${origin}`);
247
+ res.writeHead(403, { 'Content-Type': 'application/json' });
248
+ res.end(JSON.stringify({
249
+ jsonrpc: '2.0',
250
+ error: { code: -32000, message: 'Forbidden: Invalid origin' },
251
+ id: null
252
+ }));
253
+ return;
254
+ }
255
+ res.setHeader('Access-Control-Allow-Origin', origin);
256
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
257
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Accept');
258
+ if (req.method === 'OPTIONS') {
259
+ res.writeHead(200);
260
+ res.end();
261
+ return;
262
+ }
261
263
  if (url.pathname === '/') {
262
264
  if (req.method === 'POST') {
263
265
  let body = '';
@@ -9,7 +9,7 @@ async function main() {
9
9
  command: 'node',
10
10
  args: ['--experimental-strip-types', serverPath],
11
11
  env: {
12
- ...process.env,
12
+ ...Object.fromEntries(Object.entries(process.env).filter(([, value]) => value !== undefined)),
13
13
  SOCKET_API_KEY: process.env['SOCKET_API_KEY'] || ''
14
14
  }
15
15
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socketsecurity/mcp",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -20,10 +20,11 @@
20
20
  "build": "npm run clean && run-s build:*",
21
21
  "build:types": "tsc -p tsconfig.declaration.json",
22
22
  "build:permissions": "chmod +x ./index.js && (chmod +x ./mock-client/*.js 2>/dev/null || true)",
23
- "build-dtx": "run-s build build-dtx:*",
24
- "build-dtx:versions_match": "node --experimental-strip-types scripts/check-versions.ts",
25
- "build-dtx:validate": "npx dxt validate ./",
26
- "build-dtx:dtx-pack": "npx dxt pack ./",
23
+ "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 ./",
26
+ "build-mcpb:ensure-deps": "npm install --production --ignore-scripts",
27
+ "build-mcpb:mcpb-pack": "npx mcpb pack ./",
27
28
  "clean": "./scripts/clean.sh",
28
29
  "debug-stdio": "node --experimental-strip-types ./mock-client/debug-client.ts",
29
30
  "debug-sdk": "node --experimental-strip-types ./mock-client/stdio-client.ts",
@@ -33,6 +34,8 @@
33
34
  },
34
35
  "keywords": [],
35
36
  "files": [
37
+ "package.json",
38
+ "package-lock.json",
36
39
  "index.js",
37
40
  "index.d.ts",
38
41
  "index.d.ts.map",
@@ -46,14 +49,14 @@
46
49
  "url": "https://github.com/SocketDev/socket-mcp"
47
50
  },
48
51
  "dependencies": {
52
+ "@anthropic-ai/mcpb": "^1.1.0",
49
53
  "@modelcontextprotocol/sdk": "^1.18.0",
50
- "pino": "^9.7.0",
54
+ "pino": "^10.0.0",
51
55
  "pino-pretty": "^13.0.0",
52
56
  "semver": "^7.7.2",
53
57
  "zod": "^3.24.4"
54
58
  },
55
59
  "devDependencies": {
56
- "@anthropic-ai/dxt": "^0.2.0",
57
60
  "@types/node": "^24.0.7",
58
61
  "@types/semver": "^7.7.0",
59
62
  "@types/triple-beam": "^1.3.5",