@socketsecurity/mcp 0.2.1 โ 0.3.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.
- package/README.md +84 -443
- package/dist/index.cjs +17610 -9575
- package/dist/socket-gate/socket-gate.cjs +325 -248
- package/package.json +262 -185
package/README.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# Socket MCP Server
|
|
2
2
|
|
|
3
|
-
<a href="https://socket.dev/npm/package/@socketsecurity/mcp"><img src="https://socket.dev/
|
|
4
|
-
<picture><img src="https://raw.githubusercontent.com/SocketDev/socket-mcp/
|
|
3
|
+
<a href="https://socket.dev/npm/package/@socketsecurity/mcp"><img src="https://badge.socket.dev/npm/package/@socketsecurity/mcp" alt="Socket Badge" height="20"></a>
|
|
4
|
+
<picture><img src="https://raw.githubusercontent.com/SocketDev/socket-mcp/HEAD/assets/repo/coverage.svg?v=d3f1fd881dda" height="20" alt="Coverage" /></picture>
|
|
5
5
|
|
|
6
6
|
[](https://twitter.com/SocketSecurity)
|
|
7
7
|
[](https://bsky.app/profile/socket.dev)
|
|
8
8
|
|
|
9
9
|
Socket MCP lets AI assistants query Socket's dependency security scores and metadata through the Model Context Protocol (MCP).
|
|
10
10
|
Use it to score a package, audit a `package.json`, or identify risky dependencies in a conversation.
|
|
11
|
-
Connect your MCP client to the hosted server at `https://mcp.socket.dev
|
|
11
|
+
Connect your MCP client to the hosted server at `https://mcp.socket.dev/` and authenticate through OAuth, or run the npm package yourself.
|
|
12
12
|
|
|
13
13
|
## โจ Features
|
|
14
14
|
|
|
15
15
|
- ๐ **Dependency Security Scanning** - Get comprehensive security scores for npm, PyPI, cargo, Maven, NuGet, RubyGems, Go Modules, and more ([supported ecosystems](https://docs.socket.dev/docs/language-support))
|
|
16
|
-
- ๐ **Public Hosted Service** - Use our public server at `https://mcp.socket.dev
|
|
16
|
+
- ๐ **Public Hosted Service** - Use our public server at `https://mcp.socket.dev/` and sign in through your MCP client's OAuth flow
|
|
17
17
|
- ๐ **Multiple Deployment Options** - Run locally via stdio, HTTP, or use our service
|
|
18
|
-
- ๐ค **AI Assistant Integration** -
|
|
18
|
+
- ๐ค **AI Assistant Integration** - Connect from MCP-compatible clients; OAuth behavior varies by client
|
|
19
19
|
- ๐ **Batch Processing** - Check multiple dependencies in a single request
|
|
20
20
|
- ๐ **OAuth Sign-In** - Public server authenticates through your MCP client's OAuth flow; no API key to copy or manage
|
|
21
21
|
|
|
@@ -25,7 +25,7 @@ Connect your MCP client to the hosted server at `https://mcp.socket.dev/`, or ru
|
|
|
25
25
|
|
|
26
26
|
### Option 1: Use the public Socket MCP server (recommended)
|
|
27
27
|
|
|
28
|
-
The public server
|
|
28
|
+
The public server requires Socket sign-in through OAuth for every tool call, including package scoring. Some MCP clients need an explicit sign-in step. You do not need an API key.
|
|
29
29
|
|
|
30
30
|
- [Install in VS Code](https://vscode.dev/redirect/mcp/install?name=socket-mcp&config=%7B%22url%22%3A%22https%3A%2F%2Fmcp.socket.dev%2F%22%2C%22type%22%3A%22http%22%7D).
|
|
31
31
|
- [Install in Cursor](https://cursor.com/en/install-mcp?name=socket-mcp&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vbWNwLnNvY2tldC5kZXYvIn0%3D).
|
|
@@ -39,12 +39,42 @@ Add the hosted server through Claude's [custom connector settings](https://suppo
|
|
|
39
39
|
3. Select **Connect** and complete the Socket authorization flow when prompted.
|
|
40
40
|
4. Enable the connector for your conversation, then ask Claude "Check the security score for express version 4.18.2".
|
|
41
41
|
|
|
42
|
-
For Claude Code,
|
|
42
|
+
For Claude Code, add the server:
|
|
43
43
|
|
|
44
44
|
```sh
|
|
45
45
|
claude mcp add --transport http socket-mcp https://mcp.socket.dev/
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
Then run `/mcp`, select `socket-mcp`, choose **Authenticate** (or **Re-authenticate**, if shown), and approve access in your browser. An "authenticated" status before sign-in does not mean organization tools are ready.
|
|
49
|
+
|
|
50
|
+
</details>
|
|
51
|
+
|
|
52
|
+
<details><summary><b>Manual install - Codex CLI</b></summary>
|
|
53
|
+
|
|
54
|
+
Add the server:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
codex mcp add socket-mcp --url https://mcp.socket.dev/
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Codex starts sign-in during this command. You may see an `invalid_scope` page before Codex automatically retries with the three MCP read permissions. Complete the browser authorization on the retry.
|
|
61
|
+
|
|
62
|
+
To avoid that initial error page, you can instead add the server directly to `~/.codex/config.toml`:
|
|
63
|
+
|
|
64
|
+
```toml
|
|
65
|
+
[mcp_servers.socket-mcp]
|
|
66
|
+
url = "https://mcp.socket.dev/"
|
|
67
|
+
scopes = ["packages:list", "alerts:list", "threat-feed:list"]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then run:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
codex mcp login socket-mcp
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
With dynamic client registration, each sign-in creates a new OAuth client with Socket.
|
|
77
|
+
|
|
48
78
|
</details>
|
|
49
79
|
|
|
50
80
|
<details><summary><b>Manual install - VS Code</b></summary>
|
|
@@ -143,155 +173,7 @@ Reuse saved authorization while it remains valid. If a browser reports connectio
|
|
|
143
173
|
|
|
144
174
|
### Option 2: Self-host the Socket MCP server
|
|
145
175
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
**Get a token first.** Sign in at [socket.dev](https://socket.dev/), open the API tokens page, and create a token with the `packages:list` scope. That single scope covers `depscore`; the org-scoped tools need whatever scopes your organization requires for the endpoints they call. Full walkthrough: [creating and managing API tokens](https://docs.socket.dev/reference/creating-and-managing-api-tokens).
|
|
149
|
-
|
|
150
|
-
**Then pick a transport.** The server speaks the same MCP protocol either way; the difference is who launches it.
|
|
151
|
-
|
|
152
|
-
| | Stdio (Option 2a) | HTTP (Option 2b) |
|
|
153
|
-
| ---------------------- | --------------------------------------------- | -------------------------------------------------------------------- |
|
|
154
|
-
| Who starts the process | Your MCP client, on demand | You, as a long-running service |
|
|
155
|
-
| Who it serves | One local user | Any client that can reach the port |
|
|
156
|
-
| Where the token lives | The client's config, as an env var | The server env, or per-request `Authorization` headers |
|
|
157
|
-
| Reach for it when | You are a developer wiring up your own editor | You are deploying one instance for a team, or fronting it with OAuth |
|
|
158
|
-
|
|
159
|
-
Stdio is the default and the right answer for a single developer. Choose HTTP when more than one person, or something that is not a local process, needs to reach the server.
|
|
160
|
-
|
|
161
|
-
Install it once, globally, before either option:
|
|
162
|
-
|
|
163
|
-
```sh
|
|
164
|
-
pnpm add -g @socketsecurity/mcp
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
<details><summary><b>Option 2a - Stdio mode (default)</b></summary>
|
|
168
|
-
|
|
169
|
-
Claude Code:
|
|
170
|
-
|
|
171
|
-
```sh
|
|
172
|
-
claude mcp add socket-mcp -e SOCKET_API_TOKEN="your-api-token-here" -- socket-mcp
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Most other MCP clients:
|
|
176
|
-
|
|
177
|
-
```json
|
|
178
|
-
{
|
|
179
|
-
"mcpServers": {
|
|
180
|
-
"socket-mcp": {
|
|
181
|
-
"command": "socket-mcp",
|
|
182
|
-
"env": {
|
|
183
|
-
"SOCKET_API_TOKEN": "your-api-token-here"
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
</details>
|
|
191
|
-
|
|
192
|
-
<details><summary><b>Option 2b - HTTP mode</b></summary>
|
|
193
|
-
|
|
194
|
-
Run the server in HTTP mode:
|
|
195
|
-
|
|
196
|
-
```sh
|
|
197
|
-
MCP_HTTP_MODE=true SOCKET_API_TOKEN=your-api-token socket-mcp --http
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
The server listens on `http://localhost:3000/`. The MCP endpoint is `/` and the health endpoint is `/health`; every other path answers `404`.
|
|
201
|
-
|
|
202
|
-
The transport is stateless. Each `POST /` is self-contained, with no session to open, no `Mcp-Session-Id` header, and nothing to expire, so you can put several instances behind a load balancer without session affinity. `GET` and `DELETE` on the MCP endpoint answer `405`. Clients written against the 2025 protocol, which open with an `initialize` handshake, are still served.
|
|
203
|
-
|
|
204
|
-
Environment variables for HTTP mode:
|
|
205
|
-
|
|
206
|
-
| Variable | Required | Default | Description |
|
|
207
|
-
| ------------------------------------------ | -------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
208
|
-
| `MCP_HTTP_MODE` | Yes, unless you pass `--http` | `false` | Set to `true` to serve HTTP instead of stdio. The `--http` CLI flag does the same thing. |
|
|
209
|
-
| `MCP_PORT` | No | `3000` | Port to bind the HTTP server to. |
|
|
210
|
-
| `SOCKET_API_TOKEN` | Required unless OAuth is enabled | None | Socket API token for outbound API calls. See the alias list below. |
|
|
211
|
-
| `SOCKET_OAUTH_ISSUER` | With OAuth | None | OAuth issuer URL. Must be `https` on a public host. See "Enabling OAuth" below. |
|
|
212
|
-
| `SOCKET_OAUTH_INTROSPECTION_CLIENT_ID` | With OAuth | None | Client ID used for RFC 7662 token introspection. |
|
|
213
|
-
| `SOCKET_OAUTH_INTROSPECTION_CLIENT_SECRET` | With OAuth | None | Client secret used for RFC 7662 token introspection. |
|
|
214
|
-
| `SOCKET_OAUTH_REQUIRED_SCOPES` | No | None | Scopes required on incoming access tokens, separated by spaces or commas. When unset, any active token passes. |
|
|
215
|
-
| `SOCKET_OAUTH_REQUIRE_AUDIENCE` | No | `false` | When `true`, reject an access token whose introspection response carries no `aud` claim. Read the audience note below first. |
|
|
216
|
-
| `SOCKET_API_BASE_URL` | No | None | Override the upstream Socket API endpoint. Falls back to `https://api.socket.dev` when unset. |
|
|
217
|
-
| `SOCKET_DEBUG` | No | `false` | Turns on verbose request and cache tracing on stderr, points `depscore` at `http://localhost:8866`, and permits a local OAuth issuer. |
|
|
218
|
-
| `TRUST_PROXY` | No | `false` | Trust `X-Forwarded-Host` and `X-Forwarded-Proto` when building OAuth metadata URLs. Enable only behind a reverse proxy that rewrites them. |
|
|
219
|
-
|
|
220
|
-
The three OAuth variables are a set: configure all three or none. Setting only some of them makes the server print `Incomplete OAuth configuration for HTTP mode` and exit `1`, rather than quietly start unauthenticated.
|
|
221
|
-
|
|
222
|
-
`SOCKET_API_TOKEN` is canonical. These aliases are read in order, first non-empty wins: `SOCKET_API_TOKEN`, `SOCKET_API_KEY`, `SOCKET_CLI_API_TOKEN`, `SOCKET_CLI_API_KEY`, `SOCKET_SECURITY_API_TOKEN`, `SOCKET_SECURITY_API_KEY`.
|
|
223
|
-
|
|
224
|
-
`SOCKET_API_TOKEN`, `SOCKET_API_BASE_URL`, and `SOCKET_DEBUG` also apply in stdio mode. Everything else in the table is HTTP-only.
|
|
225
|
-
|
|
226
|
-
<details>
|
|
227
|
-
|
|
228
|
-
<summary>Tuning the package-file blob cache and its fetches</summary>
|
|
229
|
-
|
|
230
|
-
`package_files`, `package_file_contents`, and `package_file_grep` fetch blobs from `socketusercontent.com` and hold them in a process-wide LRU cache. These knobs exist for operators running the server at volume; the defaults are fine otherwise.
|
|
231
|
-
|
|
232
|
-
| Variable | Default | Description |
|
|
233
|
-
| ---------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
234
|
-
| `SOCKET_BLOB_CACHE_BYTES` | `67108864` (64 MB) | Bytes the blob cache holds before evicting. A non-positive or unparseable value falls back to the default. |
|
|
235
|
-
| `SOCKET_BLOB_URL` | `https://socketusercontent.com` | Base URL blobs are fetched from. |
|
|
236
|
-
| `SOCKET_BROWSER_USER_AGENT` | A Chrome UA string | `User-Agent` sent on blob fetches. |
|
|
237
|
-
| `SOCKET_BYPASS_HEADER_NAME` | None | Name of an extra header sent on every blob fetch. Both name and value must be set for it to apply. |
|
|
238
|
-
| `SOCKET_BYPASS_HEADER_VALUE` | None | Value for that header. |
|
|
239
|
-
| `SOCKET_INTERNAL_USER_AGENT` | `socket-internal-tool/1.0` | `User-Agent` sent on the authenticated file-list call. |
|
|
240
|
-
|
|
241
|
-
</details>
|
|
242
|
-
|
|
243
|
-
**Enabling OAuth.** Set all three OAuth variables to require an OAuth access token on every MCP request:
|
|
244
|
-
|
|
245
|
-
```sh
|
|
246
|
-
MCP_HTTP_MODE=true \
|
|
247
|
-
SOCKET_OAUTH_ISSUER=https://issuer.example.com \
|
|
248
|
-
SOCKET_OAUTH_INTROSPECTION_CLIENT_ID=your-client-id \
|
|
249
|
-
SOCKET_OAUTH_INTROSPECTION_CLIENT_SECRET=your-client-secret \
|
|
250
|
-
socket-mcp --http
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
With OAuth enabled, every request to the MCP endpoint goes through RFC 7662 token introspection. A raw Socket API token is rejected with a `401`, whatever its prefix; a `sktsec_` token is no more privileged than any other string here. Callers send an OAuth access token, and the server uses that token for the Socket API calls it makes on their behalf. Run without the OAuth variables to accept raw Socket API tokens instead.
|
|
254
|
-
|
|
255
|
-
At startup the server discovers the issuer's RFC 8414 metadata. An issuer that carries a path (`https://auth.example.com/tenant1`) is probed at the path-inserted well-known URL first (`https://auth.example.com/.well-known/oauth-authorization-server/tenant1`), and the metadata document's own `issuer` must match `SOCKET_OAUTH_ISSUER` byte for byte. The issuer must be `https` on a public host; a loopback or private-network issuer is refused outright unless `SOCKET_DEBUG=true` is set for local-stack work. The same rule applies to the `introspection_endpoint` the metadata advertises.
|
|
256
|
-
|
|
257
|
-
Clients discover how to authenticate from `GET /.well-known/oauth-protected-resource` (RFC 9728), which the server publishes once OAuth is on:
|
|
258
|
-
|
|
259
|
-
```json
|
|
260
|
-
{
|
|
261
|
-
"resource": "https://mcp.example.com/",
|
|
262
|
-
"authorization_servers": ["https://issuer.example.com"],
|
|
263
|
-
"scopes_supported": ["packages:list"],
|
|
264
|
-
"bearer_methods_supported": ["header"],
|
|
265
|
-
"resource_name": "Socket MCP Server"
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
A rejected request answers `401` with a `WWW-Authenticate` header naming that metadata URL and the scopes this resource requires:
|
|
270
|
-
|
|
271
|
-
```text
|
|
272
|
-
WWW-Authenticate: Bearer error="invalid_token", error_description="Invalid or expired token",
|
|
273
|
-
resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource", scope="packages:list"
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
> [!IMPORTANT]
|
|
277
|
-
> **Audience validation.** When an introspection response includes an `aud` claim, the server requires it to name this resource and rejects the token otherwise. That check is always on and has no opt-out. When the response includes no `aud` at all, the token is accepted by default, because an authorization server that never emits the claim would otherwise fail every request. Audience validation therefore protects you exactly as far as your authorization server populates `aud`; if it does not, no audience is being checked. Set `SOCKET_OAUTH_REQUIRE_AUDIENCE=true` to additionally require the claim's presence, but only once you have confirmed your authorization server returns `aud` on introspection. Enabling it against a server that omits the claim rejects all traffic.
|
|
278
|
-
|
|
279
|
-
Add `TRUST_PROXY=true` only when the server is deployed behind a trusted reverse proxy or load balancer that normalizes the forwarded host and protocol headers.
|
|
280
|
-
|
|
281
|
-
Configure your MCP client to connect to the HTTP server:
|
|
282
|
-
|
|
283
|
-
```json
|
|
284
|
-
{
|
|
285
|
-
"mcpServers": {
|
|
286
|
-
"socket-mcp": {
|
|
287
|
-
"type": "http",
|
|
288
|
-
"url": "http://localhost:3000"
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
</details>
|
|
176
|
+
See the [self-hosted server instructions](docs/commands.md#self-hosted-server) for installation, stdio and HTTP setup, environment variables, and OAuth configuration.
|
|
295
177
|
|
|
296
178
|
## Usage
|
|
297
179
|
|
|
@@ -301,300 +183,74 @@ Once installed, ask your AI assistant questions like:
|
|
|
301
183
|
- "Analyze the security of my package.json dependencies"
|
|
302
184
|
- "What are the vulnerability scores for react, lodash, and axios?"
|
|
303
185
|
|
|
304
|
-
###
|
|
305
|
-
|
|
306
|
-
<details><summary>The full tool roster - names, arguments, and what each returns</summary>
|
|
307
|
-
|
|
308
|
-
#### depscore
|
|
309
|
-
|
|
310
|
-
Query the Socket API for dependency scoring information. Returns supply chain, quality, maintenance, vulnerability, and license scores per package.
|
|
311
|
-
|
|
312
|
-
| Parameter | Type | Required | Default | Description |
|
|
313
|
-
| ---------------------- | ------ | -------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
314
|
-
| `packages` | Array | โ
Yes | - | Array of package objects to analyze |
|
|
315
|
-
| `packages[].ecosystem` | String | No | `"npm"` | Package ecosystem. See Supported ecosystems below. |
|
|
316
|
-
| `packages[].depname` | String | โ
Yes | - | Name of the dependency/package |
|
|
317
|
-
| `packages[].version` | String | No | `"unknown"` | Version of the dependency |
|
|
318
|
-
| `platform` | String | No | - | OS-architecture hint (`linux-x64`, `darwin-arm64`, `win32-x64`) applied to every package in the request. Picks the most relevant artifact when a package ships platform-specific builds. |
|
|
319
|
-
|
|
320
|
-
##### Supported ecosystems
|
|
321
|
-
|
|
322
|
-
Based on [Socket's language support](https://docs.socket.dev/docs/language-support). The `ecosystem` parameter maps to PURL types:
|
|
186
|
+
### Documentation
|
|
323
187
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
| JavaScript & TypeScript | `npm` | npm, yarn, pnpm, Bun, VLT | GA |
|
|
327
|
-
| Python | `pypi` | uv, pip, Poetry, Anaconda | GA |
|
|
328
|
-
| Go | `golang` | Go Modules | GA |
|
|
329
|
-
| Java / Scala / Kotlin | `maven` | Maven, Gradle, sbt | GA |
|
|
330
|
-
| Ruby | `gem` | Bundler | GA |
|
|
331
|
-
| .NET (C#, F#, VB) | `nuget` | NuGet | GA |
|
|
332
|
-
| Rust | `cargo` | cargo | GA |
|
|
333
|
-
| PHP | `composer` | Composer | Experimental |
|
|
334
|
-
| GitHub Actions | `actions` | GitHub Actions workflows | Experimental (workflow scanning, not package-level) |
|
|
188
|
+
- [Service and tool reference](docs/service.md) lists every tool, input, result, authentication rule, and HTTP behavior.
|
|
189
|
+
- [Server commands and workflows](docs/commands.md) covers local launch, self-hosting, environment variables, and the optional Claude Code hook.
|
|
335
190
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
Example request:
|
|
191
|
+
### Tools exposed
|
|
339
192
|
|
|
340
|
-
|
|
341
|
-
{
|
|
342
|
-
"packages": [
|
|
343
|
-
{ "ecosystem": "npm", "depname": "express", "version": "4.18.2" },
|
|
344
|
-
{ "ecosystem": "pypi", "depname": "fastapi", "version": "0.100.0" }
|
|
345
|
-
]
|
|
346
|
-
}
|
|
347
|
-
```
|
|
193
|
+
The complete tool roster, schemas, parameters, and result examples are in the [service reference](docs/service.md#tools-exposed).
|
|
348
194
|
|
|
349
|
-
|
|
195
|
+
<details><summary>Tool quick links</summary>
|
|
350
196
|
|
|
351
|
-
|
|
352
|
-
Dependency scores:
|
|
353
|
-
pkg:npm/express@4.18.2: license: 100, maintenance: 87, quality: 100, supplyChain: 97, vulnerability: 98
|
|
354
|
-
Report: https://socket.dev/npm/package/express
|
|
355
|
-
pkg:pypi/fastapi@0.100.0: license: 100, maintenance: 100, quality: 100, supplyChain: 100, vulnerability: 100
|
|
356
|
-
Report: https://socket.dev/pypi/package/fastapi
|
|
357
|
-
```
|
|
197
|
+
#### depscore
|
|
358
198
|
|
|
359
|
-
|
|
199
|
+
See [depscore](docs/service.md#depscore).
|
|
360
200
|
|
|
361
201
|
#### organizations
|
|
362
202
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
This tool needs a Socket API token. See [Authentication for organization-scoped tools](#authentication-for-organization-scoped-tools) below.
|
|
366
|
-
|
|
367
|
-
The response is the Socket API's JSON, keyed by organization id. The `slug` is what the other tools want:
|
|
368
|
-
|
|
369
|
-
```json
|
|
370
|
-
{
|
|
371
|
-
"organizations": {
|
|
372
|
-
"1234": {
|
|
373
|
-
"id": "1234",
|
|
374
|
-
"name": "Acme Robotics",
|
|
375
|
-
"plan": "enterprise",
|
|
376
|
-
"slug": "acme-robotics"
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
```
|
|
203
|
+
See [organizations](docs/service.md#organizations).
|
|
381
204
|
|
|
382
205
|
#### alerts
|
|
383
206
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
| Parameter | Type | Required | Default | Description |
|
|
387
|
-
| --------------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------- |
|
|
388
|
-
| `org_slug` | String | โ
Yes | - | Organization slug (get it from the `organizations` tool) |
|
|
389
|
-
| `severity` | String | No | - | Comma-separated subset of `low,medium,high,critical` |
|
|
390
|
-
| `status` | String | No | - | `open` or `cleared` |
|
|
391
|
-
| `category` | String | No | - | Comma-separated subset of `supplyChainRisk,maintenance,quality,license,vulnerability` |
|
|
392
|
-
| `artifact_type` | String | No | - | Comma-separated ecosystems: `npm,pypi,gem,maven,golang,nuget,cargo,chrome,openvsx` |
|
|
393
|
-
| `artifact_name` | String | No | - | Restrict to a single package name |
|
|
394
|
-
| `alert_type` | String | No | - | Comma-separated Socket alert types (e.g. `usesEval,unmaintained`) |
|
|
395
|
-
| `repo_slug` | String | No | - | Comma-separated repository slugs |
|
|
396
|
-
| `per_page` | Integer | No | `100` | Results per page (1โ5000) |
|
|
397
|
-
| `cursor` | String | No | - | Pagination cursor - the `endCursor` from a previous response |
|
|
207
|
+
See [alerts](docs/service.md#alerts).
|
|
398
208
|
|
|
399
209
|
#### threat_feed
|
|
400
210
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
| Parameter | Type | Required | Default | Description |
|
|
404
|
-
| ------------------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------ |
|
|
405
|
-
| `org_slug` | String | โ
Yes | - | Organization slug (get it from the `organizations` tool) |
|
|
406
|
-
| `filter` | String | No | `mal` | Threat category: `mal` (malware), `vuln`, `typ` (typosquat), `obf` (obfuscated), `mjo`, `kes`, `spy`, etc. |
|
|
407
|
-
| `ecosystem` | String | No | - | Ecosystem: `npm`, `pypi`, `gem`, `maven`, `golang`, `nuget`, `cargo`, `chrome`, `openvsx`, `vscode`, `huggingface` |
|
|
408
|
-
| `name` | String | No | - | Filter by package name |
|
|
409
|
-
| `version` | String | No | - | Filter by package version |
|
|
410
|
-
| `is_human_reviewed` | Boolean | No | `false` | Only return human-reviewed items |
|
|
411
|
-
| `sort` | String | No | `updated_at` | Sort field: `id`, `created_at`, `updated_at` |
|
|
412
|
-
| `direction` | String | No | `desc` | Sort direction: `asc`, `desc` |
|
|
413
|
-
| `updated_after` | String | No | - | ISO timestamp; only items updated after this |
|
|
414
|
-
| `created_after` | String | No | - | ISO timestamp; only items created after this |
|
|
415
|
-
| `per_page` | Integer | No | `30` | Results per page (1โ100) |
|
|
416
|
-
| `cursor` | String | No | - | Pagination cursor - the `nextPageCursor` from a previous response |
|
|
211
|
+
See [threat_feed](docs/service.md#threat_feed).
|
|
417
212
|
|
|
418
213
|
#### package_files
|
|
419
214
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
| Parameter | Type | Required | Default | Description |
|
|
423
|
-
| ------------ | ------ | -------- | ------- | --------------------------------------------------------------------------------------- |
|
|
424
|
-
| `ecosystem` | String | No | `npm` | `npm`, `pypi`, `gem`, `cargo`, `maven`, `golang`, `nuget`, `chrome`, `openvsx` |
|
|
425
|
-
| `depname` | String | โ
Yes | - | Package name (e.g. `lodash`, `@babel/core`, `org.springframework:spring-core`) |
|
|
426
|
-
| `version` | String | โ
Yes | - | Package version |
|
|
427
|
-
| `artifactId` | String | No | - | Per-version disambiguator (PyPI filename, Maven artifact id, NuGet asset) |
|
|
428
|
-
| `platform` | String | No | - | Platform qualifier for per-OS/arch artifacts (e.g. openvsx `linux-x64`, `darwin-arm64`) |
|
|
429
|
-
|
|
430
|
-
Output is a header line and a tree. The token after each size is the blob `hash`:
|
|
431
|
-
|
|
432
|
-
```text
|
|
433
|
-
pkg:npm/lodash@4.17.21 โ 1054 files, 1379.3 KB
|
|
434
|
-
โโโ package/
|
|
435
|
-
โโโ fp/
|
|
436
|
-
โ โโโ __.js 43B QlKUJ6782LHNEISw-t4uX1hyH1TCZye4ShYOMIAghheg
|
|
437
|
-
โ โโโ _baseConvert.js 16.0K QpGkoQltpQn5ZeTFxYQOnk8FWp-7yyeUQtyzdZXl48nA
|
|
438
|
-
```
|
|
215
|
+
See [package_files](docs/service.md#package_files).
|
|
439
216
|
|
|
440
217
|
#### package_file_contents
|
|
441
218
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
| Parameter | Type | Required | Default | Description |
|
|
445
|
-
| --------- | ------ | -------- | ------- | ------------------------------------------------------- |
|
|
446
|
-
| `hash` | String | โ
Yes | - | Blob hash from `package_files` |
|
|
447
|
-
| `path` | String | No | - | File path, for display only; does not affect the lookup |
|
|
219
|
+
See [package_file_contents](docs/service.md#package_file_contents).
|
|
448
220
|
|
|
449
221
|
#### package_file_grep
|
|
450
222
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
| Parameter | Type | Required | Default | Description |
|
|
454
|
-
| ----------------- | ------- | -------- | ------- | ------------------------------------------------------- |
|
|
455
|
-
| `hash` | String | โ
Yes | - | Blob hash from `package_files` |
|
|
456
|
-
| `pattern` | String | โ
Yes | - | JavaScript regular expression (plain literals work too) |
|
|
457
|
-
| `caseInsensitive` | Boolean | No | `false` | Match case-insensitively |
|
|
458
|
-
| `contextLines` | Integer | No | `0` | Lines of context before and after each match (0โ5) |
|
|
459
|
-
| `maxMatches` | Integer | No | `100` | Cap on matching lines returned (1โ500) |
|
|
460
|
-
| `path` | String | No | - | File path, for display only; does not affect the lookup |
|
|
223
|
+
See [package_file_grep](docs/service.md#package_file_grep).
|
|
461
224
|
|
|
462
225
|
</details>
|
|
463
226
|
|
|
464
|
-
### Authentication
|
|
465
|
-
|
|
466
|
-
`depscore` works without credentials on the public server. The `organizations`, `alerts`, `threat_feed`, and `package_files` tools call Socket's authenticated REST API, so they need a Socket API token.
|
|
467
|
-
|
|
468
|
-
How the server resolves a token depends on the transport:
|
|
227
|
+
### Authentication
|
|
469
228
|
|
|
470
|
-
|
|
471
|
-
- **HTTP mode** scopes the organization tools to the caller, never to the server's own token. Send your credential as an `Authorization: Bearer <token>` header on each request. Which credential to send depends on whether the deployment runs OAuth. On an OAuth-enabled server, send an OAuth access token: every bearer token is validated through introspection, and a raw Socket API token is rejected with a `401` challenge no matter what it starts with. On a server without OAuth, send your raw Socket API token and it is used directly. Either way the server uses that per-request token for the Socket API calls it makes on your behalf. A shared deployment never answers `organizations`, `alerts`, `threat_feed`, or `package_files` with the operator's data: when a request carries no token, those tools return the auth-required error. `depscore` alone may fall back to the server's startup token, since package scores are the same for every caller.
|
|
472
|
-
|
|
473
|
-
When a token is missing, every affected tool returns the same message:
|
|
474
|
-
|
|
475
|
-
```text
|
|
476
|
-
Authentication is required. Set SOCKET_API_TOKEN for stdio mode, or send your Socket API
|
|
477
|
-
token as an `Authorization: Bearer <token>` header (or connect through OAuth) in HTTP mode.
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
Generate a token from the [Socket dashboard](https://socket.dev/) under API tokens, then export it before launching the server:
|
|
481
|
-
|
|
482
|
-
```sh
|
|
483
|
-
export SOCKET_API_TOKEN="your-socket-api-token"
|
|
484
|
-
```
|
|
229
|
+
See the [authentication reference](docs/service.md#authentication-for-organization-scoped-tools) for local tokens, per-request HTTP credentials, and hosted OAuth.
|
|
485
230
|
|
|
486
231
|
### Worked example: organization details and alerts
|
|
487
232
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
1. **Discover the org slug.** Call `organizations` (no arguments). The server reads your token, calls `GET /v0/organizations`, and returns the organizations your token can see. Pick the `slug` you want, e.g. `acme-robotics`.
|
|
491
|
-
|
|
492
|
-
2. **Fetch alerts for that org.** Call `alerts` with the slug and any filters:
|
|
493
|
-
|
|
494
|
-
```json
|
|
495
|
-
{
|
|
496
|
-
"org_slug": "acme-robotics",
|
|
497
|
-
"severity": "high,critical",
|
|
498
|
-
"status": "open"
|
|
499
|
-
}
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
The server calls `GET /v0/orgs/acme-robotics/alerts` with the same token and returns the matching alerts plus pagination metadata. To page forward, pass the response's `endCursor` back as `cursor`.
|
|
503
|
-
|
|
504
|
-
The same token scopes every org-scoped tool, so `threat_feed` and `package_files` work the moment `organizations` confirms which slug the token belongs to.
|
|
233
|
+
See the [organization and alerts example](docs/service.md#worked-example-organization-details-and-alerts).
|
|
505
234
|
|
|
506
235
|
### Adjusting tool usage via client rules
|
|
507
236
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
| MCP Client | Rules File Location |
|
|
511
|
-
| ------------------- | --------------------------------- |
|
|
512
|
-
| Claude Desktop/Code | `CLAUDE.md` |
|
|
513
|
-
| VSCode Copilot | `.github/copilot-instructions.md` |
|
|
514
|
-
| Cursor | `.cursor/rules` |
|
|
237
|
+
See [client rule examples](docs/service.md#adjusting-tool-usage-via-client-rules).
|
|
515
238
|
|
|
516
|
-
|
|
239
|
+
### Claude Code Hook (Optional)
|
|
517
240
|
|
|
518
|
-
|
|
519
|
-
Always check dependency scores with the depscore tool when you add a new dependency. If the score is low, consider using an alternative library or writing the code yourself.
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
## Claude Code Hook (Optional)
|
|
523
|
-
|
|
524
|
-
The repo ships an optional [Claude Code hook](https://code.claude.com/docs/en/hooks) that blocks high-risk packages before installation. When Claude Code runs an install command, the hook queries the public Socket MCP server at `https://mcp.socket.dev/` and denies the install when the package's supply chain score is below `20` (known malware, typosquats, high-risk supply chain signals). No CLI to install - copy the file and wire it up; the public server signs in via OAuth on first use.
|
|
525
|
-
|
|
526
|
-
Supported ecosystems and package managers:
|
|
527
|
-
|
|
528
|
-
| Ecosystem | Commands |
|
|
529
|
-
| --------- | ----------------------------------------------------------------------------------------- |
|
|
530
|
-
| npm | `npm install`, `npm i`, `npm add`, `yarn add`, `pnpm add`, `bun add` |
|
|
531
|
-
| PyPI | `pip install`, `pip3 install`, `uv add`, `uv pip install`, `poetry add`, `pipenv install` |
|
|
532
|
-
| Cargo | `cargo add`, `cargo install` |
|
|
533
|
-
| RubyGems | `gem install`, `bundle add` |
|
|
534
|
-
| Go | `go get`, `go install` |
|
|
535
|
-
| NuGet | `dotnet add package`, `nuget install` |
|
|
241
|
+
The optional Socket package guard is documented in the [commands and workflows reference](docs/commands.md#claude-code-hook-optional).
|
|
536
242
|
|
|
537
243
|
### Setup
|
|
538
244
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
**Prerequisites:** Node.js 24+.
|
|
542
|
-
|
|
543
|
-
1. Copy the whole `dist/socket-gate` directory into your hooks folder. The
|
|
544
|
-
bundled `socket-gate.cjs` is self-contained, so it runs without any
|
|
545
|
-
dependencies beside it.
|
|
546
|
-
|
|
547
|
-
From a published install:
|
|
548
|
-
|
|
549
|
-
```bash
|
|
550
|
-
mkdir -p ~/.claude/hooks
|
|
551
|
-
cp -R node_modules/@socketsecurity/mcp/dist/socket-gate ~/.claude/hooks/
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
From a checkout, build it first:
|
|
555
|
-
|
|
556
|
-
```bash
|
|
557
|
-
pnpm run build
|
|
558
|
-
mkdir -p ~/.claude/hooks
|
|
559
|
-
cp -R dist/socket-gate ~/.claude/hooks/
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
2. Add to `~/.claude/settings.json`:
|
|
563
|
-
|
|
564
|
-
```json
|
|
565
|
-
{
|
|
566
|
-
"hooks": {
|
|
567
|
-
"PreToolUse": [
|
|
568
|
-
{
|
|
569
|
-
"matcher": "Bash",
|
|
570
|
-
"hooks": [
|
|
571
|
-
{
|
|
572
|
-
"type": "command",
|
|
573
|
-
"command": "node ~/.claude/hooks/socket-gate/socket-gate.cjs"
|
|
574
|
-
}
|
|
575
|
-
]
|
|
576
|
-
}
|
|
577
|
-
]
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
See [`hooks/socket-gate/README.md`](hooks/socket-gate/README.md) for the full
|
|
583
|
-
reference.
|
|
584
|
-
|
|
585
|
-
</details>
|
|
245
|
+
See the [hook setup instructions](docs/commands.md#setup).
|
|
586
246
|
|
|
587
247
|
### How it works
|
|
588
248
|
|
|
589
|
-
|
|
249
|
+
See [how the hook works](docs/commands.md#how-it-works).
|
|
590
250
|
|
|
591
251
|
### Limitations
|
|
592
252
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
- **Manifest edits + lockfile installs.** If Claude edits a manifest directly (`package.json`, `requirements.txt`, `Cargo.toml`, `Gemfile`, `go.mod`, `*.csproj`) then runs a bare install (`npm install`, `pip install -r requirements.txt`, `cargo build`, `bundle install`, `go mod tidy`, `dotnet restore`), there is no package name on the command line to check.
|
|
596
|
-
- **Package-manager invocations only.** Direct downloads (`curl | sh`, `wget`), post-install scripts of already-accepted packages, and transitive dependencies are not re-checked.
|
|
597
|
-
- **Indirect Claude paths.** Sub-agents, MCP tools that shell out, and non-`Bash` tool calls are not covered unless the `matcher` is broadened.
|
|
253
|
+
See the [hook limitations](docs/commands.md#limitations).
|
|
598
254
|
|
|
599
255
|
Inspired by [Jimmy Vo's dependency hook](https://blog.jimmyvo.com/posts/claudes-dependency-hook/).
|
|
600
256
|
|
|
@@ -626,48 +282,17 @@ pnpm run server-http
|
|
|
626
282
|
|
|
627
283
|
Both scripts read `SOCKET_API_TOKEN` (falling back to `SOCKET_API_KEY`) from your environment. Append `:debug` to either one (`pnpm run server-http:debug`) to set `SOCKET_DEBUG=1` and get per-request tracing on stderr.
|
|
628
284
|
|
|
629
|
-
|
|
630
|
-
| ------------------------- | ----------------------------------- |
|
|
631
|
-
| Test | `pnpm test` |
|
|
632
|
-
| Test one file | `pnpm test test/unit/purl.test.mts` |
|
|
633
|
-
| Live-API end-to-end tests | `pnpm run test:e2e` |
|
|
634
|
-
| Type check | `pnpm run type` |
|
|
635
|
-
| Lint and format | `pnpm run fix --all` |
|
|
636
|
-
| Full check suite | `pnpm run check --all` |
|
|
637
|
-
| Bundle to `dist/` | `pnpm run build` |
|
|
638
|
-
|
|
639
|
-
Never put `--` before a test path; that widens the run to the whole suite. Write `pnpm test test/unit/purl.test.mts`.
|
|
285
|
+
### Audit events
|
|
640
286
|
|
|
641
|
-
|
|
287
|
+
Audit-event destinations and record behavior are documented in the [service reference](docs/service.md#audit-events).
|
|
642
288
|
|
|
643
289
|
### Health check endpoint
|
|
644
290
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
```json
|
|
648
|
-
{
|
|
649
|
-
"status": "healthy",
|
|
650
|
-
"service": "socket-mcp",
|
|
651
|
-
"version": "0.0.20",
|
|
652
|
-
"timestamp": "2026-07-29T01:50:30.394Z"
|
|
653
|
-
}
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
Suitable for Kubernetes liveness/readiness probes, Docker health checks, load balancers.
|
|
291
|
+
The HTTP health response is documented in the [service reference](docs/service.md#health-check-endpoint).
|
|
657
292
|
|
|
658
293
|
### Troubleshooting
|
|
659
294
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
**Q: Getting a `403 Forbidden: Invalid origin` error, or the connector never opens an OAuth screen** - The server accepts client `Origin` headers when the request's `Host` matches the hosted deployment. Confirm that your client uses `https://mcp.socket.dev/` and follows its setup steps above. A persistent `Invalid origin` response requires checking that the hosted deployment includes the fix.
|
|
663
|
-
|
|
664
|
-
**Q: Local server fails to start** - Ensure Node.js 24+ is installed, check `SOCKET_API_TOKEN` is set, verify the API token has `packages:list` permission. In stdio mode a missing token is fatal: the server prints `SOCKET_API_TOKEN environment variable is required in stdio mode` and exits `1`.
|
|
665
|
-
|
|
666
|
-
**Q: The server exits with `Incomplete OAuth configuration for HTTP mode`** - `SOCKET_OAUTH_ISSUER`, `SOCKET_OAUTH_INTROSPECTION_CLIENT_ID`, and `SOCKET_OAUTH_INTROSPECTION_CLIENT_SECRET` must all be set or all be unset.
|
|
667
|
-
|
|
668
|
-
**Q: Getting authentication errors with local server** - Double-check your API key is valid, ensure `packages:list` scope, regenerate if needed. If the tool that failed was `organizations`, `alerts`, `threat_feed`, or `package_files` on an HTTP deployment, the server is refusing to answer with the operator's token by design; send your own in an `Authorization: Bearer` header.
|
|
669
|
-
|
|
670
|
-
**Q: AI assistant can't find the depscore tool** - Restart your MCP client after configuration changes, verify config is saved, check the server is running. `tools/list` advertises a one-hour public cache, so a client that caches the tool list may need a restart to pick up a newly added tool.
|
|
295
|
+
See [service troubleshooting](docs/service.md#troubleshooting).
|
|
671
296
|
|
|
672
297
|
### Getting help
|
|
673
298
|
|
|
@@ -677,14 +302,30 @@ Suitable for Kubernetes liveness/readiness probes, Docker health checks, load ba
|
|
|
677
302
|
|
|
678
303
|
</details>
|
|
679
304
|
|
|
305
|
+
## Compatibility
|
|
306
|
+
|
|
307
|
+
MCP is still evolving, and client implementations differ in how they handle parts of the protocol. We proactively track compatibility gaps and work to offer the best possible experience with Claude Code, Codex, Cursor, and Zed. The table below summarizes the latest tests and known gaps.
|
|
308
|
+
|
|
309
|
+
Snapshot dated October 2, 2026; tests ran September 29โOctober 1. Each result applies to the listed client version and setup.
|
|
310
|
+
|
|
311
|
+
| Client and tested setup | Hosted OAuth result | Verified tools and continuity | Important limit or workaround |
|
|
312
|
+
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
313
|
+
| Claude Code 2.1.285, hosted HTTP | First `organizations` call failed with a sign-in request; explicit OAuth then completed. | The 2.1.285 run verified the initial failure and successful login. `organizations` and `depscore` passed after login in a separate 2.1.284 run. | The pre-login โauthenticatedโ label was misleading; see [upstream issue #98942](https://github.com/anthropics/claude-code/issues/98942). |
|
|
314
|
+
| Codex CLI 0.159.2, hosted HTTP | Works after explicit login. | `organizations` and `depscore` passed after login, including a new conversation and idle checks. | A broad scope request showed `invalid_scope` before Codex retried with the three MCP read permissions; see [upstream issue #15643](https://github.com/openai/codex/issues/15643). |
|
|
315
|
+
| Cursor 3.22.12, hosted HTTP OAuth | Fails in tested conditions: `organizations` remained Unauthorized; the Authenticate card did not establish access. | `organizations` only; no successful hosted OAuth call verified. | Cursor 3.20 recurrence was manually reported; no fix version is known. [A related forum reply](https://forum.cursor.com/t/plugin-mcp-oauth-never-reaches-needsauth-authenticate-button-missing-browser-never-opens/170058/8) describes an unsuccessful workaround attempt but identifies a separate Cursor 3.18.9 marketplace-import blocker. |
|
|
316
|
+
| Cursor, local stdio with API token (version not recorded) | Not applicable; this setup bypasses hosted OAuth. | `depscore` passed; restart continuity was reported manually. | This does not verify hosted OAuth, `organizations`, or other tools. |
|
|
317
|
+
| Zed Agent 1.22.0, hosted HTTP | Works after explicit OAuth. | `organizations` and `depscore` passed after login, restart, and a six-minute idle check. | Intermittent timeouts after idle, cause under investigation; four client timeouts matched fast server HTTP 400 responses. |
|
|
318
|
+
|
|
319
|
+
Only `organizations` and `depscore` were tested. Token refresh, server-side revocation, and all-tool coverage were not tested. Claude Desktop, VS Code, Windsurf, and Factory were not tested in this matrix.
|
|
320
|
+
|
|
680
321
|
## License
|
|
681
322
|
|
|
682
323
|
MIT
|
|
683
324
|
|
|
684
325
|
<div align="center">
|
|
685
326
|
<picture>
|
|
686
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/SocketDev/socket-mcp/
|
|
687
|
-
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/SocketDev/socket-mcp/
|
|
688
|
-
<img width="320" height="91" alt="Socket" src="https://raw.githubusercontent.com/SocketDev/socket-mcp/
|
|
327
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/SocketDev/socket-mcp/HEAD/assets/fleet/socket-combomark-dark.svg">
|
|
328
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/SocketDev/socket-mcp/HEAD/assets/fleet/socket-combomark-light.svg">
|
|
329
|
+
<img width="320" height="91" alt="Socket" src="https://raw.githubusercontent.com/SocketDev/socket-mcp/HEAD/assets/fleet/socket-combomark-light.svg">
|
|
689
330
|
</picture>
|
|
690
331
|
</div>
|