Semantic JS MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Semantic JS MCPfind references to the authenticate function in src/"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Semantic JS MCP
Your coding agent is only as good as its understanding of your codebase.
Coding agents can generate code quickly, but reliable engineering requires more than reading files and matching text. They need to understand which declaration a reference belongs to, how symbols cross workspace boundaries, whether the collected evidence is complete, and whether that evidence is still accurate.
Semantic JS MCP gives coding agents structured, read-only semantic context so they can navigate, review, and change code with explicit uncertainty.
Better agents begin with better evidence.
It supports the JavaScript ecosystem, including TypeScript, JavaScript, TSX, JSX, Node module variants, and Vue projects. Language servers provide the underlying semantic data, which the server turns into structured results designed for coding agents.
For each file, it identifies the owning workspace and uses the corresponding TypeScript or Vue language server. Across the repository, it can distinguish verified references from unrelated or unresolved text matches. These results complement text search, source inspection, and focused tests.
Project Status
Version 0.8.1 is the current release. APIs and result contracts may evolve while the project remains on the 0.x release line. See the roadmap for areas under consideration.
Related MCP server: Axon
Installation
Codex plugin
Add the public marketplace, then install the plugin:
codex plugin marketplace add elnonathan/semantic-js-mcp
codex plugin add semantic-js-mcp@elnonathanCodex CLI 0.144.4 or newer is required for npm-backed marketplace installation. Start a new Codex session after installation. The plugin bundles both the MCP server configuration and the semantic-navigation skill.
MCP executable
Install the package globally when using an MCP host that accepts a command-based stdio configuration:
npm install --global semantic-js-mcp
semantic-js-mcp doctorConfigure the host to run semantic-js-mcp serve.
Runtime
Node.js 22 or newer is supported.
Node.js 24 LTS is recommended for new installations. See the Node.js release schedule.
rg(ripgrep) must be available onPATHfor repository-wide discovery.The nearest workspace TypeScript SDK is used when available; the bundled TypeScript SDK is the fallback.
TypeScript,
typescript-language-server, and the Vue language server are pinned dependencies. Published packages bundle every production dependency so Codex installations do not require a separate dependency installation step. Source checkouts usenpm ci; startup verifies provider entry points before accepting MCP requests.Source discovery and language selection include
.ts,.tsx,.mts,.cts,.js,.jsx,.mjs,.cjs, and.vuefiles.Run
npm run check:runtimeto report every required component and its resolved file path.
The package exposes a semantic-js-mcp executable. semantic-js-mcp serve starts the stdio MCP server, and semantic-js-mcp doctor verifies the installed Node runtime, ripgrep, resolved provider paths, MCP startup, tool discovery, TypeScript reference accounting, diagnostic freshness, and Vue navigation.
Development Setup
From a source checkout:
npm ci
npm run check
npm run check:runtime
npm run doctor
npm run smoke:ci
npm run smoke
npm run smoke:vueRun npm run benchmark after changes to scanning, references, caching, lifecycle, or memory. Normal analysis is local and read-only; it does not require network access after dependencies are installed.
For an MCP host that accepts a direct stdio configuration, point it at the checked-out server using an absolute path:
{
"mcpServers": {
"semantic-js-mcp": {
"command": "node",
"args": ["/absolute/path/to/semantic-js-mcp/server.mjs"]
}
}
}The bundled .mcp.json provides the relative-path configuration used when the repository is installed as a Codex plugin.
When the package executable is available on the host's PATH, the equivalent stdio configuration is:
{
"mcpServers": {
"semantic-js-mcp": {
"command": "semantic-js-mcp",
"args": ["serve"]
}
}
}Tool Graph
Tools are ordered from smaller responses to deeper evidence:
Tool | Provides | Typical continuation |
| Structure for one file |
|
| Symbol-name discovery |
|
| Definition resolution at a position |
|
| Inferred type and documentation |
|
| Focused diagnostics for one file |
|
| Exact identifier text count without semantic verification |
|
| Definition and reference counts by name |
|
| Reference counts at a position |
|
| Composed summary by symbol name |
|
| Composed summary at a position |
|
| First page of verified locations |
|
| A later page from the same collection |
|
| Unresolved candidates with locations and literal reasons |
|
Composite audits reuse the same internal definition, hover, and reference primitives as the narrow tools. Compatible count, audit, and reference calls reuse a short-lived reference set.
Result Contract
Every successful result contains:
server: the literal semantic-js-mcp server name and version that produced the response.resultSchema: the literal canonical result schema name and version.request: normalized inputs and explicit limit interpretation.result: evidence produced by the tool.collection: how evidence collection completed.presentation: how much collected evidence appears in this response.continueWith: exact MCP tool names that can add the next kind of evidence.
structuredContent is the canonical JSON object. The text content is YAML generated from that same object and parses back to the same data.
Collection status
complete: the requested collection scope completed and every discovered item was classified.limited: a suppliedmaxCandidatesormaxDefinitionsvalue stopped collection.partial: collection completed with explicitly reported items whose definition or owning file could not be resolved.failed: the tool call failed and the error object explains why.
Collection and presentation are independent. A complete collection may use presentation.mode: page, count-only, summary-by-file, or subset without weakening its counts.
For reference results, includeDeclaration: false excludes locations that resolve to the requested declaration. It never excludes the source position merely because that position initiated the query. The reported invariant is verifiedTotal = foundByOwningWorkspaceLanguageServer + verifiedFromOtherWorkspaces after declaration filtering and deduplication.
Vue template definitions
Definition lookup uses the Vue language server and TypeScript server first. If both leave a Vue template tag unresolved, the server parses the SFC and follows only a matching local import from <script> or <script setup>. A successful fallback reports resolutionMethod: vue-template-import-binding-definition. This proves an imported component binding; it does not infer global component registration or filename-based identity.
The Vue parser and TypeScript AST dependencies are loaded lazily only when this fallback is needed.
Signature source
Position audits first request hover information at the query position. If that position has a resolved definition but no hover information, the audit requests hover at the resolved declaration. signatureSource reports query-position-hover, resolved-definition-hover, or not-reported; signatureDefinition identifies the declaration used by the fallback.
Limits
Collection limits accept positive integers only:
omitted:
{mode: unlimited}supplied:
{mode: maximum, maximum: N}
Omitting maxCandidates or maxDefinitions requests unlimited collection. pageSize and maxResults only control returned items for tools that expose them as presentation parameters.
Text-match accounting
Repository verification reports:
matchesFoundmatchesCheckedmatchesToRequestedSymbolmatchesToDifferentSymbolsmatchesWhoseDefinitionCouldNotBeResolvedaccountingStatus: complete | incomplete
accountingStatus: complete means every discovered text match appears in exactly one classification. Unresolved matches remain explicit and make semantic collection partial.
Count and audit responses expose the referenceSetId and unresolved-candidate count. Use lsp_unresolved_reference_page to inspect those candidates without inflating every summary. The server also queries tsserver projectInfo for unresolved candidates and reports whether the file belongs to a configured or inferred TypeScript project. Reasons describe only observed behavior; they do not speculate that an alias caused a failure.
Freshness
Reusable reference sets store SHA-256 fingerprints for the source file, native reference files, every cross-workspace candidate file, and the relevant package.json, tsconfig.json, or jsconfig.json files. They also store a repository source-inventory fingerprint built from every relevant path, file size, and high-resolution modification time. Reuse and pagination verify both layers, so new, deleted, renamed, or normally modified source files invalidate repository-wide completeness. Changed evidence produces REFERENCE_SET_CONTENT_CHANGED and requires a new lsp_references collection. Expired or evicted sets produce REFERENCE_SET_NOT_FOUND_OR_EXPIRED.
The inventory is sampled before and after collection. If repository sources change during collection, the server retries once and then returns REPOSITORY_CHANGED_DURING_COLLECTION instead of publishing an unstable result.
Diagnostics clear their cache on didChange and report the analyzed document version and SHA-256 content fingerprint. Only a language-server report for that exact document version appears under diagnosticsForCurrentDocument. Otherwise that field is null, evidence.status is untrusted, and any unconfirmed report is isolated under unconfirmedDiagnosticReport. Untrusted diagnostics always produce a partial collection.
Diagnostic severities are preserved literally. If a language server omits severity, the result reports not-reported; it is not silently treated as information, warning, or error.
CI policy adapter
MCP tools report evidence; they do not decide whether a code change passes. npm run ci:evaluate -- <result.json> applies a deterministic CI policy to one canonical structured result:
pass, exit0: complete evidence and no verified error diagnostic.fail, exit1: verified diagnostics contain an error.untrusted, exit2: collection is partial or limited.blocked, exit3: the tool failed or the input is not a semantic-js-mcp result.
Pass --yaml after the input path for a YAML representation. The adapter accepts canonical JSON or YAML, validates the server and result-schema identity plus public tool and presentation literals, and never converts incomplete evidence into a pass.
Installation doctor
semantic-js-mcp doctor returns a structured installation report with the same deterministic status vocabulary and exit codes as the CI adapter:
pass, exit0: every installation and semantic fixture check passed;fail, exit1: the server ran, but a functional check returned the wrong result;untrusted, exit2: runtime checks passed, but a provider did not confirm current diagnostic evidence;blocked, exit3: a runtime requirement, provider component, or MCP startup step was unavailable.
Use semantic-js-mcp doctor --yaml for a YAML representation. An untrusted result is not converted to a package failure by the distribution smoke test, but the reason remains explicit in the report.
Cost visibility
lsp_count_text_matches scans repository text without issuing per-match semantic requests. Use it to measure common identifiers before requesting verified counts or audits. Semantic collections preserve omitted limits as unlimited and report text-search time, semantic-verification time, semantic request count, and maximum concurrency. There is no hidden candidate cap.
The bundled Codex MCP configuration allows up to 300 seconds for one tool call. Reaching a client or language-server timeout returns a failed call; it never changes collection scope or reports a timed-out collection as complete.
Memory Management
Language-server clients and reusable reference sets are released automatically using idle timeout, TTL, and LRU policies. These policies affect reuse only; they do not cap a collection being computed.
Environment variables:
SEMANTIC_JS_MCP_CLIENT_IDLE_TIMEOUT_MSdefault60000SEMANTIC_JS_MCP_CLIENT_MINIMUM_EVICTION_AGE_MSdefault15000SEMANTIC_JS_MCP_MAXIMUM_ACTIVE_CLIENTSdefault4SEMANTIC_JS_MCP_REFERENCE_SET_TTL_MSdefault300000SEMANTIC_JS_MCP_MAXIMUM_REFERENCE_SETSdefault12SEMANTIC_JS_MCP_MAXIMUM_CHANGED_REFERENCE_SET_MARKERSdefault24SEMANTIC_JS_MCP_MAXIMUM_CACHED_REFERENCE_LOCATIONSdefault50000SEMANTIC_JS_MCP_DEFAULT_REFERENCE_PAGE_SIZEdefault100SEMANTIC_JS_MCP_CROSS_WORKSPACE_CONCURRENCYdefault6
A single reference collection may exceed the cache-location budget so it can still be paged. Older collections are evicted first.
Verification
npm run check
npm run check:runtime
npm run doctor
npm run smoke
npm run smoke:ci
npm run smoke:vue
npm run smoke:distributionnpm run benchmark measures text counting, verified reference collection, memory, and freshness-validation latency at configurable match counts. Set SEMANTIC_JS_MCP_BENCHMARK_COUNTS=10,100,1000,10000 to include the 10,000-match scale.
npm run smoke:distribution packs the explicit npm file allowlist, installs the tarball into a temporary consumer project, runs the installed executable, and verifies that runtime components resolve from the consumer dependency tree rather than the source checkout.
The smoke tests create temporary generic TypeScript and Vue projects. They do not depend on a specific application repository.
Current Limitations
The server provides static semantic evidence, not runtime call tracing or behavioral proof.
Empty references and clean diagnostics do not establish absence or correctness.
Vue named-component discovery remains ambiguous when filenames, component names, import aliases, global registration, and test doubles differ. Prefer a position-based audit when an exact use is available.
Diagnostics remain
untrustedwhen the owning language server does not correlate a report with the current document version.Dynamic imports, computed property access, generated code, runtime dependency injection, and dynamically constructed class names may require text search and direct source inspection.
CSS graph analysis, Tailwind semantics, and other language domains are intentionally outside this project. Provider-native diagnostics embedded in Vue documents may still be preserved.
Roadmap
See ROADMAP.md for planned areas of development. Roadmap items describe direction, not release commitments.
Project Documents
Maintainer
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/elnonathan/semantic-js-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server