Skip to main content
Glama
SiroSuzume

MCP ts-morph Refactoring Tools

by SiroSuzume

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
rename_symbol_by_tsmorphA

[ts-morph] Type-aware rename of a TypeScript/JavaScript symbol (function, variable, class, type, interface, enum, etc.) across the entire project.

When to use

  • Renaming any symbol that may be imported, re-exported, or referenced in other files.

  • Prefer this over manual Edit + grep / sed. Identifier-based search misses re-exports, JSX attribute usage, and matches unrelated same-name tokens. This tool resolves references via the type checker, so it is both safer and faster.

  • Even for a "local-only" symbol, this tool is the correct default: it costs nothing extra and guarantees no missed reference.

When NOT to use

  • Renaming a file or folder (and updating imports to it) -> use rename_filesystem_entry_by_tsmorph.

  • Moving a symbol to a different file -> use move_symbol_to_file_by_tsmorph.

  • Just looking up where a symbol is used (no rename) -> use find_references_by_tsmorph.

Critical constraints

  • position must point at the symbol's identifier (1-based line/column, as shown by editors). If the position lands on whitespace or a different token, the rename fails.

  • symbolName must match the identifier text at that position; it is used as a sanity check.

  • All paths (tsconfigPath, targetFilePath) MUST be absolute.

Tips

  • Run with dryRun: true first when the change spans many files, to preview the affected file list.

Result

Returns the list of modified (or to-be-modified, in dryRun) file paths, plus status and processing time.

rename_filesystem_entry_by_tsmorphA

[ts-morph] Rename or move one or more TypeScript/JavaScript files and/or folders, and automatically rewrite every import/export path that references them.

When to use

  • Renaming or moving any .ts/.tsx/.js/.jsx file or directory (single or batch).

  • Prefer this over mv + manual import fixing. This tool resolves references via the type checker, so it handles relative paths, path aliases (@/), and barrel imports (from '.', from '..') that grep cannot reliably find.

  • Use batch mode (multiple entries in renames) when reorganizing several files at once -- a single AST pass is much faster than running the tool repeatedly.

When NOT to use

  • Renaming a symbol inside a file -> rename_symbol_by_tsmorph.

  • Moving a single symbol (not the whole file) to another file -> move_symbol_to_file_by_tsmorph.

Critical constraints

  • Path aliases in updated imports are REWRITTEN AS RELATIVE PATHS (e.g., @/foo -> ../foo). If you want to keep aliases, run remove_path_alias_by_tsmorph separately beforehand, or accept the conversion.

  • Barrel imports like import X from '../components' are rewritten to point at the resolved index file (e.g., '../components/index.tsx').

  • Default exports declared via a bare identifier (export default Foo;) may not be updated correctly. Default function/class declarations (export default function foo() {}) are handled.

  • All paths (tsconfigPath, oldPath, newPath) MUST be absolute.

  • The tool refuses to run on path conflicts (target already exists, duplicate destinations).

Tips

  • Run with dryRun: true first for any non-trivial rename to inspect the affected file list.

  • timeoutSeconds defaults to 120; raise it for very large projects or huge batch renames.

Result

Returns the list of modified (or to-be-modified, in dryRun) file paths, plus status and processing time. On timeout the operation is cancelled and an error is returned.

find_references_by_tsmorphA

[ts-morph] Locate the definition AND every reference of a symbol at a given position, project-wide. Read-only.

When to use

  • Assessing the blast radius of a planned refactor before changing anything.

  • Answering "who calls this function?" / "where is this type used?" precisely.

  • Prefer this over grep for identifier lookups: grep matches unrelated same-name tokens (different scopes, comments, strings), while this tool uses the type checker to return only true references.

When NOT to use

  • You just want a free-text search (comments, strings, doc files) -> use grep.

  • You already plan to rename -> skip straight to rename_symbol_by_tsmorph (it computes the same set internally and supports dryRun).

Critical constraints

  • position must land on the symbol identifier itself (1-based line/column, as shown by editors). A position on whitespace or another token will fail to resolve.

  • All paths (tsconfigPath, targetFilePath) MUST be absolute.

Result

Returns the definition (file path, line, column, source line) when found, followed by a numbered list of references with the same fields.

remove_path_alias_by_tsmorphA

[ts-morph] Convert path-alias imports/exports (e.g., @/components/Button) to relative paths (../../components/Button) within a target file or directory.

When to use

  • Standardizing on relative paths for a subset of the codebase.

  • Preparing for a large rename_filesystem_entry_by_tsmorph run when you want to control alias rewriting explicitly (note: rename_filesystem_entry_by_tsmorph already rewrites aliases to relative paths automatically; run this tool first only if you want the conversion to be a separate, reviewable commit).

  • Prefer this over manual find/replace -- relative path computation is error-prone across nested directories.

When NOT to use

  • The project has no paths mapping in tsconfig.json (this tool has nothing to do).

  • You want to ADD aliases or change one alias to another (not supported).

Critical constraints

  • Aliases are read from the paths option of the project's tsconfig.json. Only those aliases are resolved.

  • targetPath may be a single file OR a directory. Directory targets process every .ts/.tsx file under it.

  • All paths (tsconfigPath, targetPath) MUST be absolute.

Tips

  • Run with dryRun: true first when applying to a directory, to confirm the scope.

Result

Returns the list of modified (or to-be-modified, in dryRun) file paths, plus status and processing time.

move_symbol_to_file_by_tsmorphA

[ts-morph] Move one top-level symbol (function, variable, class, interface, type, enum) from one file to another, carrying its internal-only dependencies and rewriting all imports/exports across the project.

When to use

  • Splitting a large file: move related symbols to a new file one by one.

  • Relocating a helper from a generic utils.ts to a feature-specific module.

  • Prefer this over manual cut-and-paste + import fixing. Manual moves frequently miss re-exports, leave stale imports, or fail to add the new export -- this tool handles all of that via the type checker.

When NOT to use

  • Renaming the file (without moving a single symbol out of it) -> rename_filesystem_entry_by_tsmorph.

  • Renaming a symbol in place -> rename_symbol_by_tsmorph.

  • The symbol you want to move is a export default -> NOT SUPPORTED, refactor it to a named export first.

Critical constraints

  • ONE top-level symbol per call. To move N symbols, invoke the tool N times.

  • Default exports CANNOT be moved. Convert them to named exports beforehand.

  • If multiple top-level declarations share the same name (e.g., function + namespace), pass declarationKindString (e.g., "FunctionDeclaration", "VariableStatement") to disambiguate.

  • Internal dependency rules:

    • Dependencies used ONLY by the moved symbol travel with it.

    • Dependencies also used by other symbols in the source file stay put, gain export if missing, and are imported back into the destination file.

  • All paths (tsconfigPath, originalFilePath, targetFilePath) MUST be absolute.

  • targetFilePath may point to a non-existent file; it will be created.

Tips

  • Run with dryRun: true first when the source file has many co-dependencies to confirm what gets pulled along.

Result

Returns the list of modified (or to-be-modified, in dryRun) file paths, plus status and processing time.

change_signature_by_tsmorphA

[ts-morph] Add, remove, or reorder parameters of a function/method/arrow-function and propagate the matching argument changes to every call site in the project.

When to use

  • Adding a required parameter to a function with many callers (LLM single-edit reliably misses some — this tool guarantees every call site is updated via the type checker).

  • Removing or reordering parameters of a function that is imported, re-exported, or accessed through a method chain.

  • Inserting a context-like first parameter (ctx, logger, etc.) into existing helpers.

When NOT to use

  • Renaming a parameter — use rename_symbol_by_tsmorph on the parameter identifier instead.

  • Changing only the parameter's type annotation without changing arity — edit the source file directly.

  • Moving the function to another file — use move_symbol_to_file_by_tsmorph.

Critical constraints

  • position must point at the function's name identifier (1-based line/column). For const foo = () => {}, point at foo; for class C { foo() {} }, point at foo.

  • functionName must match the identifier text at that position (sanity check).

  • All paths (tsconfigPath, targetFilePath) MUST be absolute.

  • Spread arguments (fn(...args)) at call sites cause the operation to fail when a change would modify arguments. Refactor those callers manually first, or limit changes to trailing optional/defaulted parameters with no argumentForCallers.

  • Operations apply sequentially; later operations see the parameter list produced by earlier ones.

Operation semantics

  • add: Inserts a parameter at index (default: end). If argumentForCallers is provided, that exact text is inserted at the same index in every call site. If omitted, callers are left untouched (use only for trailing optional / defaulted parameters).

  • remove: Removes the parameter at index. Each call site with at least that many arguments drops the corresponding one. Calls passing fewer arguments are left untouched.

  • reorder: Rebuilds the parameter list and every call site according to newOrder. Fails if any call site does not pass exactly that many arguments (no way to safely reorder omitted optionals).

Tips

  • Run with dryRun: true first when the function has many callers to preview the impacted files.

  • For adding multiple parameters at once, list multiple add operations; their index values refer to the parameter list after prior operations in the same call have been applied.

Result

Returns the list of modified (or to-be-modified, in dryRun) file paths, plus status and processing time.

get_type_at_position_by_tsmorphA

[ts-morph] Return the TypeChecker-inferred type at a specific position in a TypeScript/JavaScript file, plus the symbol and its declaration location.

When to use

  • Quickly verifying "what is the actual inferred type of this variable / expression / function?" without spawning tsc or running a full type check.

  • Cheaper than Read-ing the declaration file when all you need is the type signature.

  • Before refactoring, to confirm what a value's actual shape is (especially helpful when types are inferred through multiple generics).

When NOT to use

  • Bulk type analysis across many positions — call tsc directly instead.

  • Listing every reference of a symbol — use find_references_by_tsmorph.

Critical constraints

  • position is 1-based (line/column), matching what editors display.

  • All paths (tsconfigPath, targetFilePath) MUST be absolute.

  • For function/method identifiers (where ALL declarations are signature-bearing) the type is rendered as a call-style (arg: T) => R text taken directly from the declaration source, preserving rest ..., optional ?, default values, and destructuring patterns. Overloads are joined with & and the implementation signature is hidden.

  • For function/namespace merges or other mixed symbols (function with extra properties), the raw TypeChecker text (e.g. typeof fn) is returned to avoid silently dropping the property side of the type.

  • For imported symbols the resolved (aliased) symbol's declaration location is reported, including barrel re-export chains (export * from, export { x } from) which are recursively unwrapped.

  • For built-in or third-party symbols (e.g. console, Promise), declaration may point inside node_modules lib.d.ts files.

Result fields

  • type: the inferred type text.

  • nodeKind / nodeText: what the position landed on (Identifier, StringLiteral, etc., and the source text — truncated to 80 chars).

  • symbol (optional): the resolved symbol's name and the kind of its first declaration.

  • declaration (optional): file path + 1-based line/column of the first declaration.

Tips

  • Pointing at whitespace or a comment line returns a SourceFile/EndOfFileToken node and the file-level inferred type (e.g. typeof import("...")) — this is NOT an error but is usually not what you want. Check nodeKind in the response and re-target to the identifier.

  • For function/namespace merges where the type returns as typeof fn, inspect the declaration location to discover the merged namespace members.

find_unused_exports_by_tsmorphA

[ts-morph] List exports that have no references outside their declaring file across the project. Read-only.

When to use

  • Hunting for dead code candidates after a refactor or migration.

  • Auditing a module's surface area: which exports does nobody actually consume?

  • Pre-deletion safety check before manually removing exports — combine with find_references_by_tsmorph to double-confirm.

When NOT to use

  • You want a single symbol's references — use find_references_by_tsmorph.

  • Single-file unused locals — tsc --noUnusedLocals is faster.

Detection scope

Reports:

  • export function/class/const/let/var/enum/interface/type ... (inline export keyword)

  • export default function/class ... and export default <Identifier>

  • export = <Identifier> (CommonJS)

Detection algorithm

For each candidate identifier, findReferencesAsNodes() is run and the following references are excluded before deciding "unused":

  • References inside the SAME file as the declaration (internal use does not count).

  • References inside any ExportDeclaration (pure re-export sites like export { x } from "./y" or export *). This means a symbol re-exported only via a barrel — with nothing actually consuming the barrel — IS reported as unused.

  • References in node_modules.

If 0 references remain, the export is reported.

Known limitations (this tool returns CANDIDATES, not verdicts)

Static analysis cannot see:

  • Dynamic require() / import() resolved from runtime strings.

  • File-system / convention based routing (Next.js page.tsx, Remix routes, etc.). Pass these as entryPoints.

  • Symbols looked up via reflection or string keys.

  • Pure local re-exports (export { x } without from) where x is declared by a separate const x = ... in the same file — this form is not enumerated.

  • Mixed function + namespace declarations may be partially missed.

Default exports are high false-positive

export default <Identifier> / export = <Identifier> (shown with the [default] tag) are prone to FALSE POSITIVES: findReferencesAsNodes runs on the local identifier and often fails to connect to import Foo from "./mod" default-import sites. A default export reported here with textHits well above 0 is almost certainly actually used. Treat [default] candidates as low confidence and always confirm with find_references_by_tsmorph.

Always verify a candidate with find_references_by_tsmorph before deletion.

Options

  • tsconfigPath: absolute path to tsconfig.json.

  • entryPoints: list of absolute file paths whose exports should be skipped (treat as public API). Reference sites IN these files still count as "used" automatically.

  • excludeFilePatterns: substrings; any file whose absolute path includes() a pattern is not scanned. Use this for test files (e.g. ".test."), generated dirs, etc.

  • maxResults: cap on number of reported entries. Default 100. When reached, scanning stops and truncated becomes true — narrow scope with the filters above and retry.

Output modes (responseFormat)

  • "list" (default): one line per candidate (format below).

  • "summary": aggregate counts for the WHOLE project — total, delete-safety split (deletable vs unexport-only), default-export count, and breakdowns by kind and by directory. On large repos the per-line list easily blows past the response size limit, so start with "summary" to see where dead code clusters, then narrow with entryPoints / excludeFilePatterns and switch to "list" for exact locations. (summary scans the whole project regardless of maxResults.)

Result format (list mode)

A bullet list of candidates with file:line:column, symbol name, declaration kind, a [default] tag for default exports, textHits=N, and sameFileRefs=N.

sameFileRefs — decides delete vs. unexport (read this first)

Every reported export is, by definition, unreferenced OUTSIDE its declaring file. sameFileRefs tells you whether it is still used INSIDE that file (declaration itself and re-export sites excluded), which determines the safe action:

  • sameFileRefs=0: not used anywhere, including its own file → truly dead, safe to delete the whole declaration (combine with textHits=0 for highest confidence).

  • sameFileRefs=1+: used within its own file → only the export keyword is unnecessary. Remove export, but KEEP the declaration — deleting it breaks the in-file references.

Deleting every reported declaration blindly will break the build: the majority are often sameFileRefs=1+ (over-exported but internally used).

textHits — text-occurrence triage hint

textHits is the number of word-boundary occurrences of the export's name in OTHER source files (declaring file excluded — so it says nothing about same-file usage; use sameFileRefs for that):

  • textHits=0: no OTHER file mentions the name. Does NOT by itself mean deletable — still check sameFileRefs.

  • textHits=1+: the name appears as a string literal, JSX tag, dynamic import().then(m => m.X), or comment. Verify with find_references_by_tsmorph before deleting. Short names (e.g. a, id) match incidentally — discount accordingly.

Trailing line reports Scanned files: N and Truncated: bool.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

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/SiroSuzume/mcp-ts-morph'

If you have feedback or need assistance with the MCP directory API, please join our Discord server