Skip to main content
Glama

npm node license

Type Atlas 是一个用于代码智能的 MCP 服务器。Volar 语言服务器从拥有每个文件的 TypeScript 项目给出答案,因此定义、引用、类型、诊断和范围与编辑器显示的内容一致。

响应是为上下文窗口而不是屏幕编写的。文件大纲是其中的声明,而不是每个嵌套的回调。读取会将函数体折叠为签名。inspect_symbol 将八个语言服务器请求组合成一个答案。每个答案都会说明它覆盖的范围以及它的开销。

我每天都在一个几乎完全由智能体维护的大型 monorepo 上使用它。

TypeScript、Markdown 和 JSON。Node 22.20 或更高版本。Apache-2.0。

安装

codex mcp add type-atlas -- npx --yes @type-atlas/mcp@latest

claude mcp add --scope user type-atlas -- npx --yes @type-atlas/mcp@latest

code --add-mcp '{"name":"type-atlas","command":"npx","args":["--yes","@type-atlas/mcp@latest"]}'

任何其他客户端都采用标准形式:

{
  "mcpServers": {
    "type-atlas": {
      "command": "npx",
      "args": ["--yes", "@type-atlas/mcp@latest"]
    }
  }
}

如果客户端在没有你的 shell PATH 的情况下启动服务器,它将无法按名称找到 npx;在这种情况下,请提供 which npx 给出的绝对路径。在 Windows 上,如果客户端无法启动 npx.cmd 垫片,则需要使用 "command": "cmd""args": ["/c", "npx", "--yes", "@type-atlas/mcp@latest"]

客户端在启动时读取 MCP 配置,因此之后需要重启。@latest 会在每次进程启动时解析;如果你不希望工具行为在你脚下发生变化,请固定版本。

search_coderelated_codeinvestigate_codesearch_dependency_code 通过 uvx 运行语义索引,并且需要 uv。如果没有 uv,这四个工具会报告缺少 uv,explore_symbol 会省略其 related-code 部分,其余功能不受影响。

推荐

安装服务器并不会改变智能体会选择什么工具。某些智能体(包括 Claude)会组合使用 shell 允许的一切命令,将它们串联起来,并每次给出全新的理由,因此列出几个要避免的命令并不奏效。指令必须排除整个类别并指明例外。将以下内容添加到 AGENTS.mdCLAUDE.md

Type Atlas MCP 是阅读和导航 TypeScript 与 JavaScript 代码的必需工具。这不是一种偏好。任何 shell 命令,无论由什么组成,都不是可接受的替代方案,普通的文件读取也不行。唯一有效的回退是服务器宕机、调用出错,或者文件既不是 TS 也不是 JS。

--require-intent

使用此标志时,只读调用必须携带一句话,说明它服务于哪个决策,这句话会回显在答案上方。没有这句话的调用将失败。

codex mcp add type-atlas -- npx --yes @type-atlas/mcp@latest --require-intent

这是为那些导航范围远超其变更所需、事后又说不出原因的智能体准备的。默认关闭。

Related MCP server: agent-workspace-mcp

工具调用结果

路径相对于工作区,坐标从 1 开始,因此一个答案中的位置可以成为下一次调用的有效输入。编辑工具返回补丁;不会替你写入任何内容。

以下所有内容均由场景套件从运行中的服务器针对 fixtures/ledger 捕获而来,该套件会重放相同的调用,并在出现偏差时失败。这里没有任何手写内容,改变工具的回答也会在同一个提交中改变此文件。源文件是 README.mdoc。每个工具在 docs/tools 中都有一个包含更多用例的页面。

list_files

将结构、行数和 git status 放在同一个树中,使用编辑器已经使用的徽标字母。已删除的文件也会占一行,尽管它们只存在于 git 的答案中。折叠的目录会说明其中包含什么,而不是消失。

智能体的输入

tool: List files
workspace: fixtures/ledger
# working tree arranged: currency.ts edited · rounding.ts created · index.ts deleted
directory: packages/money
depth: 2

# answered in 57ms

响应

packages/money/
├  src/ · 3 changed
│  ├  currency.ts · 21 loc · M +2
│  ├  index.ts · D -12
│  ├  money.ts · 58 loc
│  ├  rounding-mode.ts · 15 loc
│  └  rounding.ts · 11 loc · U
├  tests/
│  ├  money.test.ts · 15 loc
│  └  rounding-parity.ts · 15 loc
├  package.json · 19 loc
└  tsconfig.json · 20 loc

inspect_symbol

悬停、定义、类型定义、实现、调用方、调用和引用,一次调用全部完成。引用是在统计调用方和定义之后剩余的部分,因此每个使用位置只会列出一次。与分别调用这些工具相比,字符数约为其四分之一,往返次数约为其七分之一。

智能体的输入

tool: Inspect symbol
workspace: fixtures/ledger
file: packages/accounts/src/journal.ts
symbol: Journal

# answered in 49ms

响应

Journal [class] · packages/accounts/src/journal.ts:24:14-24:21 · range 24:1-73:2 · packages/accounts/tsconfig.json

```typescript
class Journal<TMeta = undefined>
```

An append-only journal of balanced entries. `TMeta` carries whatever a
consumer attaches to each entry — an import batch id, an approval trail —
without the journal knowing its shape.

## Callers (4)

packages/accounts/tests/journal.test.ts
├  test("posts a balanced transfer through the overload") callback [function] 5:56-14:2 · calls 6:23-6:30
└  test("refuses an unbalanced entry") callback [function] 16:37-29:2 · calls 17:23-17:30
packages/reports/src/balance.ts
└  balancesAsOf [variable] 23:14-23:26 · range 23:14-51:2 · calls 24:12-24:19
packages/importers/src/csv.ts
└  importStatement [variable] 28:14-28:29 · range 28:14-47:2 · calls 29:12-29:19

## Mentions that are not calls (4 of 9 references · 9 projects loaded)

packages/accounts/tests/journal.test.ts:3:25-3:32:  import { credit, debit, Journal, UnbalancedEntryError } from "../src/index.ts";
packages/accounts/src/index.ts:11:22-11:29:  export { type Entry, Journal, UnbalancedEntryError } from "./journal.ts";
packages/reports/src/balance.ts:4:8-4:15:  type Journal,
packages/importers/src/csv.ts:1:10-1:17:  import { Journal, type Entry, credit, debit, type AccountPath } from "@ledger/accounts";

references lists all 9, with paging.

read_file

参数是一个数组,因此一次调用可以读取多个文件。默认情况下,函数体会折叠为签名,标题会说明节省了多少行;fold: false 则返回完整函数体。

智能体的输入

tool: Read files
workspace: fixtures/ledger
file: ["packages/accounts/src/posting.ts","packages/money/src/rounding-mode.ts"]

# answered in 7ms

响应

2 files · 42 lines · 6 folded to signatures, pass fold: false for the bodies

=== packages/accounts/src/posting.ts · 32 lines ===

 1 | import { type Money, negate } from "@ledger/money";
 2 | import type { AccountPath } from "./account.ts";
 3 |
 4 | /**
 5 |  * One side of a journal entry. The discriminant is the bookkeeping side, so
 6 |  * every consumer's switch is checked for exhaustiveness by the compiler.
 7 |  */
 8 | export type Posting =
 9 |   | { readonly side: "debit"; readonly account: AccountPath; readonly amount: Money }
10 |   | { readonly side: "credit"; readonly account: AccountPath; readonly amount: Money };
11 |
12 | export const debit = (account: AccountPath, amount: Money): Posting => ({
13 |   side: "debit",
14 |   account,
15 |   amount,
16 | });
17 |
18 | export const credit = (account: AccountPath, amount: Money): Posting => ({
19 |   side: "credit",
20 |   account,
21 |   amount,
22 | });
23 |
24 | /** A posting's effect on a debit-normal running balance. */
25 | export const signedAmount = (posting: Posting): Money => {
   |   ... 26-31 folded
32 | };

=== packages/money/src/rounding-mode.ts · 15 lines ===

 1 | /** How sub-minor precision resolves when a statement and the books disagree. */
 2 | export enum RoundingMode {
 3 |   HalfUp = "half-up",
 4 |   HalfEven = "half-even",
 5 |   Truncate = "truncate",
 6 | }
 7 |
 8 | /** Per-institution conventions, as observed in their exports. */
 9 | const bankRounding: Readonly<Record<string, RoundingMode>> = {
10 |   "first-national": RoundingMode.HalfEven,
11 |   "harbor-credit": RoundingMode.HalfUp,
12 | };
13 |
14 | export const roundingModeOf = (bank: string): RoundingMode =>
15 |   bankRounding[bank] ?? RoundingMode.HalfEven;

occurrences

字面文本,按文件分组,并附上扫描的文件数。语义工具会对存在的内容进行排名,这对于确认某个 token 在拆除后已不存在毫无用处;这里的零会附带相同的扫描计数,因此它是有意义的。

智能体的输入

tool: Occurrences
workspace: fixtures/ledger
text: signedAmount

# answered in 12ms

响应

"signedAmount" occurs 12 times in 7 files · 67 files scanned under the workspace · 1 file of declared build output not scanned.

packages/accounts/src/index.ts:12:39 · export { credit, debit, type Posting, signedAmount } from "./posting.ts";
packages/accounts/src/journal.ts
├  3:39  · import { credit, debit, type Posting, signedAmount } from "./posting.ts";
└  52:12 · .map(signedAmount)
packages/accounts/src/posting.ts:25:14 · export const signedAmount = (posting: Posting): Money => {
packages/reconcile/src/drift.ts
├  4:24  · import { type Posting, signedAmount } from "@ledger/accounts";
└  20:37 · const journalTotal = postings.map(signedAmount).reduce((total, amount) => total + amount);
packages/reconcile/src/matching.ts
├  1:55  · // DELIBERATELY BROKEN — the imports for `money` and `signedAmount` are
└  14:20 · const amount = signedAmount(posting);
packages/reports/src/balance.ts
├  6:3   · signedAmount,
└  34:57 · add(own.get(posting.account) ?? zero(currency), signedAmount(posting)),
packages/rules/src/builtin.ts
├  1:10  · import { signedAmount } from "@ledger/accounts";
└  26:12 · .map(signedAmount)

search_code

按代码的功能来查找代码,适用于你猜不到它叫什么名字的情况。命中结果按排名顺序返回,每条都带有它来源的文件范围,因此下一次调用有地方可去。实时答案还会为每条命中携带一个相关度百分比;下面的示例中省略了它,因为其背后的嵌入分数在不同机器上会有差异,而这些用例需要逐字节比较。

智能体的输入

tool: Search code
workspace: fixtures/ledger
query: walking an account up through each of its ancestor accounts
snippetLines: 6

# answered in 20ms

响应

Search: walking an account up through each of its ancestor accounts

5 matches · no identifier to anchor on, so these are ranked by meaning alone

=== 1 · packages/accounts/src/account.ts:21-35 ===

Structure: parentPath
Symbol: parentPath [variable] · selection 21:14-21:24 · range 21:14-24:2

21 | export const parentPath = (path: AccountPath): AccountPath | undefined => {
22 |   const at = path.lastIndexOf(":");
23 |   return at === -1 ? undefined : path.slice(0, at);
24 | };
25 |
26 | /** Every ancestor from root to the account itself: `a`, `a:b`, `a:b:c`. */

=== 2 · packages/reports/src/balance.ts:1-23 ===

Structure: BalanceLine
Symbol: BalanceLine [interface] · selection 11:18-11:29 · range 11:1-16:2

1 | import {
2 |   type AccountPath,
3 |   type Entry,
4 |   type Journal,
5 |   lineage,
6 |   signedAmount,

=== 3 · packages/accounts/src/journal.ts:59-73 ===

Structure: Journal > history
Symbol: history [method] · selection 60:3-60:10 · range 60:3-64:4

59 |   /** Entries touching an account, oldest first. */
60 |   history(account: AccountPath): readonly Entry<TMeta>[] {
61 |     return this.entries.filter((entry) =>
62 |       entry.postings.some((posting) => posting.account === account),
63 |     );
64 |   }

=== 4 · packages/reports/src/statement.ts:1-11 ===

Structure: statementLine
Symbol: statementLine [variable] · selection 8:14-8:27 · range 8:14-11:2

1 | import { type Account, normalBalance } from "@ledger/accounts";
2 | import { format, type Money, negate } from "@ledger/money";
3 |
4 | /**
5 |  * One rendered statement line. The sign follows the account's normal side:
6 |  * a liability holding a credit balance reads as positive on its statement.

=== 5 · packages/accounts/src/posting.ts:1-24 ===

Structure: credit
Symbol: credit [variable] · selection 18:14-18:20 · range 18:14-22:3

1 | import { type Money, negate } from "@ledger/money";
2 | import type { AccountPath } from "./account.ts";
3 |
4 | /**
5 |  * One side of a journal entry. The discriminant is the bookkeeping side, so
6 |  * every consumer's switch is checked for exhaustiveness by the compiler.

diagnostics

编译器自身的全程序检查,按项目进行,而不是按文件进行。对一个文件的编辑通常会破坏另一个文件,而正是这个调用能找到那个文件。

智能体的输入

tool: Diagnostics
workspace: fixtures/ledger
file: packages/reconcile/src/drift.ts

# answered in 23ms

响应

packages/reconcile/src/drift.ts · 4 problems · packages/reconcile/tsconfig.json

=== packages/reconcile/src/drift.ts ===

error ts(2365) 16:33-16:52 — inside lines.reduce() callback
  Operator '+' cannot be applied to types 'number' and 'Money'.
   14 | /** Statement total, computed by someone who forgot Money is not a number.…
   15 | export const statementTotal = (lines: readonly StatementLine[]): number =>
   16 |   lines.reduce((total, line) => total + line.amount, 0);
      |                                 ^^^^^^^^^^^^^^^^^^^
   17 |
   18 | /** Drift between the journal's view and the bank's view of one day. */

error ts(2365) 20:77-20:91 — inside reduce() callback
  Operator '+' cannot be applied to types 'import("packages/money/src/money").Money' and 'import("packages/money/src/money").Money'.
   18 | /** Drift between the journal's view and the bank's view of one day. */
   19 | export const drift = (postings: readonly Posting[], statement: readonly St…
   20 |   const journalTotal = postings.map(signedAmount).reduce((total, amount) =…
      |                                                                             ^^^^^^^^^^^^^^
   21 |   return format(money(journalTotal - statementTotal(statement), "usd"));
   22 | };

error ts(2345) 21:65-21:70 — inside drift
  Argument of type '"usd"' is not assignable to parameter of type 'Currency'.
   19 | export const drift = (postings: readonly Posting[], statement: readonly St…
   20 |   const journalTotal = postings.map(signedAmount).reduce((total, amount) =…
   21 |   return format(money(journalTotal - statementTotal(statement), "usd"));
      |                                                                 ^^^^^
   22 | };
   23 |

error ts(2362) 21:23-21:35 — inside drift
  The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
   19 | export const drift = (postings: readonly Posting[], statement: readonly St…
   20 |   const journalTotal = postings.map(signedAmount).reduce((total, amount) =…
   21 |   return format(money(journalTotal - statementTotal(statement), "usd"));
      |                       ^^^^^^^^^^^^
   22 | };
   23 |

workspace_symbols

在会话已加载的每个项目中按名称查找声明,适用于你大致知道它叫什么、但完全不知道它在哪里。

智能体的输入

tool: Workspace symbols
workspace: fixtures/ledger
file: packages/importers/src/statement-parser.ts
query: Parser

# answered in 100ms

响应

3 symbols matching Parser · 9 projects loaded · packages/importers/tsconfig.json

CsvStatementParser [class] · packages/importers/src/statement-parser.ts:25:1-35:2
FixedWidthStatementParser [class] · packages/importers/src/statement-parser.ts:41:1-64:2
StatementParser [class] · packages/importers/src/statement-parser.ts:7:1-23:2

file_references

谁导入了这个模块。这个模块级的问题,无需先在其中挑选一个符号即可回答。

智能体的输入

tool: File references
workspace: fixtures/ledger
file: packages/money/src/money.ts

# answered in 134ms

响应

packages/money/src/money.ts · referenced from 90 places · 10 projects loaded · packages/money/tsconfig.json

1-20 of 90 places · pass offset: 20 for the rest

packages/accounts/src/journal.ts
├  1:10  — at module level
└  53:15 — inside post
packages/money/src/index.ts
├  3:3 — at module level
└  4:3 — at module level
packages/money/tests/money.test.ts
├  2:10  — at module level
├  2:15  — at module level
├  5:10  — inside test("adds amounts of one currency exactly") callback
├  9:16  — inside expect() callback
├  9:67  — inside test("refuses to combine currencies") callback
├  13:10 — inside test("formats major and minor units per currency") callback
└  14:10 — inside test("formats major and minor units per currency") callback
packages/reconcile/src/drift.ts
├  5:10  — at module level
└  21:10 — inside drift
packages/reports/src/balance.ts
├  8:10  — at module level
├  34:9  — inside balancesAsOf
└  41:28 — inside balancesAsOf
packages/reports/src/statement.ts
├  2:10  — at module level
└  10:40 — inside statementLine
packages/rules/src/builtin.ts
├  2:10  — at module level
└  28:58 — inside closedPeriodsBalance

Package

Role

@type-atlas/mcp

MCP 服务器

@type-atlas/core

无头代码智能 API

@type-atlas/language-server

由核心包驱动的、基于 Volar 的语言服务器

开发

vp install
vp run check
vp run check:distribution

CONTRIBUTING.md 包含变更和发布流程。

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
33Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Exposes TypeScript Language Server Protocol functionality to AI agents, enabling them to query types at specific positions, find definitions and references, get diagnostics, run type tests, and type-check inline code just like in an IDE.
    9
    102
    3
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A TypeScript-aware MCP server that provides coding agents with repository discovery, code intelligence, and web project context for local codebases. It enables deep symbol navigation, diagnostic reporting, and structural analysis of monorepos without requiring full IDE integration.
    7
    18
    1
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Bridges the Model Context Protocol with Language Server Protocol to provide AI agents with persistent access to code intelligence features including navigation, diagnostics, refactoring, and completion across 7+ programming languages.
    3,520
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI coding agents to interact with TypeScript projects through compiler-level code intelligence, providing tools for navigation, type information, diagnostics, refactoring, and semantic search.
    29
    339
    3
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

  • A Model Context Protocol server for Wix AI tools

  • Give your AI agent a persistent map of your project's structure, dependencies, and bugs.

View all MCP Connectors

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/tyler-mitchell/type-atlas'

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