Skip to main content
Glama

npm node license

Type Atlas는 제가 모든 TypeScript 프로젝트에서 모든 코드 탐색 작업에 사용하도록 모든 코드 에이전트에 적용하는 도구입니다. 대부분의 프로젝트는 모노레포입니다. 일부는 변경 사항이 시스템의 나머지 부분에 어떻게 맞아떨어지는지 이해하는 것이 실제 작업의 일부가 될 만큼 크고 복잡합니다. 이 도구는 에이전트의 기본 코드 탐색 방식을 완전히 대체하도록 설계되었습니다.

저는 제 코딩 에이전트가 제 프로젝트에서 실제로 작동하는 방식을 바탕으로 수개월 동안 이 도구를 반복 개선해 왔습니다. Type Atlas가 하는 대부분의 일은 제가 계속 같은 문제를 목격했기 때문에 존재합니다:

  • 에이전트는 시스템에 대한 불완전한 시야로 추론합니다. 파일을 찾았지만 그 파일이 어떻게 사용되어야 하는지를 결정하는 주변 코드를 놓칠 수 있습니다.

  • 에이전트는 이미 존재하는 것을 다시 만듭니다. 그 기능은 이미 저장소에 있지만, 에이전트는 그것이 무엇이라고 불리는지 모르기 때문에 찾지 못합니다.

  • 에이전트는 코드를 너무 적게 읽거나(Claude) 훨씬 너무 많이 읽습니다(Codex). 너무 적게 읽으면 충분한 주변 맥락 없이 결정을 내리게 됩니다. 너무 많이 읽으면 작업과 무관한 전체 파일과 구현 세부 사항으로 컨텍스트 창을 채웁니다.

  • 에이전트는 IDE가 이미 보여주고 있을 오류를 찾기 위해 반복적으로 타입 검사를 실행하느라 멈춥니다. 이는 구현 전반에 지연을 추가하고 피드백을 필요보다 늦게 도착하게 만듭니다.

  • 에이전트는 근본적으로 맹목적으로 작동합니다. 문자열 검색 탐색은 코드베이스에 대한 강력한 내부 지도를 제공하지 않습니다. 에이전트는 우연히 검색된 파일 조각과 일치 항목으로 구현 결정을 내려야 하며, 중요한 구조와 컴파일러가 알고 있는 정보는 여전히 누락되어 있습니다.

프로젝트가 성장함에 따라 이러한 문제는 누적되어 에이전트가 작성하는 코드 품질에 직접적으로 나타나기 시작합니다.

의미론적 코드 탐색

코딩 에이전트는 기본적으로 파일 읽기와 문자열 검색을 통해 코드를 탐색합니다. 이는 소스 텍스트를 제공하고 모델이 TypeScript 언어 서비스가 이미 알고 있는 관계를 재구성하도록 남겨둡니다.

Type Atlas는 에이전트에게 그 의미론적 정보에 대한 직접적인 접근을 제공합니다:

  • 심볼은 같은 텍스트의 모든 출현이 아닌 실제 정의와 참조로 해석됩니다.

  • 호출자와 구현은 심볼과의 관계로 식별됩니다.

  • 추론된 타입은 주변 소스에서 재구성되는 대신 언어 서비스에서 제공됩니다.

  • 결과는 소스 범위와 소유 TypeScript 프로젝트가 첨부된 상태로 유지됩니다.

텍스트 일치는 에이전트가 텍스트를 찾고 있을 때 여전히 유용합니다. 그러나 질문이 프로그램 자체에 관한 것일 때 의미론적 탐색의 약한 대체재일 뿐입니다.

이미 존재하는 것 찾기

대규모 코드베이스에는 에이전트가 이름으로 알 이유가 없는 유용한 코드가 포함되어 있습니다. 문자열 검색은 에이전트가 검색을 구성할 수 있을 만큼의 어휘를 이미 알고 있을 때 가장 잘 작동합니다.

Type Atlas는 다른 진입 경로를 제공합니다:

  • 에이전트는 자연어로 동작을 설명하고 코드가 하는 일을 기반으로 코드를 찾을 수 있습니다.

  • 발견된 결과는 실제 심볼과 정확한 소스 범위로 연결됩니다.

  • 그 심볼에서 에이전트는 또 다른 식별자를 추측하여 검색하는 대신 코드베이스를 통해 실제 관계를 따라갈 수 있습니다.

이는 대규모 모노레포에서 특히 유용합니다. 에이전트가 또 다른 것을 만들어야 한다고 결정하기 전에 기존 헬퍼와 확립된 구현을 더 쉽게 발견할 수 있습니다.

일반 작업 중 진단

IDE의 개발자는 작업 중에 컴파일러 피드백을 봅니다. 코딩 에이전트는 일반적으로 구현을 중단하고 타입 검사 명령을 실행한 다음 결과를 기다려서 그 피드백을 얻습니다.

Type Atlas는 그 피드백의 상당 부분을 에이전트가 이미 수행하고 있던 작업으로 이동시킵니다:

  • 관련 진단이 일반적인 코드 인텔리전스 응답과 함께 도착할 수 있습니다.

  • 오류는 영향을 받는 코드가 여전히 에이전트의 현재 작업 컨텍스트의 일부일 때 표시됩니다.

  • 잘못된 타입 가정은 여러 개의 의존적 편집으로 바뀌기 전에 잡을 수 있습니다.

저는 여전히 검증을 위해 전체 타입 검사를 사용합니다. 그러나 그것이 에이전트가 작업 중에 오류를 알게 되는 주요 방식일 필요는 없습니다.

응답은 모델 컨텍스트에 맞게 구성됨

응답을 더 작게 만드는 것은 제거된 정보가 불필요했을 때만 유용합니다. 모델은 또한 남은 것의 구성을 사용합니다.

Type Atlas는 구조를 정보의 일부로 취급합니다:

  • 레이블은 결과의 역할을 명시적으로 만듭니다.

  • 그룹화는 관련 사실을 함께 유지합니다.

  • 파일 경계는 관련 없는 소스가 서로 섞이는 것을 방지합니다.

  • 소스 위치는 설명하는 대상에 첨부된 상태로 유지됩니다.

  • 트리는 평평한 시퀀스가 아닌 계층 구조를 유지합니다.

  • 진단은 이를 이해하는 데 필요한 소스를 유지합니다.

동일한 원칙이 무엇을 생략할지 결정합니다. 시그니처로 충분할 때 함수 본문은 접힌 상태로 유지될 수 있습니다. 반복적인 직렬화와 관련 없는 소스는 단지 사용 가능하다는 이유만으로 컨텍스트 창을 차지할 필요가 없습니다.

목표는 유용한 정보 밀도입니다. 더 적은 토큰이 중요하지만, 모델이 그 토큰을 이해하는 데 도움이 되는 구조를 제거하는 것은 목적을 무너뜨리는 것입니다.

다음 결정을 위한 정보

모든 도구 호출은 에이전트의 추론 과정의 일부입니다. 좋은 응답은 현재 질문에 답하면서 에이전트가 다음에 무엇을 검사할지 결정할 수 있는 더 나은 위치에 있게 해야 합니다.

Type Atlas는 유용한 후속 정보를 그것을 노출한 결과 가까이에 유지합니다:

  • 심볼은 코드베이스에서 어떻게 참여하는지 이해하는 데 필요한 관계와 함께 도착할 수 있습니다.

  • 저장소 구조는 파일 자체와 함께 줄 수와 작업 트리 상태를 전달할 수 있습니다.

  • 검색 결과는 직접 따라갈 수 있는 구체적인 소스 범위를 포함합니다.

  • 에이전트가 한 결과에서 다른 결과로 이동할 때 프로젝트 컨텍스트는 첨부된 상태로 유지됩니다.

이는 에이전트가 조사의 각 분기에서 더 나은 증거를 갖게 합니다. 모든 텍스트 일치를 동등하게 의미 있는 단서로 취급하는 대신 프로그램에 실제로 존재하는 관계를 따라갈 수 있습니다.

이점은 더 높은 품질의 탐색입니다. 각 단계는 다음 단계를 선택하는 데 필요한 정보를 더 많이 보존합니다.

프로젝트 및 범위 인식

TypeScript 질문은 프로젝트 컨텍스트에 따라 달라집니다. 이는 답변이 한 프로젝트 내에서는 정확하면서도 저장소 전체로는 불완전할 수 있는 모노레포에서 특히 중요해집니다.

Type Atlas는 그 경계를 보이게 유지합니다:

  • 파일은 해당 파일을 소유한 TypeScript 프로젝트를 통해 해석됩니다.

  • 결과는 범위가 중요할 때 출처가 된 프로젝트 범위를 명시합니다.

  • 개수는 결과의 크기를 명시적으로 만듭니다.

  • 답변이 저장소 전체보다 적게 다룰 때 한계가 명시됩니다.

  • 소스 위치는 이후 호출에 직접 전달될 수 있습니다.

에이전트는 답변에 의존하기 전에 답변이 실제로 무엇을 다루는지 이해할 수 있는 충분한 정보를 얻습니다.

일상적인 에이전트 사용에서 구축됨

저는 모든 TypeScript 프로젝트에서 제 코딩 에이전트와 함께 Type Atlas를 매일 사용합니다. 현재의 동작은 반복적인 사용에서 나왔습니다.

디자인의 상당 부분은 반복되는 에이전트 동작에서 직접 추적할 수 있습니다:

  • 에이전트가 필요하지 않은 본문에 컨텍스트를 소비하고 있었기 때문에 읽기가 접힙니다.

  • 반복적인 타입 검사 명령이 구현 시간을 낭비하고 있었기 때문에 진단이 일반 응답과 함께 이동합니다.

  • 에이전트가 별도의 호출을 통해 같은 정보를 계속 재구성하고 있었기 때문에 의미론적 관계가 그룹화됩니다.

  • 유용한 코드가 종종 에이전트가 작업에서 추론할 수 없는 이름을 가지고 있기 때문에 자연어 코드 검색이 존재합니다.

그것이 여전히 제가 Type Atlas를 작업하는 방식입니다. 에이전트가 같은 탐색 문제에 시간을 낭비하거나 같은 종류의 정보를 반복적으로 놓치는 것을 계속 보게 되면, 저는 도구를 변경합니다.

아래 예제는 픽스처 모노레포에 대해 실행 중인 서버에서 캡처되었으며 구현으로 회귀 검사되었습니다.

설치

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"]
    }
  }
}

셸 PATH 없이 서버를 시작하는 클라이언트는 이름으로 npx를 찾지 못합니다. 그런 경우 which npx의 절대 경로를 제공하십시오. Windows에서 npx.cmd 셰임을 실행할 수 없는 클라이언트는 "args": ["/c", "npx", "--yes", "@type-atlas/mcp@latest"]와 함께 "command": "cmd"가 필요합니다.

클라이언트는 시작 시 MCP 구성을 읽으므로 이후에 다시 시작하십시오. @latest는 모든 프로세스 시작 시 해석됩니다. 도구 동작이 사용자 모르게 변경되는 것을 원하지 않으면 버전을 고정하십시오.

search_code, related_code, investigate_code, search_dependency_code는 uvx를 통해 의미론적 인덱스를 실행하며 uv가 필요합니다. 없으면 이 네 가지는 uv가 누락되었다고 보고하고, explore_symbol는 관련 코드 섹션을 생략하며, 나머지는 영향을 받지 않습니다.

권장 사항

서버를 설치해도 에이전트가 사용하는 도구는 바뀌지 않습니다. Claude를 포함한 일부 에이전트는 셸이 허용하는 모든 것을 연결하여 조립하고 매번 새로운 정당성을 만들어 내므로, 피해야 할 몇 가지 명령을 지정하는 것은 효과가 없습니다. 지침은 전체 범주를 배제하고 예외를 명명해야 합니다. AGENTS.md 또는 CLAUDE.md에 다음을 추가하십시오:

Type Atlas MCP는 TypeScript 및 JavaScript에서 코드를 읽고 탐색하는 데 필수 도구입니다. 이것은 선호가 아닙니다. 어떤 구성의 셸 명령도 허용 가능한 대체재가 아니며, 일반 파일 읽기도 아닙니다. 유효한 대체 수단은 서버가 다운된 경우, 호출이 오류를 반환한 경우, 또는 TS도 JS도 아닌 파일뿐입니다.

--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

호버, 정의, 타입 정의, 구현, 호출자, 호출, 참조를 한 번의 호출로 제공합니다. 참조는 호출자와 정의가 설명된 후의 잔여물이므로 사용은 한 번만 나열됩니다. 이 도구들을 별도로 호출하는 것에 비해 문자 수는 4배 적고 왕복은 7배 적습니다.

에이전트 입력

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 · 5 relevant projects searched)

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

파일별로 그룹화된 리터럴 텍스트와 스캔된 파일 수입니다. 의미론적 도구는 존재하는 것을 순위화하므로, teardown 후 토큰이 사라졌는지 확인하는 데는 쓸모가 없습니다. 여기서 0이 나오는 것은 동일한 스캔 횟수와 함께 오므로, 의미 있는 결과입니다.

Agent의 입력

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

이름을 추측할 수 없을 때, 코드가 하는 일을 기준으로 코드를 찾습니다. 결과는 순위 순서로 반환되며, 각 결과는 해당 코드가 나온 파일 범위를 포함하므로 다음 호출이 갈 곳을 알 수 있습니다. 라이브 응답에는 히트당 관련성 백분율도 포함되지만, 아래에서는 생략되었습니다. 그 이유는 그 뒤에 있는 임베딩 점수가 머신마다 다르고, 이 사례들은 바이트 단위로 비교되기 때문입니다.

Agent의 입력

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

파일 단위 패스가 아닌, 프로젝트별 컴파일러의 전체 프로그램 검사입니다. 한 파일의 편집은 보통 다른 파일을 깨뜨리며, 이 호출이 그 파일을 찾아냅니다.

Agent의 입력

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

세션이 로드한 모든 프로젝트에서 이름으로 선언을 찾습니다. 대략적인 이름은 알지만 위치에 대해서는 아무것도 모를 때 사용합니다.

Agent의 입력

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

# answered in 100ms

응답

3 symbols matching Parser · 8 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

이 모듈을 누가 import하는지. 모듈 수준의 질문으로, 먼저 내부의 심볼을 선택하지 않고도 답할 수 있습니다.

Agent의 입력

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

# answered in 134ms

응답

packages/money/src/money.ts · referenced from 90 places · 6 relevant projects searched · 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
└  5:3 — at module level
packages/money/tests/money.test.ts
├  2:10  — at module level
├  2:15  — at module level
├  2:38  — 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/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

패키지

패키지

역할

@type-atlas/mcp

MCP 서버

@type-atlas/core

헤드리스 코드 인텔리전스 API

@type-atlas/language-server

core 패키지가 구동하는 Volar 기반 언어 서버

개발

vp install
vp run check
vp run check:distribution

CONTRIBUTING.md에 변경 및 릴리스 프로세스가 있습니다.

Related MCP Connectors

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
    614 npm
    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
    15 npm
    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.
    1,932 npm
    MIT
  • A
    license
    A
    quality
    B
    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
    225 npm
    3
    Apache 2.0