SkillTotal

Is @modelcontextprotocol/sdk safe?

No malicious indicators - review capabilities before installing
Notable — review in context (capabilities are not malware):
  • Node.js shell/command execution
  • Node.js network egress
  • Delegated authentication (OAuth 2.0 / OIDC)

@modelcontextprotocol/sdk is an AI npm_package analyzed by SkillTotal's deterministic static scanner. The scan found no malicious indicators, though 4 risky constructs are reported for review. It can: delegated authentication, mcp tools detected, network egress and shell execution — capabilities are what the code can do, not a verdict on intent. Risk score 0/100 (low).

@modelcontextprotocol/sdk 1.30.0

npm_package · npm:@modelcontextprotocol/sdk
LOW
0
/ 100 risk score
Snapshot · scanned Aug 19, 2026 · @modelcontextprotocol/sdk@1.30.0 · engine 0.41.0 / ruleset 45

Automated static-analysis result. It can contain false positives and false negatives, and is not a claim about the intent of @modelcontextprotocol/sdk's authors. Report a false positive.

Capabilities — what this component can do (not a risk score):
delegated authenticationmcp tools detectednetwork egressshell execution

Behavioral traits

How this component maps to the CSA agentic threat model. Descriptive — it never affects the risk score.

Tool surface
Tool Usage
Execution authority
Tool Access Control / Direct Tool Access
Network egress
Interaction & Communication / Direct Communication
Delegated authentication
Tool Execution Context / User Delegated Credentials

Findings (4)

HIGHNode.js shell/command executionST-SHELL-NODE

The component can run operating-system commands or spawn processes.

const match = regex.exec(authenticateHeader);
import { IOType } from 'node:child_process';
const cross_spawn_1 = __importDefault(require("cross-spawn"));
const match = regex.exec(authenticateHeader);
import { IOType } from 'node:child_process';
import spawn from 'cross-spawn';
this._process = spawn(this._serverParams.command, this._serverParams.args ?? [], {

Why it matters: Powerful and often legitimate — confirm the commands aren't built from untrusted input.

Fix: Confirm the command and its arguments are fully controlled and not derived from untrusted input; prefer execFile with an argument array.

MEDIUMNode.js network egressST-NET-NODE

The component makes outbound network requests.

import { IncomingMessage, ServerResponse } from 'node:http';
import { IncomingMessage, ServerResponse } from 'node:http';
*   async fetch(request: Request): Promise<Response> {
*   async fetch(request: Request): Promise<Response> {
import { IncomingMessage, ServerResponse } from 'node:http';
import { IncomingMessage, ServerResponse } from 'node:http';
*   async fetch(request: Request): Promise<Response> {
*   async fetch(request: Request): Promise<Response> {

Why it matters: Usually legitimate, but confirm the destinations are expected and no sensitive data leaves.

Fix: Confirm the destination hosts are expected and that no sensitive data is sent off-host.

LOWDelegated authentication (OAuth 2.0 / OIDC)ST-AUTH-DELEGATED

An OAuth 2.0 / OpenID Connect delegated-authentication flow was detected (authorization-code / refresh-token / token-exchange grant, an OIDC authorize/discovery endpoint or id_token, or a delegation library). Tools authenticate with the end user's delegated, scoped credentials rather than a long-lived embedded service credential. (25 occurrence(s) shown as evidence).

// OIDC: https://example.com/.well-known/openid-configuration
url: new URL(`/.well-known/openid-configuration`, url.origin),
// RFC 8414 style: Insert /.well-known/openid-configuration before the path
url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),
// OIDC Discovery 1.0 style: Append /.well-known/openid-configuration after the path
url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),
authorizationUrl = new URL(metadata.authorization_endpoint);
grant_type: 'authorization_code',
grant_type: 'refresh_token',
const authorization_endpoint = '/authorize';
authorization_endpoint: new URL(authorization_endpoint, baseUrl || issuer).href,
router.use(new URL(oauthMetadata.authorization_endpoint).pathname, (0, authorize_js_1.authorizationHandler)({ provider: options.provider, ...options.authorizationOptions }));
authorization_endpoint: z.ZodURL;
authorization_endpoint: z.ZodURL;
authorization_endpoint: z.ZodURL;
id_token: z.ZodOptional<z.ZodString>;
authorization_endpoint: exports.SafeUrlSchema,
authorization_endpoint: exports.SafeUrlSchema,
id_token: z.string().optional(), // Optional for OAuth 2.1, but necessary in OpenID Connect
// OIDC: https://example.com/.well-known/openid-configuration
url: new URL(`/.well-known/openid-configuration`, url.origin),
// RFC 8414 style: Insert /.well-known/openid-configuration before the path

Fix: Delegated auth is a lower-blast-radius execution context than an embedded static credential. Confirm the requested scopes are minimal and that tokens are never logged or forwarded off-host.

LOWMCP tool surface detectedST-MCP-DETECTED

An MCP tool surface (manifest or tool definitions) was found.

* const server = new Server(
* const server = new Server(

Why it matters: Just context — review which tools it offers and their permissions.

Fix: Review the declared MCP tools and their permissions.

Check your own component

Run the same evidence-backed scan on any MCP server, agent skill, or package.

Scan your own component

How we determine this: deterministic static analysis (regex + AST), evidence-anchored, no code execution. Methodology →