Skip to content

Commit 1122b36

Browse files
authored
Merge pull request #117 from SocketDev/anthropic-updates
compatibility with latest @modelcontextprotocol/sdk
2 parents 11071ab + 35fe8cc commit 1122b36

File tree

6 files changed

+156
-37
lines changed

6 files changed

+156
-37
lines changed

index.ts

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,49 +65,53 @@ async function getApiKeyInteractively (): Promise<string> {
6565
// Initialize API key
6666
let SOCKET_API_KEY = process.env['SOCKET_API_KEY'] || ''
6767

68+
// Build headers dynamically to reflect current API key
69+
function buildSocketHeaders (): Record<string, string> {
70+
return {
71+
'user-agent': `socket-mcp/${VERSION}`,
72+
accept: 'application/x-ndjson',
73+
'content-type': 'application/json',
74+
authorization: `Bearer ${SOCKET_API_KEY}`
75+
}
76+
}
77+
6878
// No session management: each HTTP request is handled statelessly
6979

7080
// Create server instance
7181
const server = new McpServer({
7282
name: 'socket',
7383
version: VERSION,
74-
description: 'Socket MCP server',
75-
capabilities: {
76-
resources: {},
77-
tools: {},
78-
streaming: {}
79-
},
8084
})
8185

82-
server.tool(
86+
server.registerTool(
8387
'depscore',
84-
"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).",
8588
{
86-
packages: z.array(z.object({
87-
ecosystem: z.string().describe('The package ecosystem (e.g., npm, pypi)').default('npm'),
88-
depname: z.string().describe('The name of the dependency'),
89-
version: z.string().describe("The version of the dependency, use 'unknown' if not known").default('unknown'),
90-
})).describe('Array of packages to check'),
89+
title: 'Dependency Score Tool',
90+
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).",
91+
inputSchema: z.object({
92+
packages: z.array(z.object({
93+
ecosystem: z.string().describe('The package ecosystem (e.g., npm, pypi)').default('npm'),
94+
depname: z.string().describe('The name of the dependency'),
95+
version: z.string().describe("The version of the dependency, use 'unknown' if not known").default('unknown'),
96+
})).describe('Array of packages to check'),
97+
}),
98+
annotations: {
99+
readOnlyHint: true,
100+
},
91101
},
92102
async ({ packages }) => {
93103
logger.info(`Received request for ${packages.length} packages`)
94104

95-
const SOCKET_HEADERS = {
96-
'user-agent': `socket-mcp/${VERSION}`,
97-
accept: 'application/x-ndjson',
98-
'content-type': 'application/json',
99-
authorization: `Bearer ${SOCKET_API_KEY}`
100-
}
101-
102105
// Build components array for the API request
103106
const components = packages.map(pkg => {
104-
const cleanedVersion = pkg.version.replace(/[\^~]/g, '') // Remove ^ and ~ from version
107+
const cleanedVersion = (pkg.version ?? 'unknown').replace(/[\^~]/g, '') // Remove ^ and ~ from version
108+
const ecosystem = pkg.ecosystem ?? 'npm'
105109
let purl: string
106110
if (cleanedVersion === '1.0.0' || cleanedVersion === 'unknown' || !cleanedVersion) {
107-
purl = `pkg:${pkg.ecosystem}/${pkg.depname}`
111+
purl = `pkg:${ecosystem}/${pkg.depname}`
108112
} else {
109113
logger.info(`Using version ${cleanedVersion} for ${pkg.depname}`)
110-
purl = `pkg:${pkg.ecosystem}/${pkg.depname}@${cleanedVersion}`
114+
purl = `pkg:${ecosystem}/${pkg.depname}@${cleanedVersion}`
111115
}
112116
return { purl }
113117
})
@@ -116,7 +120,7 @@ server.tool(
116120
// Make a POST request to the Socket API with all packages
117121
const response = await fetch(SOCKET_API_URL, {
118122
method: 'POST',
119-
headers: SOCKET_HEADERS,
123+
headers: buildSocketHeaders(),
120124
body: JSON.stringify({ components })
121125
})
122126

@@ -187,6 +191,8 @@ server.tool(
187191
.join(', ')
188192

189193
results.push(`${purl}: ${scoreEntries}`)
194+
} else {
195+
results.push(`${purl}: No score found`)
190196
}
191197
}
192198

manifest.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"manifest_version": "0.1",
2+
"manifest_version": "0.2",
33
"name": "Socket",
4-
"version": "0.0.12",
4+
"version": "0.0.13",
55
"description": "Socket MCP server for scanning dependencies",
66
"long_description": "__Secure your code by default.__\nThe Socket MCP server brings powerful, real-time dependency scanning directly into Claude. Instantly audit packages from npm, PyPI, Cargo, and more—right inside your chats—with zero setup. Built on the Model Context Protocol (MCP), this extension automatically evaluates packages for:\n - Vulnerabilities and malware\n - Supply chain risks\n - Code quality and maintenance\n - License compliance\n\n With a single command, Claude will return detailed security scores (0–100) across five critical dimensions—helping you make informed decisions and avoid risky dependencies before they hit production.",
77
"author": {
@@ -47,6 +47,7 @@
4747
"vibecoding"
4848
],
4949
"license": "MIT",
50+
"privacy_policies": ["https://socket.dev/privacy"],
5051
"repository": {
5152
"type": "git",
5253
"url": "https://github.com/SocketDev/socket-mcp"

mock-client/stdio-client.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ async function main () {
1212
args: ['--experimental-strip-types', serverPath],
1313

1414
env: {
15-
...process.env,
15+
...Object.fromEntries(
16+
Object.entries(process.env).filter(([, value]) => value !== undefined)
17+
) as Record<string, string>,
1618
SOCKET_API_KEY: process.env['SOCKET_API_KEY'] || ''
1719
}
1820
})

package-lock.json

Lines changed: 113 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@socketsecurity/mcp",
3-
"version": "0.0.12",
3+
"version": "0.0.13",
44
"type": "module",
55
"main": "./index.js",
66
"bin": {
@@ -23,6 +23,7 @@
2323
"build-mcpb": "run-s build build-mcpb:*",
2424
"build-mcpb:versions_match": "node --experimental-strip-types scripts/check-versions.ts",
2525
"build-mcpb:validate": "npx mcpb validate ./",
26+
"build-mcpb:ensure-deps": "npm install --production --ignore-scripts",
2627
"build-mcpb:mcpb-pack": "npx mcpb pack ./",
2728
"clean": "./scripts/clean.sh",
2829
"debug-stdio": "node --experimental-strip-types ./mock-client/debug-client.ts",
@@ -33,6 +34,8 @@
3334
},
3435
"keywords": [],
3536
"files": [
37+
"package.json",
38+
"package-lock.json",
3639
"index.js",
3740
"index.d.ts",
3841
"index.d.ts.map",

test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ test('Socket MCP Server', async (t) => {
1414
command: 'node',
1515
args: ['--experimental-strip-types', serverPath],
1616
env: {
17-
...process.env,
17+
...Object.fromEntries(
18+
Object.entries(process.env).filter(([, value]) => value !== undefined)
19+
) as Record<string, string>,
1820
SOCKET_API_KEY: apiKey
1921
}
2022
})

0 commit comments

Comments
 (0)