npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

codemode-lsp

v0.4.2

Published

Semantic code intelligence + refactoring MCP for TypeScript/JS: one LSP-backed execute tool — call graphs, impact analysis, symbol dependencies, atomic multi-file refactors

Readme

codemode-lsp

Semantic code intelligence and refactoring for TypeScript/JavaScript agents: an MCP server exposing a single execute tool backed by the language server. The LLM writes one JavaScript script that chains semantic operations (lsp.*) — filtering, looping, and aggregating in code instead of across many tool-call round trips:

const refs = await lsp.findReferences("src/api.ts", "handleRequest");
const relevant = refs.filter((r) => r.context.includes("deprecated"));
for (const ref of relevant) {
  await lsp.replaceSymbolBody(ref.file, ref.symbolPath, newImpl);
}
({ modified: relevant.length });

It shines on codebase-wide work that grep-based agents get subtly wrong: impact analysis, call graphs, usage audits, and atomic multi-file refactors. Names are resolved, not text-matched. Writes are transactional — nothing hits disk unless the whole script succeeds, and successful writes come back as reviewable unified diffs.

Setup

No install step — the package bundles its own typescript-language-server. The workspace root is the directory the server is spawned from:

{
  "mcpServers": {
    "codemode-lsp": {
      "command": "npx",
      "args": ["-y", "codemode-lsp"]
    }
  }
}

Add "env": { "CODEMODE_READONLY": "1" } to try it on a repo it physically cannot write to.

Operations

| | | | --- | --- | | read | readFile, getSymbols (pass 1 as depth for top level only), getSymbolBody, findSymbol, findReferences, goToDefinition, incomingCalls, outgoingCalls (true calls only), getDependencies (what a symbol's body needs from outside itself), searchText, listFiles, getDiagnostics | | verify | checkProject — whole-project type check over the buffered state; path aliases resolve even in files created mid-script | | write | moveSymbol / moveSymbols (full move, single or batch: imports computed and deduped, importers repointed, source pruned), organizeImports, addMissingImports, renameSymbol, replaceSymbolBody, insertBeforeSymbol, insertAfterSymbol, deleteSymbol, writeFile, deleteFile |

The tool returns { result, logs, changes }. Symbols are addressed as (file, "MyClass/myMethod") pairs discovered via getSymbols. Full type definitions are embedded in the tool description (generated from source); if a client truncates it, await lsp.help() returns the complete reference.

See PRD.md for the complete spec and decision log.

Configuration

| Variable | Default | Effect | | --- | --- | --- | | CODEMODE_TIMEOUT_MS | 60000 | Script timeout | | CODEMODE_LSP_BIN | bundled server | Language server command | | CODEMODE_READONLY | unset | 1/true removes the write ops entirely |

Limitations

  • TypeScript/JavaScript only (the architecture is language-agnostic).
  • Per-file diagnostics cover session-touched files; checkProject() is the whole-project check. On files created mid-script, per-file "Cannot find module" alias errors are tagged likelyFalsePositive: truecheckProject() has no such false positives.
  • getDependencies is syntactic; moveSymbol moves top-level symbols only.
  • Reference.isWriteAccess is always false (not exposed over standard LSP).

Development

bun run check           # typecheck + lint + all tests — run before declaring done
bun run generate:types  # regenerate src/lsp-types.generated.ts after API changes
bun run eval            # LLM benchmark: headless Claude Code, execute tool only

The tool description's worked examples run verbatim as golden tests, and every eval task's reference solution runs in the normal suite — neither can rot.