MCP ts-morph Refactoring Tools
MCP ts-morph Refactoring Tools
ts-morph を利用して、TypeScript / JavaScript コードベースに対する AST ベースのリファクタリング操作を提供する MCP サーバーです。シンボル名の変更、ファイル/フォルダ名の変更、参照検索などを、プロジェクト全体の整合性を保ちながら行えます。
目次
Related MCP server: TypeScript Rename Helper
クイックスタート
MCP クライアントの設定ファイル(mcp.json 等)に以下を追加します。npx を使うことで、公開済みの最新バージョンが自動的に利用されます。
{
"mcpServers": {
"mcp-tsmorph-refactor": {
"command": "npx",
"args": ["-y", "@sirosuzume/mcp-tsmorph-refactor"],
"env": {}
}
}
}ロギングをカスタマイズする場合は ロギング設定 を参照してください。ローカルのソースから起動する場合は 開発 を参照してください。
提供されるツール
各ツールは ts-morph で AST を解析し、プロジェクト全体の参照を保ちながら変更を行います。すべてのツールはプロジェクトの tsconfig.json パスを必要とします。
ツール | 概要 |
シンボル名をプロジェクト全体で一括変更 | |
ファイル/フォルダ名を変更し import パスを更新 | |
シンボルの定義・参照箇所を一覧表示 | |
パスエイリアスを相対パスに置換 | |
シンボルを別ファイルに移動し参照を更新 | |
関数の引数を追加/削除/並べ替え、全呼び出し箇所を更新 | |
指定位置の推論された型情報を取得 | |
未使用 export 候補を列挙 |
rename_symbol_by_tsmorph
指定ファイル内の特定位置にあるシンボル(関数・変数・クラス・インターフェースなど)の名前を、プロジェクト全体で一括変更します。
ユースケース: 参照箇所が多く手作業での変更が困難な場合。
必要な情報: 対象ファイルのパス、シンボルの位置(行・列)、現在のシンボル名、新しいシンボル名。
rename_filesystem_entry_by_tsmorph
複数のファイルおよび/またはフォルダの名前を変更し、プロジェクト内のすべての import / export 文のパスを自動的に更新します。
ユースケース: ファイル構成の変更に伴う import パスの修正。複数のファイル/フォルダを一度にリネーム/移動したい場合。
必要な情報: リネーム操作の配列
renames: { oldPath: string, newPath: string }[]。挙動:
参照解決には主にシンボル解析を用います。
パスエイリアス(
@/など)を含む参照は更新されますが、相対パスに変換されます。ディレクトリのインデックスを参照するインポート(例:
../components)は、明示的なファイルパス(例:../components/index.tsx)に更新されます。操作前にパスの衝突(既存パス・操作内の重複)をチェックします。
注意: 多数のファイル/フォルダや非常に大きなプロジェクトでは、解析と更新に時間がかかる場合があります。
export default Identifier;形式のデフォルトエクスポートの参照は正しく更新されない場合があります(既知の制限)。
find_references_by_tsmorph
指定ファイル内の特定位置にあるシンボルの定義箇所と、プロジェクト全体でのすべての参照箇所を検索して一覧表示します。
ユースケース: ある関数や変数の使用箇所の把握。リファクタリングの影響範囲の調査。
必要な情報: 対象ファイルのパス、シンボルの位置(行・列)。
remove_path_alias_by_tsmorph
指定したファイルまたはディレクトリ内の import / export 文に含まれるパスエイリアス(@/components など)を、相対パス(../../components など)に置換します。
ユースケース: プロジェクトの移植性を高めたい、特定のコーディング規約に合わせたい場合。
必要な情報: 処理対象のファイルまたはディレクトリのパス。
move_symbol_to_file_by_tsmorph
指定したシンボル(関数・変数・クラス・インターフェース・型エイリアス・Enum)を別ファイルに移動し、プロジェクト全体の参照(import/export パスを含む)を自動的に更新します。
ユースケース: 特定の機能を別ファイルに切り出してコード構成を変更したい場合。
必要な情報: 移動元・移動先のファイルパス、移動するシンボルの名前。同名シンボルがある場合は種類(
declarationKindString)を指定して曖昧性を解消できます。挙動: そのシンボル内でのみ使用される内部依存も一緒に移動します。移動元の他シンボルからも参照される依存は移動元に残り、必要に応じて
exportが追加されて移動先でインポートされます。注意: デフォルトエクスポート(
export default)されたシンボルは移動できません。
change_signature_by_tsmorph
関数・メソッド・アロー関数の引数を追加・削除・並べ替えし、プロジェクト内のすべての呼び出し箇所の引数を合わせて更新します。
ユースケース: 呼び出し元が多い関数に必須引数を追加したい、import / 再エクスポート / メソッドチェーン経由で参照される関数の引数を削除・並べ替えたい場合。LLM の単発編集では取りこぼしが起きやすい更新を、型チェッカー経由で確実に反映します。
必要な情報: 対象ファイルのパス、関数名識別子の位置(行・列)、関数名、適用する操作の配列
operations。操作(
operations):add:index(省略時は末尾)に引数を挿入。argumentForCallersを指定すると各呼び出し箇所の同じ位置にそのテキストを挿入。省略時は呼び出し側を変更しない(末尾の optional / デフォルト引数専用)。remove:indexの引数を削除。その数以上の引数を渡している呼び出しから対応分を削除。reorder:newOrderに従って引数リストと各呼び出しを再構築。引数の数が一致しない呼び出しがあると失敗します。操作は順に適用され、後続の操作は先行操作適用後の引数リストを参照します。
注意: スプレッド引数(
fn(...args))を含む呼び出しは、引数を変更する操作で失敗します。呼び出し元が多い場合はdryRun: trueで影響ファイルを先に確認してください。引数のリネームはrename_symbol_by_tsmorph、関数の移動はmove_symbol_to_file_by_tsmorphを使ってください。
get_type_at_position_by_tsmorph
TypeScript / JavaScript ファイルの指定位置における、TypeChecker が推論した型・シンボル・宣言箇所を返します。
ユースケース:
tscを起動せずに「この変数 / 式 / 関数の実際の推論型は何か」を素早く確認したい場合。宣言ファイルをReadするより安価に型シグネチャを得たいとき。リファクタリング前に値の実際の形状を確認したいとき。必要な情報: 対象ファイルのパス、検査する位置(行・列)。
注意: 空白やコメント行を指す場合はファイルレベルの推論型(例:
typeof import("..."))が返り、通常は意図した結果ではありません。レスポンスのnodeKindを確認して識別子に再ターゲットしてください。多数の位置を一括で解析したい場合はtscを直接使ってください。
find_unused_exports_by_tsmorph
プロジェクト全体を走査し、宣言ファイルの外から参照されていない export を候補として列挙します。
検出対象: インライン
export(export function/class/const/let/var/enum/interface/type)、export default(識別子・関数・クラス)、export = <Identifier>。判定方法:
findReferencesAsNodes()の結果から、同一ファイル内の参照・ExportDeclaration配下の参照(export { x } from "./y"等の純粋な再エクスポート)・node_modules内の参照を除外し、残り 0 件なら未使用候補とします。ユースケース: デッドコード掃除、モジュールの公開面の棚卸し。削除前には必ず
find_references_by_tsmorphでダブルチェックしてください。sameFileRefs(削除 vs unexport の判断): 各候補に、同一ファイル内での参照数(宣言自身と再エクスポートサイトは除外)を添えます。報告される候補は定義上「宣言ファイルの外では未参照」なので、削除アクションはこの値で決まります。sameFileRefs=0: 同一ファイル内でも未使用 → 真のデッド。宣言ごと削除して安全(textHits=0も併せるとより確実)。sameFileRefs=1+: 同一ファイル内では使用中 →exportキーワードだけ不要。宣言は残すこと(消すと同一ファイル内参照が壊れる)。報告された宣言を一律削除するとビルドが壊れます。
textOccurrences(textHits): 宣言ファイル以外のソース内で\b<name>\bが出現する回数。0は「他ファイルに名前が無い」だけで、同一ファイル内使用の有無は別途sameFileRefsを見ること(このフィールド単独では「削除して安全」を判断できない)。1+なら文字列リテラル / JSX / 動的参照の可能性があるためfind_references_by_tsmorphで要確認。default export の偽陽性:
[default]タグの付く候補(export default <Identifier>/export = <Identifier>)は、findReferencesAsNodesがimport Foo from "./mod"の default import と結びつかず偽陽性になりやすい。textHitsが 0 より十分大きい default export はほぼ使用中。低信頼として必ずfind_references_by_tsmorphで確認してください。responseFormat:"list"(デフォルト、1 候補 1 行)/"summary"(プロジェクト全体の集計=総数・削除安全性の内訳・kind 別・ディレクトリ別)。大規模リポでは全件列挙が応答サイズ上限を超えやすいので、まず"summary"でデッドコードの偏りを把握し、entryPoints/excludeFilePatternsで絞ってから"list"で正確な位置を取得する運用が安全(summaryはmaxResultsに関わらず全体をスキャン)。オプション:
entryPoints(絶対パス配列。公開 API として常に使用扱い)、excludeFilePatterns(部分一致でスキャン対象外に)、maxResults(list モードの上限。デフォルト 100)、expandNamespaceImports(デフォルト ON)。既知の限界: 動的
require/import()、ファイルシステム規約に依存するルーティング(Next.js のpage.tsx等)、文字列リフレクション越しの参照は検出できません。entryPoints/excludeFilePatternsで候補を絞り込んでください。monorepo の built dist パッケージは系統的偽陽性: workspace パッケージが package.json の
exports(またはmain/module/types)でビルド成果物(例:./dist/index.js)を公開している場合、他パッケージからの import はビルド出力(または node_modules)側に解決され、スキャン対象の src 側シンボルに紐づきません。そのため実際に消費されている export がそのパッケージだけ一括で未使用候補になります。この形は構造的に検出し、結果の先頭に ⚠ パッケージ単位の警告(パッケージ名・スキャン外を指すエントリポイント・影響候補数)を付けます。警告が付いたパッケージの候補は低信頼として扱い、削除前にtextHitsとfind_references_by_tsmorphで必ず確認してください。回避策: 解析時はそのパッケージのexportsをソース(./src/index.ts等)に向けるか、候補を個別に検証する。
ロギング設定
サーバーの動作ログは環境変数で制御します。mcp.json の env ブロックで設定します。
環境変数 | 説明 | デフォルト |
| ログの詳細度。 |
|
| 出力先。 |
|
|
|
|
LOG_OUTPUT=console かつ開発環境(NODE_ENV !== 'production')で pino-pretty がインストールされている場合は、見やすい形式で出力されます。MCP クライアントへの標準出力の影響を避けたい場合は file を指定してください。
設定例:
{
"mcpServers": {
"mcp-tsmorph-refactor": {
"command": "npx",
"args": ["-y", "@sirosuzume/mcp-tsmorph-refactor"],
"env": {
"LOG_LEVEL": "debug",
"LOG_OUTPUT": "file",
"LOG_FILE_PATH": "/Users/yourname/logs/mcp-tsmorph.log"
}
}
}
}開発
前提条件
Node.js(バージョンは
package.jsonのvoltaフィールドを参照)pnpm(バージョンは
package.jsonのpackageManagerフィールドを参照)
セットアップとビルド
git clone https://github.com/sirosuzume/mcp-tsmorph-refactor.git
cd mcp-tsmorph-refactor
pnpm install
pnpm build # dist/ に出力主なコマンド
pnpm test # テスト実行
pnpm test:watch # ウォッチモードでテスト
pnpm check-types # 型チェック(コンパイルなし)
pnpm lint # Lint チェック
pnpm lint:fix # Lint 修正
pnpm format # フォーマット
pnpm inspector # MCP Inspector でデバッグローカルビルドを MCP クライアントから使う
ビルド後、node で dist/index.js を直接起動できます。
{
"mcpServers": {
"mcp-tsmorph-refactor-dev": {
"command": "node",
"args": ["/path/to/your/local/repo/dist/index.js"],
"env": {
"LOG_LEVEL": "debug"
}
}
}
}デバッグ用ランチャー
サーバーの起動シーケンスや標準入出力を詳細に確認したい場合は、scripts/mcp_launcher.js を使います。本来のサーバープロセスを子プロセスとして起動し、起動情報や出力を .logs/mcp_launcher.log に記録します。
mcp.json の command を "node"、args を scripts/mcp_launcher.js へのパスに変更してクライアントを再起動すると、.logs/mcp_launcher.log(およびサーバー自身のログ)が確認できます。
{
"mcpServers": {
"mcp-tsmorph-refactor": {
"command": "node",
"args": ["scripts/mcp_launcher.js"],
"env": {
"LOG_OUTPUT": "file",
"LOG_FILE_PATH": ".logs/mcp-ts-morph.log"
}
}
}
}リリース
このパッケージは GitHub Actions ワークフロー(.github/workflows/release.yml)を介して npm に自動公開されます。
Git タグがバージョンの単一の真実の source です。 package.json の version と src/version.ts の VERSION はどちらも 0.0.0-development に固定されており、リリースワークフローが tag から値を取り出して焼き込みます。手動で bump する必要はありません。
公開手順
git checkout main && git pull --ff-only
git tag v1.2.0
git push origin v1.2.0タグ push でワークフローがトリガーされ、以下を順に実行します。
tag(
v1.2.0)から VERSION(1.2.0)を抽出(strict SemVer のみ。プレリリース未サポート)placeholder バージョンのまま
pnpm testnode scripts/release-version.mjs --bake 1.2.0でsrc/version.tsとpackage.jsonのversionを書き換えpnpm builddist/version.jsにexports.VERSION = "1.2.0";が含まれることをgrep -Fで確認_version_noteを package.json から除去pnpm publish --provenanceで npm へ公開(Trusted Publishing / OIDC)
完了後、npm view @sirosuzume/mcp-tsmorph-refactor version で反映を確認してください。
npm Trusted Publishing が前提です。
NPM_TOKENは廃止済みで、GitHub Actions の OIDC を介して publish されます(release.ymlのid-token: write参照)。
なぜ tag を真実の source にしているか
旧運用では「package.json の version を bump」「src/mcp/config.ts の serverInfo.version を bump」「タグを打つ」の 3 手順のいずれかを忘れると不整合がリリースされていました(実際にズレた履歴あり)。新運用では開発中はずっと 0.0.0-development のままで、リリース時に CI が tag を見て全箇所を更新するため、bump 忘れが構造的に発生しません。
CI(.github/workflows/ci.yml)は PR / main push のたびに node scripts/release-version.mjs --check を実行し、両ファイルが placeholder のままであることを確認します。手で bump した PR はここで失敗します。
失敗時の復旧
ワークフロー途中で失敗した場合は tag を削除せず、main に修正をマージしてから次のパッチタグ(
vX.Y.(Z+1))を打ってください(fix-forward)。同じタグでの再 publish は npm の immutability により不可能なため、tag の上書きは無意味です。
ライセンス
このプロジェクトは MIT ライセンスの下で公開されています。詳細は LICENSE ファイルをご覧ください。
Available Tools
8 toolschange_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_tsmorphon 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
positionmust point at the function's name identifier (1-based line/column). Forconst foo = () => {}, point atfoo; forclass C { foo() {} }, point atfoo.functionNamemust 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 noargumentForCallers.Operations apply sequentially; later operations see the parameter list produced by earlier ones.
Operation semantics
add: Inserts a parameter at
index(default: end). IfargumentForCallersis 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: truefirst when the function has many callers to preview the impacted files.For adding multiple parameters at once, list multiple
addoperations; theirindexvalues 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Path to the project's tsconfig.json file. | |
| targetFilePath | Yes | Path to the file containing the function declaration. | |
| position | Yes | Exact position of the function name identifier. | |
| functionName | Yes | Name of the function/method at that position. | |
| changes | Yes | Ordered list of signature operations to apply. See the tool description for semantics. | |
| dryRun | No | If true, only show intended changes without modifying files. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It extensively discloses behavioral traits: critical constraints (position, functionName, absolute paths, spread arguments, sequential operations), operation semantics for add/remove/reorder, and tips (dryRun). It also explains the result format. This is thorough and leaves no ambiguity about the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with clear sections: purpose, usage guidelines, critical constraints, operation semantics, tips, and result. It is front-loaded with the core purpose and each section earns its place. There is no redundant information, and the length is appropriate for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, nested objects, no output schema, no annotations), the description is very complete. It covers all necessary aspects: when to use, constraints, operation semantics, result format, and even provides tips for previewing changes. It does not need an output schema as the result is described as a list of modified files. The description fully equips an AI agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but the description adds significant meaning beyond the schema. It explains how `index` works in sequential operations, the nuance of `argumentForCallers`, and the semantics of each operation kind (add, remove, reorder). It also clarifies the `newOrder` array format for reorder. This added context is valuable for correct usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Add, remove, or reorder parameters of a function/method/arrow-function and propagate the matching argument changes to every call site in the project.' It uses a specific verb ('add, remove, reorder') and resource (function parameters), and distinguishes itself from sibling tools like rename_symbol_by_tsmorph and move_symbol_to_file_by_tsmorph in the 'When NOT to use' section.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes explicit 'When to use' and 'When NOT to use' sections, providing clear context and alternatives. It specifies when to use this tool (e.g., adding required parameters with many callers, removing/reordering parameters) and when not to (e.g., renaming parameters, changing type annotations, moving the function). It also names sibling tools as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
grepfor 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 supportsdryRun).
Critical constraints
positionmust 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Absolute path to the project's tsconfig.json file. | |
| targetFilePath | Yes | Absolute path to the file containing the symbol. | |
| position | Yes | The exact position of the symbol. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description fully covers behavior: read-only, constraints on position (must land on symbol identifier), absolute paths required, and result format (definition + references).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, bullet points, code blocks. Front-loaded purpose, every sentence adds value, no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description explains result format (definition and numbered references with file path, line, column, source line). Covers constraints, use cases, and sibling differentiation. Very complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters with descriptions, and description adds critical context: paths must be absolute, position must be on the symbol identifier, and 1-based line/column. Adds significant value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool locates the definition AND every reference of a symbol, project-wide, and is read-only. It distinguishes from siblings like rename_symbol_by_tsmorph and grep.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'When to use' and 'When NOT to use' sections provide clear guidance, including specific examples like blast radius assessment and alternatives such as grep for free-text search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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_tsmorphto double-confirm.
When NOT to use
You want a single symbol's references — use
find_references_by_tsmorph.Single-file unused locals —
tsc --noUnusedLocalsis faster.
Detection scope
Reports:
export function/class/const/let/var/enum/interface/type ...(inline export keyword)export default function/class ...andexport 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 likeexport { x } from "./y"orexport *). 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 asentryPoints.Symbols looked up via reflection or string keys.
Pure local re-exports (
export { x }withoutfrom) wherexis declared by a separateconst x = ...in the same file — this form is not enumerated.Mixed function + namespace declarations may be partially missed.
Workspace packages that publish built output: in a monorepo, when a scanned package's
package.jsonentry points (exports/main/module/types) resolve outside the scanned sources (e.g."exports": { ".": "./dist/index.js" }), imports from OTHER workspace packages resolve to the built files (or node_modules) instead of the scanned sources. Every export of such a package is then reported unused even when it IS consumed — a systematic false positive. The tool detects this shape and prepends a ⚠ package-level warning to the result; treat all candidates from a warned package as low confidence. Workaround: point that package'sexportsat source files for analysis, or verify each candidate withfind_references_by_tsmorph/textHits.
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 totsconfig.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 pathincludes()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 andtruncatedbecomes 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 withentryPoints/excludeFilePatternsand switch to"list"for exact locations. (summaryscans the whole project regardless ofmaxResults.)
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 withtextHits=0for highest confidence).sameFileRefs=1+: used within its own file → only theexportkeyword is unnecessary. Removeexport, 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 checksameFileRefs.textHits=1+: the name appears as a string literal, JSX tag, dynamicimport().then(m => m.X), or comment. Verify withfind_references_by_tsmorphbefore deleting. Short names (e.g.a,id) match incidentally — discount accordingly.
⚠ Package-level warnings
When a package that produced candidates publishes built output (see Known limitations), a ⚠ warnings block is prepended to the result (both list and summary modes) naming the package, its out-of-scan entry points, and how many candidates are affected. Those candidates are likely false positives.
Trailing line reports Scanned files: N and Truncated: bool.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Absolute path to the project's tsconfig.json. | |
| entryPoints | No | Absolute file paths to treat as public API. Exports declared here are skipped. | |
| excludeFilePatterns | No | Substrings; files whose absolute path includes any of these are not scanned. | |
| maxResults | No | Cap on reported entries (list mode). Default 100. Ignored intent in "summary" mode, which scans the whole project. | |
| responseFormat | No | "list" (default): one line per candidate. "summary": aggregate counts (delete-safety / kind / directory) for the WHOLE project — use this first on large repos to avoid huge output, then narrow with entryPoints/excludeFilePatterns and switch to "list". | list |
| expandNamespaceImports | No | Default true. Inject synthetic named imports into files containing `import * as ns from "./mod"` so that exports of the target module register as 'used' even when consumed only via `{ ...ns }` spread or other escaping patterns. Set to false if you want raw findReferences semantics. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses the tool's behavior: read-only, detection algorithm, excluded reference types, known limitations (dynamic imports, routing conventions, monorepo false positives), and detailed guidance on interpreting results (`sameFileRefs`, `textHits`). It even warns about default export false positives and package-level warnings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is quite long but well-structured with headings, bullet points, and code formatting. Each section serves a purpose—core statement, usage guidelines, algorithm, limitations, options, output format, and result interpretation. While no sentence seems wasted, it could be slightly trimmed without losing value. The front-loading of purpose and usage is effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, no output schema, no annotations), the description is remarkably complete. It covers not only how to invoke the tool but also how to interpret results (`sameFileRefs`, `textHits`), common pitfalls (default exports, monorepo false positives), and strategies for narrowing scope. The agent can confidently use this tool based solely on the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the input schema already provides parameter descriptions (100% coverage), the description adds significant practical context: how `entryPoints` affect results, when to use `responseFormat='summary'` for large repos, how `maxResults` interacts with summary mode, and the purpose of `expandNamespaceImports`. This guidance helps the agent use parameters effectively.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear statement: 'List exports that have no references outside their declaring file across the project. Read-only.' It explicitly distinguishes from the sibling tool `find_references_by_tsmorph` in the 'When NOT to use' section, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes dedicated 'When to use' and 'When NOT to use' sections, providing concrete scenarios and naming alternative tools (e.g., `find_references_by_tsmorph`, `tsc --noUnusedLocals`). This gives the agent clear context for selecting the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
tscor 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
tscdirectly instead.Listing every reference of a symbol — use
find_references_by_tsmorph.
Critical constraints
positionis 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) => Rtext 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),declarationmay point insidenode_moduleslib.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. ChecknodeKindin the response and re-target to the identifier.For function/namespace merges where the type returns as
typeof fn, inspect thedeclarationlocation to discover the merged namespace members.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Path to the project's tsconfig.json file. | |
| targetFilePath | Yes | Path to the file containing the position to inspect. | |
| position | Yes | Exact position to inspect. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses critical constraints: 1-based position, absolute paths, handling of function/method identifiers (overloads, merged symbols), imports, and built-ins. It also describes result fields and potential edge cases (whitespace/comments). No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with clear sections, bullet points, and front-loaded core purpose. Every sentence adds value, covering constraints, usage, and results efficiently without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the tool, no output schema, and no annotations, the description is remarkably complete. It explains all result fields, error states (whitespace/comments), and provides actionable tips. Covers all important aspects for an AI agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, providing a baseline of 3. The description adds value beyond the schema by explaining that position is 1-based, paths must be absolute, and by providing context for how parameters are used (e.g., how position maps to node types). This extra guidance justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Return the TypeChecker-inferred type at a specific position in a TypeScript/JavaScript file, plus the symbol and its declaration location.' It uses specific verbs and resources, and distinguishes from siblings by mentioning cheaper alternative to tsc and not for bulk analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes explicit 'When to use' and 'When NOT to use' sections, providing clear guidance on appropriate contexts (quick type checking, before refactoring) and exclusions (bulk analysis, listing references). It also names alternatives like tsc and find_references_by_tsmorph.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.tsto 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
exportif missing, and are imported back into the destination file.
All paths (
tsconfigPath,originalFilePath,targetFilePath) MUST be absolute.targetFilePathmay point to a non-existent file; it will be created.
Tips
Run with
dryRun: truefirst 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Absolute path to the project's tsconfig.json file. Essential for ts-morph. | |
| originalFilePath | Yes | Absolute path to the file containing the symbol to move. | |
| targetFilePath | Yes | Absolute path to the destination file. Can be an existing file; if the path does not exist, a new file will be created. | |
| symbolToMove | Yes | The name of the single top-level symbol you want to move in this execution. | |
| declarationKindString | No | Optional. The kind of the declaration. Providing this helps resolve ambiguity if multiple symbols share the same name. | |
| dryRun | No | If true, only show intended changes without modifying files. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden. It discloses critical behaviors: internal dependency rules (carries only internal deps, leaves shared ones with export), path requirements (must be absolute), creation of non-existent target file, and dry-run support. Covers all significant behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured with sections, bullet points, and clear headings. Immediately states core functionality, then provides usage guidelines, constraints, tips, and result. Every sentence earns its place; no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema and 6 parameters, the description thoroughly explains the tool's behavior, constraints, and expected result (list of modified files). Includes a tip to use dryRun first. Everything an agent needs to invoke correctly is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds some extra context (e.g., 'Essential for ts-morph' for tsconfigPath, 'disambiguate' for declarationKindString) but mostly restates schema, providing moderate added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: moving a top-level symbol between files while rewriting imports/exports. It distinguishes from sibling tools by naming them explicitly (e.g., rename_filesystem_entry_by_tsmorph, rename_symbol_by_tsmorph) and noting when not to use this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Includes explicit 'When to use' and 'When NOT to use' sections with clear context and alternatives, such as renaming a file or renaming a symbol. Also warns about unsupported default exports, guiding the agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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_tsmorphrun when you want to control alias rewriting explicitly (note:rename_filesystem_entry_by_tsmorphalready 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
pathsmapping intsconfig.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
pathsoption of the project'stsconfig.json. Only those aliases are resolved.targetPathmay be a single file OR a directory. Directory targets process every.ts/.tsxfile under it.All paths (
tsconfigPath,targetPath) MUST be absolute.
Tips
Run with
dryRun: truefirst 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Absolute path to the project's tsconfig.json file. | |
| targetPath | Yes | Absolute path to the target file or directory. | |
| dryRun | No | If true, only show intended changes without modifying files. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral traits: aliases from tsconfig, targetPath as file or directory, requirement for absolute paths, dryRun behavior, and result format. It clearly indicates it modifies files (or shows intended changes). Minor deduction for not mentioning error handling or idempotency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections, front-loaded with the main action, and every sentence provides useful information. It is concise yet comprehensive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and 3 parameters, the description covers key aspects: data source (tsconfig), scope (file or directory), constraints (absolute paths), tips (dryRun), and result format. Slightly incomplete regarding error cases or behavior when no aliases found, but sufficient for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds context (e.g., tsconfigPath is the project's tsconfig, paths must be absolute) but does not significantly increase meaning beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Convert path-alias imports/exports to relative paths within a target file or directory', using specific verb and resource. It distinguishes from sibling tools by noting that rename_filesystem_entry_by_tsmorph already does this automatically.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes explicit 'When to use' and 'When NOT to use' sections, providing clear guidance on when to choose this tool over alternatives like rename_filesystem_entry_by_tsmorph, and when not to use it (e.g., no paths mapping, wanting to add aliases).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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, runremove_path_alias_by_tsmorphseparately 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: truefirst for any non-trivial rename to inspect the affected file list.timeoutSecondsdefaults 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Absolute path to the project's tsconfig.json file. | |
| renames | Yes | An array of rename operations, each with oldPath and newPath. | |
| dryRun | No | If true, only show intended changes without modifying files. | |
| timeoutSeconds | No | Maximum time in seconds allowed for the operation before it times out. Defaults to 120. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses critical behaviors: path aliases rewritten as relative, barrel imports resolved, default exports may not update, paths must be absolute, refuses on conflicts, dryRun and timeout behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear headings, bullet points, and concise sentences. Every section adds value without redundancy. Length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given complexity and no output schema, description covers usage, constraints, tips, and result format. Sufficient for an agent to decide when and how to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so each parameter is already documented. Description adds general context (e.g., dryRun tip, timeout default) but does not significantly enhance parameter semantics beyond schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool renames or moves TypeScript/JavaScript files/folders and automatically rewrites import/export paths. It distinguishes from sibling tools like rename_symbol_by_tsmorph and move_symbol_to_file_by_tsmorph by specifying what each handles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'When to use' and 'When NOT to use' sections with concrete alternatives (e.g., rename_symbol_by_tsmorph for symbol renaming, move_symbol_to_file_by_tsmorph for moving symbols). Also advises batch mode for multiple renames for efficiency.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
positionmust 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.symbolNamemust 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: truefirst 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tsconfigPath | Yes | Path to the project's tsconfig.json file. | |
| targetFilePath | Yes | Path to the file containing the symbol to rename. | |
| position | Yes | The exact position of the symbol to rename. | |
| symbolName | Yes | The current name of the symbol. | |
| newName | Yes | The new name for the symbol. | |
| dryRun | No | If true, only show intended changes without modifying files. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It describes the tool as type-aware, safe, and fast, and explains 'Critical constraints' about position and symbolName. However, it does not detail error handling or access permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections and bullet points. It is concise yet comprehensive, with every sentence adding value. No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, nested objects, no output schema), the description covers constraints, usage guidance, and result format thoroughly. It even includes a tip to use dryRun first.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but the description adds significant value: it clarifies that position must be 1-based and point to the symbol's identifier, symbolName is a sanity check, paths must be absolute, and dryRun for preview. This goes beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Type-aware rename of a TypeScript/JavaScript symbol across the entire project,' using specific verbs and resources. It distinguishes itself from sibling tools like rename_filesystem_entry_by_tsmorph and move_symbol_to_file_by_tsmorph by explicitly listing what it is not for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Dedicated 'When to use' and 'When NOT to use' sections provide explicit guidance, including when to prefer this over manual grep or sibling tools. It names alternatives (e.g., find_references_by_tsmorph) and clarifies when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.5.2- Changed
find_unused_exports_by_tsmorph2 fields changed- changed
Input schema / properties / maxResults / descriptionPrevious value: -"Cap on reported entries. Default 100."New value: +"Cap on reported entries (list mode). Default 100. Ignored intent in \"summary\" mode, which scans the whole project." - added
Input schema / properties / responseFormatAdded value: +{ + "default": "list", + "description": "\"list\" (default): one line per candidate. \"summary\": aggregate counts (delete-safety / kind / directory) for the WHOLE project — use this first on large repos to avoid huge output, then narrow with entryPoints/excludeFilePatterns and switch to \"list\".", + "enum": [ + "list", + "summary" + ], + "type": "string" +}
2 tool updates
v1.5.0- Added
find_unused_exports_by_tsmorph - Added
get_type_at_position_by_tsmorph
1 tool update
v1.3.0- Added
change_signature_by_tsmorph
5 tool updates
v1.1.0- Added
find_references_by_tsmorph - Added
move_symbol_to_file_by_tsmorph - Added
remove_path_alias_by_tsmorph - Added
rename_filesystem_entry_by_tsmorph - Added
rename_symbol_by_tsmorph
5 tool updates
v1.0.1- Removed
find_references_by_tsmorph - Removed
move_symbol_to_file_by_tsmorph - Removed
remove_path_alias_by_tsmorph - Removed
rename_filesystem_entry_by_tsmorph - Removed
rename_symbol_by_tsmorph
5 tool updates
v1.0.0- First observed
find_references_by_tsmorph - First observed
move_symbol_to_file_by_tsmorph - First observed
remove_path_alias_by_tsmorph - First observed
rename_filesystem_entry_by_tsmorph - First observed
rename_symbol_by_tsmorph
TDQS
Scored across 8 tools
Each tool owns a clearly distinct operation—symbol rename, file rename/move, symbol move, signature change, reference lookup, type query, alias removal, and dead-export detection. The descriptions include explicit "When NOT to use" cross-references that route the agent to the correct counterpart, leaving no ambiguity between overlapping-sounding tools like rename_symbol vs. move_symbol vs. rename_filesystem_entry.
All 8 tools follow a consistent snake_case verb_noun_by_tsmorph pattern, with the shared suffix making the family instantly recognizable. Minor structural variations like move_symbol_to_file_by_tsmorph and get_type_at_position_by_tsmorph are still verb-first and follow the same morphological convention, so there is no real inconsistency.
8 tools is a well-scoped size for a refactoring toolkit. Each tool covers a distinct, frequently-needed refactoring or analysis operation with no redundancy or bloat, and the count is comfortably within the ideal 3–15 range.
The surface covers the major project-wide refactorings—rename symbol, rename/move files, move symbol, change signature, dead-code detection—plus read-only helpers for references and types. The only notable gap is the absence of extract/inline-style refactorings, but those aren't strongly implied by the server's stated purpose, so this is a minor rather than significant gap.
Maintenance
Related MCP Connectors
Stateless TS/JS compiler facts for agents: references, imports, impact. No repo index or OAuth.
Manage files and folders directly from your workspace. Read and write files, list directories, cre…
Ask a codebase what calls what: search, blast radius, paths between symbols, and diffs.
Coding agents in multi-service codebases routinely rebuild existing helpers, trust stale type definitions, and modify API contracts without knowing who consumes them. Carrick solves this by indexing your entire TypeScript ecosystem across service and repository boundaries. By integrating deeply with the TypeScript compiler, Carrick traces every route, type, and cross-service call while recording function behaviour so agents search by intent rather than name. Delivered via MCP for AI agents and LSP for IDEs, Carrick ensures models see existing endpoints and utilities before generating new code. The scanner is source-available and runs from your CLI or CI pipeline.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides code refactoring capabilities for TypeScript/JavaScript and Python through Language Server Protocol integration. Enables renaming symbols, extracting functions, finding references, and moving code between files via natural language commands.52,399 npm7MIT
- AlicenseAqualityCmaintenanceProvides compiler-grade TypeScript symbol renaming and file/directory move planning through the TypeScript Language Service, returning structured edit plans without modifying files.385 npmMIT
- AlicenseAqualityDmaintenanceProvides Python refactoring capabilities via the Rope library, enabling AI agents to perform safe, project-wide code transformations such as renaming symbols, moving modules, and extracting methods.101MIT
- AlicenseAqualityBmaintenanceA TypeScript/JavaScript refactoring MCP server that uses the TypeScript compiler to perform safe, type-aware code transformations such as renaming, extracting functions, and organizing imports across your codebase.4109 npm12MIT