javascript-mcp-server
Deterministic MCP server for semantic analysis of JavaScript/TypeScript codebases, including frameworks like Vue, Angular, React, and Node. It provides tools for type checking, code metrics, framework-specific analysis, and quality heuristics via static parsing.
README
javascript-mcp-server
Deterministic MCP server for semantic analysis of JavaScript/TypeScript with interpretation of the Vue, Nuxt, Angular, React, Next, Svelte and Node frameworks.
Inspired by the existing deterministic servers (COBOL, Go, Rust, Python, Java): the server parses, resolves types and normalizes code 100% statically; the LLM only queries already-resolved structures. The AI never interprets the framework directly.
Deterministic mechanism
| Layer | Mechanism |
|---|---|
| JS/TS language | TypeScript Compiler API via ts-morph (AST + TypeChecker + scope) |
| Vue | @vue/compiler-sfc (parse + compileScript with registerTS): resolves defineProps<Props>(), defineProps({}), defineEmits, and the real template bindings (prop/ref/const/function). Also registers defineModel (v-model), useTemplateRef and defineSlots<{...}>() from <script setup>. RegEx fallback for Options API (props: { a: { type, required } } and props: { a: String } forms) |
| Nuxt | Conventions over Vue: pages/ → routes, composables/ and utils/ → auto-imports, server/api → HTTP routes |
| Angular | @angular/compiler (parseTemplate) for real template analysis (inputs/outputs/interpolations/pipes); decorators (@Component, @Input/@Output, DI, lifecycle) and @NgModule/Routes metadata read structurally with ts-morph (RegEx fallback when there is no ts-morph project) |
| React / Next / Svelte | Structure conventions: .tsx/.jsx with JSX, Next app//pages/, .svelte (props/stores/events/lifecycle) and Svelte 5 runes ($state, $derived, $effect, $props, $inspect) |
| Node | ts-morph + detection of express/fastify/koa, node: builtins, process.env |
The ProjectManager keeps an incremental cache: each file is indexed with its size:mtime signature; refresh_js_project only re-reads modified/new files and removes deleted ones, without rebuilding the whole project. Re-loading the same alias (load_js_project) also refreshes incrementally instead of rebuilding.
Requirements
- Node.js ≥ 20
- npm
Evolution roadmap: see
ROADMAP.md.
Installation and build
npm install
npm run build # compiles to dist/
npm start # starts the stdio server
npm run typecheck # type checking
npm test # smoke tests (node:test + InMemoryTransport)
npm run test:snapshots # verifies golden markdown snapshots
npm run test:snapshots:update # regenerates the snapshots (only if the change is intentional)
npm run test:stress # performance and incremental cache over a synthetic project of 240+ files (fixture in tmpdir)
Tools (103)
Projects
load_js_project— loads a directory, detects the framework (if already loaded, does an incremental refresh)list_loaded_projects/unload_js_project/refresh_js_projectprogram_summary— executive summarydetect_framework—vue | nuxt | angular | react | next | svelte | express | fastify | node | plainget_file_content— content of a file by path suffixsearch_source— case-insensitive searchlist_files— TS/JS files with lines, optionally filter by extension (includes.vue)
Language / TypeScript
list_functions— functions and class methods with signaturelist_ts_types— interfaces, type aliases, enums, classeslist_variables— module variablesfunction_call_graph— local call graphfind_references— references to a symbolvariable_xref— data flow of a variable: definition/read/write (semantic classification)function_callers— invocations of a functionresolve_type— definition of a symbolfind_check_implementations— classes that implement/inheritget_type_hierarchy— what a type extends/implements and who uses itinspect_function— signature, parameters, doc and body of a function orClass.methodinspect_class— decorators, extends/implements, fields, methods, constructortypecheck_project— real type errors of the project (TypeChecker diagnostics via ts-morph)
Metrics / technical debt
function_metrics— cyclomatic complexity, body lines and parameters per function/method (with filters)find_high_complexity— functions with high cyclomatic complexity (configurable threshold)find_long_functions— functions with a long body (configurable threshold)
Quality / bug-hunt (heuristics)
find_unchecked_errors— async calls withoutawait/.catch: fetch,fs.*, exec, spawn, query, DB clients andaxios/HTTP; alsomap/forEachover unawaited promises; excludes Node callback variants (fs.writeFile(path, data, cb)); exact callee match and per-line dedupfind_unused_variables— unused module variables (cross-file analysis; exported excluded)find_dead_code— unreferenced functions/methods (cross-file analysis; Angular lifecycle hooks excluded)find_unimplemented_interfaces— interfaces whose methods no class implements explicitlyfind_any_usages— uses ofany(annotations,as any,<any>, arrays, parameters/returns) grouped by file; type debt
Vue
list_vue_components/analyze_vue_component(props, emits, slots, composables, reactive state, provide/inject;defineModel→v-modelsection,useTemplateRef→Template refssection,defineSlots→Slotssection)vue_template_binding_analysis— which script variables the template uses, classified with the compiler's real bindings (prop/ref/const/function)find_vue_provide_inject— cross-file provide/inject graph by key (resolves exported constants, detects orphan keys)find_vue_unused_reactive— declared reactive state unused in template/script (heuristic)find_vue_template_undefined— template identifiers without binding/local/builtin (heuristic)
Nuxt
list_nuxt_pages— routes frompages/+server/apilist_nuxt_composables/list_nuxt_server_api/list_nuxt_plugins_middlewarenuxt_auto_imports/nuxt_configlist_nuxt_page_meta—definePageMetaper page (layout, middleware, title, validate, pageTransition)
Angular
list_angular_components/analyze_angular_component(Input/Output, DI, lifecycle)angular_template_analysis— template analysis with@angular/compiler(inputs/outputs/interpolations/pipes/structural directives + references without a class member)angular_dependency_graph— @Injectable services and consumerslist_angular_routes/list_angular_modules/list_angular_servicesangular_module_graph— NgModules (declarations, imports, providers)analyze_angular_route_guards— route guards/resolvers (canActivate/canActivateChild/canActivateFn/canDeactivate/canLoad/canMatch/resolve) and their definitionslist_angular_standalone_components— standalone components (composition imports) vs non-standalone (NgModule)find_angular_change_detection— ChangeDetectionStrategy (OnPush/Default) and manual CD (heuristic)find_angular_subscription_leaks— subscribe() without unsubscribe/takeUntil/async pipe (heuristic)
React / Next / Svelte
list_react_components— .tsx/.jsx components with JSX, exports and used hooksanalyze_react_component— deep analysis of a component: typed props, hooks with arguments, custom hooks, early returns, memo/forwardRef and contextslist_react_hooks_deps— useEffect/useMemo/useCallback with their deps array (heuristic: flags missing deps)list_react_context— cross-file contexts: createContext, providers and useContext consumerslist_next_routes— app router routes (app/**/page.tsx) and pages routerlist_next_api_routes— API routes (app/**/route.ts) with HTTP methods andmiddleware.tsanalyze_react_state— state inventory per component: useState/useReducer/useRef with bindingsfind_react_effect_leaks— useEffect with listeners/timers/subscriptions without cleanup (heuristic)list_next_data_fetching— ISR/cache in app router: revalidate, generateStaticParams, generateMetadata, fetch with next.revalidate/tags and use client/server directivesfind_react_memo_opportunities— components with non-primitive props without memo() and JSX with new values per render (heuristic)list_svelte_components— .svelte components with props, stores and dispatched eventsanalyze_svelte_component— deep analysis of a Svelte component: props, reactivity ($:), Svelte 5 runes ($state/$derived/$effect/$props/$inspect/…), stores, context, lifecycle, bindings, snippets and dispatched eventslist_sveltekit_routes— SvelteKit routes by directory convention (src/routes): +page, +page.server (load/actions), +layout, +server.ts (API) and +errorfind_svelte_effect_leaks— onMount with listeners/timers/subscriptions without cleanup in onDestroy (heuristic)find_svelte_unused_stores— stores (writable/readable/derived) unused in any template or script (heuristic)list_sveltekit_server_hooks— hooks.server.ts: handle (sequence), handleError and handleFetch with their structurelist_sveltekit_load_actions— load and actions per route with details (throw error/fail/redirect/params)list_react_files— .tsx/.jsx/.svelte files with lines
Node
list_api_endpoints— Express/Fastify/Koaanalyze_api_endpoint— handler call chain (→ service → repo), validation, auth middleware and next(err); resolves mounted routerslist_express_routers— sub-routers, mounts, global middleware in order and error-handlers (4 args)node_native_modules/node_entry_points/node_async_flownode_process_env— variables read withprocess.env(dot/bracket), crossed with the root.env*files: flags defined keys (✓) and undefined keys (⚠ must be set in the environment/CI), and lists.envkeys without any read in the code (orphans)find_event_emitter_leaks— EventEmitter listeners without their cleanup pair in scope (heuristic)find_sync_io_blocking—fs.*Syncin handlers/async that blocks the event loop (heuristic)find_unclosed_resources— streams/connections/http.request without close/end/destroy (heuristic)find_deprecated_apis—new Buffer,url.parse,util.is*,createCipher,require.extensions(heuristic)
Cross-framework
module_dependency_graph— relative imports/requires graph between modules, with cycles and modules without importersfind_test_mapping— production modules (src/) → tests that import them, and src/ without tests
Security and robustness (heuristics)
find_xss_vectors— XSS vectors: v-html (Vue),{@html}(Svelte), dangerouslySetInnerHTML (React), innerHTML/insertAdjacentHTML/document.writefind_sql_injection— query/execute with interpolated template literal or string concatenationfind_eval_sites— eval / new Function / Function() (dynamic execution)find_command_injection— exec/execSync/spawn with variable interpolationfind_hardcoded_secrets— keys/passwords/tokens with literal value, URLs with credentials, private keys and AWS keysfind_insecure_http— http://, ws:// WebSocket and cookies without Secure/HttpOnlyfind_silent_catches— empty catches, console-only, or without error binding (discarded error)find_event_listener_leaks— addEventListener/setInterval without removeEventListener/clearInterval in the same scope
Technical debt and quality (heuristics)
find_code_duplication— duplicated code blocks (copy-paste) between functions/methodsfind_todo_fixme— TODO / FIXME / HACK / XXX markers in commentsfind_unused_dependencies— package.json dependencies never imported in any filefind_ts_ignores— type suppressors @ts-ignore / @ts-nocheck / @ts-expect-errorfind_magic_numbers— numeric literals that are not 0/1 outside named constants
TypeScript types in depth (heuristics)
find_non_null_assertions— non-null assertionsexpr!(trust without verification)find_unsafe_type_casts—as any,as neverand double castas unknown as Xfind_loose_generics— type parameters without constraint or unused in the bodyfind_untyped_exports— exported functions/methods without return type or unannotated params
Limitations and heuristics
- The bug-hunt tools (
find_unchecked_errors,find_unused_variables,find_dead_code,find_unimplemented_interfaces) are heuristics by design: they flag "possible" dead code and can produce false positives/negatives (indirect use via decorators, template refs or dynamic calls). The reference count is cross-file over the real AST (ts-morph), notgrep. find_dead_codeexcludes exported symbols and Angular lifecycle hooks (ngOnInit, etc.), which are invoked by the framework.find_dead_code/find_unused_variablesalso count identifiers from templates (.htmlin Angular,<template>block in Vue/Nuxt): a method used only from the template is not reported as dead.find_unimplemented_interfacesis heuristic: in TypeScript interface satisfaction is structural, so a class can satisfy one without declaring it inimplements. Empty interfaces and those extended by another interface are discarded.find_any_usagesis a type-debt heuristic: it detects ts-morph's semanticanynodes (: any,as any,<any>,any[], parameters/returns). It does not distinguish intentionalany(e.g. ananyat the boundary with untyped libraries) from accidental; it groups by file sorted by number of uses.find_unchecked_errorsonly considers known callees (fetch,fs.*, exec, spawn, query, DB client verbs…) and requires the line to be free ofawait/.catch/.then/Promise.all. Generic HTTP verbs (get,post,put,patch,delete,head,options) only count when the receiver is HTTP/axios (axios,http(s),client,request,api) — somap.get(...)is not flagged. It also detectsmap/forEachthat fire unawaited promises (fire-and-forget), excluding those already handled withawait/Promise.all/.catchon the same line. Node callback variants (fs.writeFile(path, data, cb),fs.readFile(p, cb)) are excluded because the callback receives the error.variable_xrefclassifies DEFINITION/WRITE/READ with ts-morph semantic references (findReferences); it is not interprocedural flow analysis.angular_template_analysisreports template identifiers without a class member. Members are resolved via ts-morph (incl.@Input/@Output, methods, getters/setters, constructor parameters); if there is no ts-morph project a RegEx fallback is used that can miss cases. Template pipes are resolved to the project's@Pipe/@Directiveclass (by class name or by the decorator'sname) and excluded from the "without a member" section; the realparseTemplateerrors are shown in "Compiler diagnostics".@Componentmetadata (analyze_angular_component,list_angular_components) is read structurally with ts-morph, with RegEx fallback.detect_frameworkis heuristic overpackage.json+ directory structure. A project that uses@vue/compiler-sfconly as a build dependency (without SFCs in the app code) is no longer classified as Vue. React is detected by dependency + presence of.tsx/.jsx; Next/Svelte by dependency.list_fileswithext='.vue'lists SFCs by directory walk (ts-morph does not parse.vue); the rest of the extensions come from the ts-morph project.inspect_functionandresolve_typeresolve top-level functions, nested functions andClass.methodmethods; arrow-functions are only shown ininspect_function.- The analysis does not run
npm installon the analyzed project: it only readspackage.json,tsconfig.jsonand the source code. - Vue SFC parsing is cached by
size:mtimeMssignature (same criterion as the ProjectManager): SFCs are not re-parsed on every tool call. analyze_vue_component: theComposablessection lists each composable once (dedup);defineSlotsis extracted by finding the real}>()closing so it does not cut on nested types ({ title: string }), anddefineModelsupports generics (defineModel<string>()).analyze_svelte_component: theRunes (Svelte 5)section lists the lines with runes ($state,$derived/$derived.by,$effect/$effect.pre,$props,$inspect,$bindable); the$:(classic reactivity) stay in their own section. Svelte 5 converts$:into runes, but they are not translated into each other: each syntax is reported where it appears.
Distribution (single-file)
The server can be packaged into a single self-contained JS file that includes all the
dependencies (TypeScript, ts-morph, Vue/Angular compilers). On the destination only Node ≥ 20
is needed — no npm, no node_modules, no copying the directory:
npm run dist:bundle # generates release/javascript-mcp-server.cjs (~26 MB)
./release/javascript-mcp-server.cjs # executable, shebang included
- It is the same server (103 tools), verified with stdio smoke:
initialize,tools/list, project loading, Vue analysis with@vue/compiler-sfcand semantic analysis with ts-morph. - The
--externalare the optional template-engines that@vue/compiler-sfctries torequirelazily inside try/catch (twig, ejs, pug, handlebars, …); they are not used and do not affect the tools. - The bundle is CJS (
format=cjs): even if the project is ESM, the final file is a single.cjs. - The
release/directory is not versioned; regenerate it with the script after each change.
MCP client configuration
{
"mcpServers": {
"javascript": {
"command": "node",
"args": ["/path/to/javascript-mcp-server/dist/index.js"]
}
}
}
Or using the single-file bundle:
{
"mcpServers": {
"javascript": {
"command": "/path/to/javascript-mcp-server/release/javascript-mcp-server.cjs"
}
}
}
Structure
src/
├── index.ts # MCP server + tool registration
├── project-manager.ts # project loading, framework detection, ts-morph cache
├── analysis.ts # language semantic engine (ts-morph) + cross-framework bug-hunt
├── markdown.ts / version.ts
└── ast/
├── vue.ts # Vue interpretation (+ SFC cache by signature)
├── nuxt.ts # Nuxt conventions
├── angular.ts # Angular interpretation
├── react.ts # React / Next
├── svelte.ts # Svelte / SvelteKit (leaks, stores, hooks, load/actions)
├── node.ts # Node/Express/Fastify
├── security.ts # security (XSS, injection, secrets, …)
├── debt.ts # technical debt (duplication, unused deps, magic numbers)
├── cross.ts # module_dependency_graph and find_test_mapping
└── types.ts # TypeScript types in depth (non-null, casts, generics, exports)
test/
├── smoke.test.ts # smoke tests via InMemoryTransport
├── snapshot.test.ts # golden markdown snapshots (regenerate with npm run test:snapshots:update)
├── stress.test.ts # performance/incremental cache (npm run test:stress; generates the fixture in tmpdir)
├── generate-stress.ts # generator of the synthetic project of 240+ files used by stress.test.ts
├── snapshots/ # golden tool outputs
└── fixtures/ # example projects (vue-basic, vue-deep, nuxt-basic, nuxt-deep, angular-basic,
# angular-deep, react-basic, react-next-deep, next-basic, svelte-basic, sveltekit-basic,
# svelte-deep, node-express, node-deep, ts-deep, cross-modules, security-vulns,
# debt-vulns, js-pure, type-errors, callgraph-basic)
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。