Skip to main content
interlace
Plugin: mcp-sdk-security

eslint-plugin-mcp-sdk-security

MCP SDK security — tool-input validation and transport hygiene

AI-Optimized Security

Every rule includes CWE, OWASP, and CVSS metadata for AI assistants to provide precise, context-aware fixes.

Install

npm install -D oxlint-plugin-mcp-sdk-security
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-mcp-sdk-security"],  "rules": {    "mcp-sdk-security/no-code-injection-in-tool": "error",    "mcp-sdk-security/no-command-injection-in-tool": "error",    "mcp-sdk-security/no-credential-leak-in-tool": "error",    "mcp-sdk-security/no-duplicate-tool-name": "warn",    "mcp-sdk-security/no-path-traversal-in-tool": "error",    "mcp-sdk-security/no-predictable-session-id": "error",    "mcp-sdk-security/no-shared-stateless-transport": "error",    "mcp-sdk-security/no-sql-injection-in-tool": "error",    "mcp-sdk-security/no-ssrf-in-tool": "error",    "mcp-sdk-security/no-tool-description-injection": "error",    "mcp-sdk-security/no-untrusted-stdio-command": "error",    "mcp-sdk-security/no-untrusted-tool-metadata-in-prompt": "error",    "mcp-sdk-security/no-unvalidated-tool-args": "error",    "mcp-sdk-security/require-http-transport-hardening": "error",    "mcp-sdk-security/require-tool-input-schema": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-mcp-sdk-security'],    rules: {      'mcp-sdk-security/no-code-injection-in-tool': 'error',      'mcp-sdk-security/no-command-injection-in-tool': 'error',      'mcp-sdk-security/no-credential-leak-in-tool': 'error',      'mcp-sdk-security/no-duplicate-tool-name': 'warn',      'mcp-sdk-security/no-path-traversal-in-tool': 'error',      'mcp-sdk-security/no-predictable-session-id': 'error',      'mcp-sdk-security/no-shared-stateless-transport': 'error',      'mcp-sdk-security/no-sql-injection-in-tool': 'error',      'mcp-sdk-security/no-ssrf-in-tool': 'error',      'mcp-sdk-security/no-tool-description-injection': 'error',      'mcp-sdk-security/no-untrusted-stdio-command': 'error',      'mcp-sdk-security/no-untrusted-tool-metadata-in-prompt': 'error',      'mcp-sdk-security/no-unvalidated-tool-args': 'error',      'mcp-sdk-security/require-http-transport-hardening': 'error',      'mcp-sdk-security/require-tool-input-schema': 'error',    },  },});

oxlint-plugin-mcp-sdk-security re-exports eslint-plugin-mcp-sdk-security/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.


Live from GitHub

This content is fetched directly from README.md on GitHub and cached for 1 hour.

Live README from GitHubfrom eslint-plugin-mcp-sdk-security/README.md, cached for 1 hour.Edit on GitHub

⭐ If this plugin caught a real bug for you, star the repo — it's the signal that keeps these rules maintained.

Description

Security rules for code built on @modelcontextprotocol/sdk.

Scope: this plugin lints the MCP SDK's API shapes — registerTool, transports, handler signatures. It does not inspect MCP wire traffic, which isn't visible from source. Every rule gates on the SDK actually being imported, so it stays silent in files that don't use MCP.

  • Why — a linter nobody reads protects nothing. We would rather miss a finding than spend your attention on one that was never real.
  • How — evidence, not names. A rule fires on what the code does, resolved through the AST and ESLint's own scope analysis.
  • What — every finding carries its fix, in prose for a human and as structured JSON for an agent. Security rules add a CWE mapping and, where assigned, a CVSS score.

That trade costs recall, and we measure it: methodology · results · a false positive is a bug.

Getting Started

oxlint / Vite+ — the same rules under the same mcp-sdk-security/<rule> IDs, without ESLint:

npm install oxlint-plugin-mcp-sdk-security --save-dev
// .oxlintrc.json
{ "jsPlugins": ["oxlint-plugin-mcp-sdk-security"] }
// vite.config.ts
import { defineConfig } from 'vite-plus';

export default defineConfig({ lint: { jsPlugins: ['oxlint-plugin-mcp-sdk-security'] } });

ESLint:

npm install eslint-plugin-mcp-sdk-security --save-dev

⚙️ Configuration Presets

PresetRules (error, except no-duplicate-tool-name at warn)Description
minimalno-command-injection-in-tool, require-tool-input-schemaOnly the rules whose every finding is a defect by construction.
recommendedno-code-injection-in-tool, no-command-injection-in-tool, no-credential-leak-in-tool, no-duplicate-tool-name, no-path-traversal-in-tool, no-predictable-session-id, no-shared-stateless-transport, no-sql-injection-in-tool, no-ssrf-in-tool, no-tool-description-injection, no-untrusted-stdio-command, no-untrusted-tool-metadata-in-prompt, no-unvalidated-tool-args, require-http-transport-hardening, require-tool-input-schemaThe default. Every rule, each at error from CVSS 7.0 up and warn below.
strictno-code-injection-in-tool, no-command-injection-in-tool, no-credential-leak-in-tool, no-duplicate-tool-name, no-path-traversal-in-tool, no-predictable-session-id, no-shared-stateless-transport, no-sql-injection-in-tool, no-ssrf-in-tool, no-tool-description-injection, no-untrusted-stdio-command, no-untrusted-tool-metadata-in-prompt, no-unvalidated-tool-args, require-http-transport-hardening, require-tool-input-schemaEvery rule, at its recommended level. Where a new rule lands before its false-positive profile is measured.

Supported servers: @modelcontextprotocol/sdk (v1), the v2 split packages (@modelcontextprotocol/server, client, core, node, express, hono, fastify), and mcp-handler / @vercel/mcp-adapter. Every rule stays silent in a file that imports none of them.

What the rules cover:

  • Tool handlers — a tool argument, request.params.arguments or a ResourceTemplate variable reaching a process (no-command-injection-in-tool), a file path (no-path-traversal-in-tool), a request host (no-ssrf-in-tool), SQL text (no-sql-injection-in-tool) or eval / vm (no-code-injection-in-tool); the environment or the caller's token in a result, or that token forwarded upstream (no-credential-leak-in-tool); the schema/handler contract (require-tool-input-schema, no-unvalidated-tool-args); one name registered twice (no-duplicate-tool-name).
  • Model-facing text — a tool, prompt or resource description built from text a client, a remote service or a file controls (no-tool-description-injection).
  • HTTP transports — DNS-rebinding protection, allowedHosts and authentication (require-http-transport-hardening), a stateless transport or server shared across requests (no-shared-stateless-transport, CVE-2026-25536), and predictable session IDs (no-predictable-session-id).
  • Clients — a server's tool metadata written into an LLM prompt (no-untrusted-tool-metadata-in-prompt), and a stdio server command taken from a tool argument, a network response or project config (no-untrusted-stdio-command).

Each taint rule follows the value inside its handler — used directly, built into a string, or derived — and resolves sinks to the module that defines them. Tool handlers are this plugin's scope, so on the same line it may report alongside eslint-plugin-node-security (no-shell-injection, detect-non-literal-fs-filename, no-ssrf, detect-eval-with-expression) or eslint-plugin-secure-coding (no-sql-injection), which cover the same sinks outside MCP handlers. Each rule's doc states its overlap.

Usage

// eslint.config.js
import mcpSdkSecurity from 'eslint-plugin-mcp-sdk-security';

export default [
  mcpSdkSecurity.configs.recommended,
];

Or wire the rules yourself:

import mcpSdkSecurity from 'eslint-plugin-mcp-sdk-security';

export default [
  {
    plugins: { 'mcp-sdk-security': mcpSdkSecurity },
    rules: {
      'mcp-sdk-security/require-tool-input-schema': 'error',
    },
  },
];

oxlint

Every rule in this plugin runs on oxlint as well as ESLint:

{ "jsPlugins": ["eslint-plugin-mcp-sdk-security/oxlint"] }

📦 Compatibility

PackageVersion
@modelcontextprotocol/sdknpm
ESLintnpm
Node.jsnode

See the ESLint Version Support Policy for the full matrix.

Rules

Legend

IconDescription
💼Recommended: Included in the recommended preset.
⚠️Warns: Set to warn in recommended preset.
🔧Auto-fixable: Automatically fixable by the --fix CLI option.
💡Suggestions: Providing code suggestions in IDE.
🚫Deprecated: This rule is deprecated.
🟢Type-unaware: AST-only, runs in oxlint JS-plugin tier.
🟡Type-aware (refining): pure-AST primary path; types refine precision.
🟠Type-aware (graceful): requires TS program; silent without it.
RuleCWEOWASPCVSSDescription🧠💼⚠️🔧💡🚫
no-code-injection-in-toolCWE-95A03:2021Disallow an MCP tool argument reaching eval, new Function or a vm context as code.🟢💼
no-command-injection-in-toolCWE-78A03:2021Disallow an MCP tool argument choosing the command a child_process call runs.🟢💼
no-credential-leak-in-toolCWE-200A01:2021Disallow an MCP tool returning the server's environment or the caller's token, or forwarding that token ups…🟢💼
no-duplicate-tool-nameCWE-694A04:2021Disallow registering or listing two MCP tools with the same name on one server.🟢⚠️
no-path-traversal-in-toolCWE-22A01:2021Disallow an MCP tool argument choosing the file an fs call reads, writes or deletes without a containment c…🟢💼
no-predictable-session-idCWE-330A02:2021Disallow an MCP sessionIdGenerator that returns a counter, a timestamp, Math.random() or a constant.🟢💼
no-shared-stateless-transportCWE-488A04:2021Disallow sharing one stateless Streamable HTTP transport or one MCP server across requests.🟢💼
no-sql-injection-in-toolCWE-89A03:2021Disallow an MCP tool argument reaching the text of a SQL query instead of its parameters.🟢💼
no-ssrf-in-toolCWE-918A10:2021Disallow an MCP tool argument choosing the host an outbound HTTP request is sent to.🟢💼
no-tool-description-injectionCWE-1427A03:2021Disallow MCP tool, prompt and resource descriptions built from text a client, a remote service or a file co…🟢💼
no-untrusted-stdio-commandCWE-78A03:2021Disallow an MCP client spawning a stdio server whose command comes from a tool argument, a network response…🟢💼
no-untrusted-tool-metadata-in-promptCWE-1427A03:2021Disallow an MCP client writing a server's tool, prompt or resource metadata into an LLM prompt instead of i…🟢💼
no-unvalidated-tool-argsCWE-20A03:2021Disallow a tool handler reading an argument its declared input schema does not include.🟢💼
require-http-transport-hardeningCWE-346A05:2021Require an MCP HTTP server transport to validate the Host header and a network-reachable MCP server to auth…🟢💼
require-tool-input-schemaCWE-20A03:2021Require an input schema when an MCP tool handler reads arguments.🟢💼

⭐ Support & follow

If this plugin caught a real bug for you, star the repo — stars are the signal that keeps the Interlace ESLint ecosystem maintained — and follow the writeups on Dev.to for the benchmarks and security research behind these rules.

GitHub stars

Part of the Interlace ESLint ecosystem — AI-native rules with LLM-optimized error messages:

Security

PluginDownloadsDescription
eslint-plugin-anthropic-securitydownloadsAnthropic SDK security.
eslint-plugin-browser-securitydownloadsXSS, DOM security.
eslint-plugin-drizzle-securitydownloadsDrizzle security.
eslint-plugin-express-securitydownloadsExpress middleware hardening.
eslint-plugin-gemini-securitydownloadsGoogle Gemini SDK security.
eslint-plugin-jwt-securitydownloadsToken security.
eslint-plugin-knex-securitydownloadsKnex security.
eslint-plugin-lambda-securitydownloadsAWS Lambda hardening.
eslint-plugin-mongodb-securitydownloadsMongoDB injection.
eslint-plugin-mysql-securitydownloadsMySQL security.
eslint-plugin-nestjs-securitydownloadsNestJS framework hardening.
eslint-plugin-node-securitydownloadsServer-side patterns.
eslint-plugin-openai-securitydownloadsOpenAI SDK security.
eslint-plugin-postgresql-securitydownloadsPostgreSQL security.
eslint-plugin-prisma-securitydownloadsPrisma security.
eslint-plugin-secure-codingdownloadsInjection prevention.
eslint-plugin-sequelize-securitydownloadsSequelize ORM security.
eslint-plugin-sqlite-securitydownloadsSQLite security.
eslint-plugin-supabase-securitydownloadsSupabase security.
eslint-plugin-typeorm-securitydownloadsTypeORM security.
eslint-plugin-vercel-ai-securitydownloadsAI SDK security.

Code quality

PluginDownloadsDescription
eslint-plugin-cli-floordownloadsCLI floor for commander, yargs and burgee.
eslint-plugin-conventionsdownloadsTeam-specific habits and styles.
eslint-plugin-import-nextdownloadsFast cycle + import-graph analysis.
eslint-plugin-maintainabilitydownloadsCognitive load and clean-code patterns.
eslint-plugin-modernizationdownloadsESNext migration + syntax evolution.
eslint-plugin-modularitydownloadsStructural integrity and DDD patterns.
eslint-plugin-operabilitydownloadsProduction readiness and resource health.
eslint-plugin-react-a11ydownloadsReact accessibility / WCAG.
eslint-plugin-react-featuresdownloadsReact best practices and optimization.
eslint-plugin-reliabilitydownloadsRuntime stability and error safety.

📄 License

MIT © Ofri Peretz

Building secure JavaScript with Interlace? Star the repo to get new rules and CWE coverage as we ship them — or follow the AI-code-security benchmarks behind them.