mcp server
mitre-cwe-mcp-server
Explore MITRE CWE weaknesses and CAPEC attack patterns, mitigations, code examples, and mappings via MCP. STDIO or Streamable HTTP.
Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- Node.js 20 or newer
{
"mcpServers": {
"mitre-cwe-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/mitre-cwe-mcp-server"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 24, 2026Public Hosted Server: https://mitre-cwe.caseyjhand.com/mcp
Overview
MITRE's CWE and CAPEC catalogs connect software and hardware weaknesses with attack mechanics. Search root causes, inspect mitigations and code examples, navigate CWE views and live hierarchies, and follow recorded CWE → CAPEC → ATT&CK mappings.
Tools
| Tool | Description |
|---|---|
cwe_list_reference | Discover views, filter vocabulary, workflow guidance, and catalog refresh health |
cwe_get_weakness | Retrieve CWE weaknesses or categories with selected sections and complete example pages |
cwe_get_attack_pattern | Retrieve CAPEC attack patterns, categories, and views: prerequisites, execution steps, mitigations, members, and recorded mappings |
cwe_search_weaknesses | Search weaknesses by text, platform, abstraction, consequences, status, mapping usage, view, taxonomy mapping (CERT C ARR30-C), or observed-example CVE |
cwe_search_attack_patterns | Search CAPEC by text, CWE or ATT&CK mapping, abstraction, severity, or likelihood |
cwe_get_view | Read a CWE view's metadata and direct members in published order |
cwe_get_hierarchy | Traverse live CWE parents, children, ancestors, or descendants within a view |
Capability reference
cwe_list_reference tool
topic:views,abstraction_levels,mitigation_phases,platforms,relationship_natures,filter_values,workflow, orversions; optional all-tokenfilteron labels, using the word-start and bounded-prefix rule below (scriptfinds JavaScript)viewslists every CWE view with its direct member count, and a filter-defined view'sfilterDefinitionfilter_valueslists weakness statuses, mapping usage, and taxonomy names, consequence impacts, and CAPEC statuses, severity, and likelihood- Lists page with
limit(default 20, max 100) andpagination.nextCursor;versionsadds each loaded catalog's version, date, counts, and refresh errors
cwe_get_weakness tool
- 1–200 CWE IDs (
CWE-79,CWE79,cwe 079,CWE_79, or79); up to 20 distinct items are processed per call and the rest return indeferredIds. A malformed item comes back innotFoundwithout failing the batch; only an item holding a control character other than whitespace, or a non-ID item over 150 characters, rejects the call sections:summary,consequences,mitigations,relations,examples,detection,observed,platforms,mappings,notes(default: the first four);[]returns an outlinesummaryincludes recorded alternate terms (XSS), ordinalities (Primary, Resultant, Indirect), and background details,platformsadds functional areas and affected resources, andrelationsnames each related weakness.notesreturns every note MITRE records for weaknesses and categories, such as Relationship, Maintenance, Terminology, and Research Gap notesentries[].kindisfull,partial(default sections that did not fit the response budget are listed inoutlinewith their sizes, andnoticegroups re-calls by their complete response size, keeping example parameters only on the examples group), oroutline;notFound[].reasonisnot_found,wrong_type(a view, which belongs tocwe_get_view, or a prefixed ID of the other catalog), orinvalid_id(an item that is no ID, echoed trimmed;NVD-CWE-noinfoandNVD-CWE-Otherget their own guidance). Categories resolve here- Examples filter by
exampleLanguageand page withexampleOffset(default 0),exampleLimit(default 3, no fixed cap), andexamplePage.nextOffset. Withsectionsomitted, setting any of the three to a non-default value addsexamplesafter the defaults (outlined with its page size and a re-call when it does not fit); explicitsectionswithoutexamplesignore them, andguidancegives the re-call that addsexamples. Each example keeps its ordered prose and code, with code laid out as MITRE's pages show it (4 spaces per indentation level), and lists the references it cites inreferences
cwe_get_attack_pattern tool
- 1–200 CAPEC IDs (
CAPEC-66,CAPEC66,capec_066, or66), Deprecated and Obsolete included; up to 20 distinct items per call, the rest indeferredIds sections:summary,prerequisites,execution,skills,consequences,mitigations,examples,relations,mappings,notes(default: summary, prerequisites, execution, mitigations, and mappings for patterns; summary and relations for categories and views);[]returns an outlineentries[].typeisattack_pattern,category, orview, and only patterns carryabstraction. A category or view'srelationslist its directmembersin source order, or for a filter-defined view its source XPath asfilterDefinition; itsmappingsandnotescarry the recorded taxonomy mappings, references, and MITRE notes- Start at view
CAPEC-1000(Mechanisms of Attack) orCAPEC-3000(Domains of Attack) to browse patterns by category - Same
entries[].kindandnotFoundcontract ascwe_get_weakness; CAPEC patterns, categories, and views all resolve here, sowrong_typemarks only a prefixed CWE ID. Mappings keep the recorded CWE and ATT&CK IDs
cwe_search_weaknesses tool
- Optional all-token
filterover the name, MITRE's recorded alternate terms (XSS,ReDoS,UAF), the description, and the extended description, plus exactlanguage,technology,abstraction,consequenceImpact,status,mappingUsage,taxonomyName,taxonomyEntryId,observedCveId, andviewId; no filters browses the catalog - A
filtertoken matches at a word start, after_, or at a camelCase hump (dosfinds ReDoS). Tokens of at least four Unicode letters also match after exactly oneunormisprefix at a word start (trustedfinds untrusted;configfinds misconfiguration). Prefixes are never stripped recursively; spelling coincidences remain possible. Other compounds are searched as written:serializationdoes not find CWE-502,deserializationdoes. A token ending in a digit never matches before another digit (79skips RFC 793) - Each result carries MITRE's
mappingUsage, such asAllowed,Allowed-with-Review, orProhibited, which says whether the entry may be used to map a vulnerability taxonomyName(such asCERT C Secure CodingorISA/IEC 62443) andtaxonomyEntryId(such asARR30-CorA1, any case) find the weaknesses that record a taxonomy mapping, both holding on one mapping when given together;observedCveId(such asCVE-2021-44228) finds the weaknesses MITRE cites that CVE on as an observed example, not NVD's CVE-to-CWE assignments. Each result then lists every mapping (matchedTaxonomyMappings) or observed example (matchedObservedExamples) that matchedviewIdincludes same-view membership closure, or for a filter-defined view the weaknesses its source XPath filter selects (CWE-658 C, CWE-702 Implementation, …). Categories are excluded; every status is included by default- Ranked by all tokens in the name or in one alternate term, then in the description, then any other match, then numeric ID; previews hold the first sentence, and
cwe_get_weaknessreturns the terms insummary.limitdefault 20, max 100; continue withpagination.nextCursor
cwe_search_attack_patterns tool
- Optional all-token
filterover the name, recorded alternate terms (MITM), and the description, using the same word-start and bounded-prefix rule ascwe_search_weaknesses, pluscweId,attackTechniqueId,abstraction,severity, andlikelihood; CWE mappings match exactly, and a parent ATT&CK technique includes its recorded subtechniques includeInactive(defaultfalse) adds Deprecated and Obsolete patterns. Ranked by all tokens in the name or in one alternate term, then in the description, then any other match, then numeric ID;cwe_get_attack_patternreturns the terms insummary.limitdefault 20, max 100; continue withpagination.nextCursor
cwe_get_view tool
- One view
id(fromcwe_list_referencetopicviews);limitdefault 20, max 100, continued bypagination.nextCursor - Objective, audience, status, filter definition, recorded notes, and direct
membersin published order. Navigation views list only top-level members;cwe_get_hierarchyreaches descendants - A filter-defined view lists no members:
filterDefinitionis its source XPath, andcwe_search_weaknesseswith itsviewIdreturns the weaknesses that filter selects. A filter with a part the server does not evaluate is named as such inguidance, and that search returns none with a notice found: falsecarriesnot_foundorwrong_type
cwe_get_hierarchy tool
- One CWE
idand adirection:parents,children,ancestors, ordescendants;viewIddefaults to1000, orallfor every view.primaryOnlyapplies to ancestors only. Parents and children include category and view relations and match the first level of the same view's tree - View-scoped
nodes, parent-to-childedges,found,retrievedAt, andhierarchyFingerprint. Empty relations succeed; upstream failures are errors, and a temporary MITRE refusal (HTTP 403) is retryable after a few minutes. Node names come from the loaded catalog and can lag the live API - The total deadline includes queue wait; expiry is retryable
hierarchy_timeout, while caller cancellation is nonretryable. Source-recordedrelationsremain available throughcwe_get_weakness, but do not replace live children or descendants limitdefault 20, max 100 edges; each page lists only the nodes its edges reference, plus any root without edges on the first page. Eachpagination.nextCursorcall re-fetches the traversal;invalid_cursormeans the topology or catalog changed, so restart without a cursor
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
MITRE-specific:
- No API key. Both XML catalogs load into memory before the server accepts requests. Each successful download is saved to a cache directory (
CWE_CACHE_DIR), and a later start loads the saved copy without waiting on MITRE, so a restart works while MITRE is unreachable. The first start, or any start without a usable saved copy, needs MITRE's CWE and CAPEC download sources - CWE checks for a new version every 24 hours and CAPEC refreshes weekly; a catalog loaded from the cache is checked right after start and, while those checks fail, again after 5, 10, 20, 40, then every 60 minutes. A failed refresh keeps the loaded data and shows in
cwe_list_referencetopicversions, which also reports whether each catalog came from the cache or a download - MITRE can refuse a burst of requests from one address with HTTP 403 for a few minutes. Catalog downloads, version checks, and hierarchy calls report it as a temporary, retryable failure and do not retry it immediately
- Hierarchy calls go to the live CWE REST API and keep multiple parents and view identity; search and detail run against the local catalogs
- MITRE statuses and absent sections stay explicit. CAPEC mappings and execution flows are incomplete: a missing mapping does not establish that no relationship exists, or that an ATT&CK ID is current
Agent-friendly output:
- Provenance on every response: catalog versions and dates, load time, source links, and attribution
- A 24,000-byte budget across both output surfaces, enrichment included. Whole IDs, items, or edges defer to the next call, and a default detail selection omits whole sections that do not fit, naming them for a re-call; explicit selections stay complete, and a single record or item over budget returns whole with a notice
- Continuation through
deferredIds,pagination.nextCursor, orexamplePage.nextOffset; stale cursors fail withinvalid_cursor, unknown vocabulary withunknown_filter, whose message names the field and value and lists the supported values or thecwe_list_referencetopic that does - CWE and CAPEC ID inputs accept an optional prefix in any case, followed by
-,_, a space, or nothing, and drop leading zeros. ATT&CK technique IDs takeTddddorTdddd.ddd, with or without theTin either case (T1059,t1059.001,1059). A malformed single ID is an invalid argument whose message names the accepted forms content[]andstructuredContentcarry the same values, ordered example code included. Catalog prose and code are reference data, never instructions
Getting started
Public Hosted Instance
A public instance is available at https://mitre-cwe.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"mitre-cwe-mcp-server": {
"type": "streamable-http",
"url": "https://mitre-cwe.caseyjhand.com/mcp"
}
}
}
Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"mitre-cwe-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/mitre-cwe-mcp-server@latest"],
"env": { "MCP_TRANSPORT_TYPE": "stdio", "MCP_LOG_LEVEL": "info" }
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"mitre-cwe-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/mitre-cwe-mcp-server@latest"],
"env": { "MCP_TRANSPORT_TYPE": "stdio", "MCP_LOG_LEVEL": "info" }
}
}
}
Or with Docker:
{
"mcpServers": {
"mitre-cwe-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "-v", "mitre-cwe-cache:/usr/src/app/.cache", "ghcr.io/cyanheads/mitre-cwe-mcp-server:latest"]
}
}
}
The named volume keeps the catalog cache across --rm containers, so a later start does not need MITRE.
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp after both catalogs load
Prerequisites
- Bun v1.4.0 or higher (or Node.js v24+).
- Outbound HTTPS access to
cwe.mitre.organdcapec.mitre.orgfor catalog downloads (at least once, to fill the cache), andcwe-api.mitre.orgfor version checks and live hierarchy calls.
Installation
- Clone the repository:
git clone https://github.com/cyanheads/mitre-cwe-mcp-server.git
- Navigate into the directory:
cd mitre-cwe-mcp-server
- Install dependencies:
bun install
- Configure environment:
cp .env.example .env
# edit .env for optional transport, authentication, and logging settings
Configuration
No environment variables are required. Catalog sources, refresh intervals, and response limits are fixed; framework storage settings do not persist these catalogs.
| Variable | Description | Default |
|---|---|---|
CWE_CACHE_DIR | Directory for the last good CWE and CAPEC downloads (cwec_latest.xml.zip, capec_latest.xml, each with a .json record). A relative path resolves against the working directory. To seed an empty cache while MITRE is unreachable, copy downloaded files in under those names. | mitre-cwe-mcp-server under the user cache directory (~/Library/Caches, %LOCALAPPDATA%, or $XDG_CACHE_HOME / ~/.cache); /usr/src/app/.cache in Docker |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_HTTP_HOST | HTTP bind address. | 127.0.0.1 |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. | stateless |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.). | info |
LOGS_DIR | Directory for log files (Node.js only). | <app-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry. | false |
See .env.example for the full list of optional overrides.
Running the server
Local development
-
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Project structure
| Directory | Purpose |
|---|---|
src/mcp-server/tools/definitions | Seven read-only tools. |
src/mcp-server/tools | Shared output schemas, section projection, budgets, and pagination. |
src/config | Server environment configuration (CWE_CACHE_DIR). |
src/services/catalog | Catalog acquisition, the last-known-good cache, XML normalization, indexes, refresh lifecycle, and live hierarchy. |
tests/ | Unit and integration tests, mirroring the src/ structure. |
docs/ | Design and generated directory reference. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor logging,ctx.statefor storage - Register new tools and resources in the
createApp()arrays insrc/index.ts - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
License
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
CWE data: Copyright © 2006–2026, The MITRE Corporation. CAPEC data: Copyright © 2007–2026, The MITRE Corporation. CWE and CAPEC are MITRE trademarks; their data licenses and disclaimers are reproduced in THIRD_PARTY_NOTICES.md.