Skip to main content
ClaudeWave

TypeScript type inference inspection tool for AI coding assistants

MCP ServersOfficial Registry1 stars0 forks● TypeScriptMITUpdated today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/11/2026
Install in Claude Code / Claude Desktop
Method: NPX · typeprobe
Claude Code CLI
claude mcp add typeprobe -- npx -y typeprobe
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "typeprobe": {
      "command": "npx",
      "args": ["-y", "typeprobe"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Use cases

MCP Servers overview

<p align="center">
  <img src="typeprobe-logo.webp" alt="typeprobe logo" width="400">
</p>

# typeprobe

typeprobe asks the TypeScript compiler what it infers (types, completions, type errors) so that AI coding agents and tests don't have to guess. It comes as:

- an MCP server for coding agents (Claude Code, Codex, Cursor, VS Code, Gemini CLI, any stdio client),
- `typeprobe/testing`, which returns inferred types as strings for snapshot tests,
- a CLI and a synchronous library API.

typeprobe was called prinfer until 4.0.0. See [Migrating from prinfer](#migrating-from-prinfer).

## Quick start

Give your agent the compiler:

```bash
npx -y typeprobe setup claude    # or codex, cursor, vscode, gemini; see Install
```

The agent can now call `hover_by_name(file: "src/utils.ts", name: "names")` and get `Type: string[]` back, or `diagnostics(file)` after an edit.

Lock the types your API infers in a test (Vitest, Jest, Bun, or any runner with snapshots):

```typescript
import { expect, test } from "vitest"; // or "bun:test"
import { inferredType } from "typeprobe/testing";
import { groupBy, type User } from "../src/users";

const users: User[] = [{ name: "Ada", role: "admin" }];
const byRole = groupBy(users, (user) => user.role);

test("groupBy keys the result by the callback's return type", () => {
  expect(inferredType(import.meta.url, { name: "byRole" }))
    .toMatchInlineSnapshot(`"Record<Role, User[]>"`);
});
```

Write the matcher empty (`toMatchInlineSnapshot()`) and the runner fills it in. A refactor that changes the type fails the test.

## Install

Every command runs through `npx`, so nothing needs installing first. After `npm i -g typeprobe`, drop the `npx -y` prefix: setup then registers the `typeprobe-mcp` binary, which skips npx's package check on each launch.

**Claude Code.** The plugin bundles the MCP server and a skill that tells Claude when to use it:

```text
/plugin marketplace add clockblocker/typeprobe
/plugin install typeprobe@typeprobe
```

**Other clients**, or Claude Code without the plugin:

| Client | Command | Writes |
| :- | :- | :- |
| Claude Code | `npx -y typeprobe setup claude` | `claude mcp add`; `--scope project` for a shared `.mcp.json` |
| Codex | `npx -y typeprobe setup codex` | `codex mcp add` (`~/.codex/config.toml`) |
| Cursor | `npx -y typeprobe setup cursor` | `~/.cursor/mcp.json`; `--scope project`: `.cursor/mcp.json` |
| VS Code | `npx -y typeprobe setup vscode` | `code --add-mcp`; `--scope project`: `.vscode/mcp.json` |
| Gemini CLI | `npx -y typeprobe setup gemini` | `~/.gemini/settings.json`; `--scope project`: `.gemini/settings.json` |

Any other MCP client: typeprobe is a stdio server started with `npx -y typeprobe mcp`.

```json
{
  "mcpServers": {
    "typeprobe": { "command": "npx", "args": ["-y", "typeprobe", "mcp"] }
  }
}
```

It is also listed in the [MCP Registry](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.clockblocker/typeprobe) as `io.github.clockblocker/typeprobe` and on [Smithery](https://smithery.ai/servers/clockblocker/typeprobe).

Setup options:

- `--print` shows the command or config change without applying it.
- `--npx` registers `npx -y typeprobe mcp` even when `typeprobe-mcp` is installed. Use it when the client can't find `typeprobe-mcp`; editors started outside a shell often miss nvm, fnm, or volta paths.
- Re-running setup updates the `typeprobe` entry's command and leaves other servers alone. JSON configs keep keys you added to the entry, such as `env`. A JSON config that doesn't parse is left untouched, and setup prints the entry to add by hand.
- A `prinfer` entry from before the rename is replaced rather than kept next to the new one: `claude` and `codex` remove it, and JSON configs swap it for `typeprobe` in place, keeping its other keys (with `PRINFER_*` env names renamed to `TYPEPROBE_*`).
- On Windows the server is registered as `cmd /c npx -y typeprobe mcp` (or `cmd /c typeprobe-mcp`), because clients launch it without a shell and can't run npm's `.cmd` shims.

### Tell the agent when to use it

Tool descriptions only go so far; agents still reach for `tsc` or write annotations by hand. Add a short usage block to your instructions file (the Claude Code plugin ships the same guidance as a skill):

```bash
npx -y typeprobe setup agents-md                  # ./AGENTS.md
npx -y typeprobe setup agents-md --file CLAUDE.md
```

The block sits between `<!-- typeprobe:start -->` and `<!-- typeprobe:end -->`; re-running updates it in place, and replaces a block prinfer wrote (`<!-- prinfer:start -->`).

## MCP tools

| Tool | Use it for |
| :- | :- |
| `hover_by_name` | The type of a named symbol. Start here. |
| `hover` | The type of a token on a line: callback parameters, expressions, repeated names. |
| `batch_hover` | Up to 100 lookups, across files, in one call. |
| `completions` | What TypeScript offers at a cursor, such as string-literal union members. |
| `diagnostics` | Type errors in one file, without checking the whole project. |
| `annotations` | Annotations TypeScript would infer anyway. |

Shared parameters:

- `file` is absolute or relative to the server's working directory. Lines and columns are 1-based.
- `project` is a `tsconfig.json` path; the default is the nearest one above the file.
- `backend` (`typescript7` by default, or `typescript6`) on the hover tools and `diagnostics`. If a call fails or looks wrong on TypeScript 7, retry it with `typescript6`. See [Backends and compilers](#backends-and-compilers).
- Hover tools take `include_docs` (JSDoc), `include_cost` (see [Type cost budgets](#type-cost-budgets)), `full`, and `max_chars`. Type text is capped at 4000 characters per type, and a cut type ends with a line like `… truncated: 187 chars total, union of 4 members. Pass max_chars: N to see more (0 for no limit).` `full: true` turns off TypeScript's own truncation (`{ ...; }`, `... 12 more ...`) and lists every overload. Structured content is never cut.

### hover_by_name

```text
hover_by_name(file: "src/utils.ts", name: "names")
hover_by_name(file: "src/utils.ts", name: "names", line: 11)   # line picks among same-named symbols
```

```text
Type: string[]
Name: names
Kind: const
Position: 11:14
```

When a name is declared more than once, the lookup prefers declarations and says which it picked: `Matched line 8 of 2 declarations (also 12); pass line to choose.` The structured result lists the others as `alternatives: [{ line, column, kind }]`. A `line` that matches none fails with `SYMBOL_NOT_FOUND` and lists the declaration lines in `declaredAt`. A `line` where the name is used rather than declared, such as `box.value` in an `if`, gives the type there, narrowed by the code around it.

Overloaded functions show the first signature, then up to three more (`full: true` lists all; structured `overloads` always has every one):

```text
Type: (value: string): number (+1 overload)
Overloads:
  (value: number): string
Returns: number
Name: parse
Kind: function
Position: 1:17
```

### hover

Pass `text` copied from the line and typeprobe finds the column. Whole identifiers match first: on `users.map((user) => user.name)`, `text: "user"` skips `users` and hits the callback parameter, and `occurrence: 2` picks the next `user`. Only when the line has no whole-identifier match is `text` matched as a substring. `column` works in place of `text`. Generic calls show their instantiated types, as in an editor.

```text
hover(file: "src/utils.ts", line: 11, text: "user")
```

```text
Type: { id: number; name: string; }
Name: user
Kind: parameter
Position: 11:33
Target: "user" at 11:33
```

If the text isn't on the line, the error quotes the line:

```text
Error [SYMBOL_NOT_FOUND]: Text "nope" not found on line 11 of /project/src/utils.ts
Nearby identifiers: name, names, map, user, users
Suggestion: Line 11 reads: "export const names = users.map((user) => user.name);". Copy text exactly from it, or give a column instead.
```

### batch_hover

Each item is `{name, line?}`, `{line, text, occurrence?}`, or `{line, column}`, with an optional `file` that overrides the shared top-level `file`. Failures are per item, including a missing file, so one bad lookup doesn't lose the rest.

```text
batch_hover(file: "src/utils.ts", positions: [
  {name: "users"},
  {line: 11, text: "user"},
  {file: "src/missing.ts", line: 1, column: 1}
])
```

```text
Batch hover results: 2 succeeded, 1 failed

--- src/utils.ts:users:6 ---
Type: { id: number; name: string; }[]
...

--- src/missing.ts:1:1 ---
Error [FILE_NOT_FOUND]: File not found: /project/src/missing.ts
Suggestion: Check the path. Relative paths resolve against the MCP server's working directory (/project); pass an absolute path to be sure.
```

A line or column outside the file is an `INVALID_ARGUMENT` error that gives the valid range.

### Hover results

Every hover returns the same fields on every backend and surface:

- `signature`: the type text alone, on one line, without the declaration keyword or name an editor hover starts with. `string[]` for a variable, `(value: string): number` for a function, the instantiated signature for a call. Type aliases keep their name and type parameters (`type Event = { kind: "open"; ... } | ...`); interfaces and classes are their name (`Box<T>`). Optional members read as `tsc` writes them in declarations: `digits?: number`, with `| undefined` only where the source wrote it or the type isn't the annotation's (an instantiated generic, a `Partial<T>`).
- `display`: the editor's hover text (`const names: string[]`). Only the TypeScript 7 language server reports it.
- `kind`: the editor's label (`function`, `method`, `const`, `parameter`, `property`, `type`, `interface`, `class`, `enum`, ...), plus `call` for the callee of a call.
- `returnType`, `documentation`, `overloads`, `unionMembers`, and `alternatives` when they apply.
- `cost`: `{ instantiations, types }` with `include_cost: true`.
- `compiler`: `{ name, version, source }`, t
ai-agentsclaude-codeclideveloper-toolsmcpmcp-servermodel-context-protocoltype-inferencetypescripttypescript-compiler

What people ask about typeprobe

What is clockblocker/typeprobe?

+

clockblocker/typeprobe is mcp servers for the Claude AI ecosystem. TypeScript type inference inspection tool for AI coding assistants It has 1 GitHub stars and its last recorded update is dated 2026-10-10.

How do I install typeprobe?

+

You can install typeprobe by cloning the repository (https://github.com/clockblocker/typeprobe) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is clockblocker/typeprobe safe to use?

+

Our security agent has analyzed clockblocker/typeprobe and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains clockblocker/typeprobe?

+

clockblocker/typeprobe is maintained by clockblocker. The last recorded GitHub activity is dated 2026-10-10, with 0 open issues.

Are there alternatives to typeprobe?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy typeprobe to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: clockblocker/typeprobe
[![Featured on ClaudeWave](https://claudewave.com/api/badge/clockblocker-typeprobe)](https://claudewave.com/repo/clockblocker-typeprobe)
<a href="https://claudewave.com/repo/clockblocker-typeprobe"><img src="https://claudewave.com/api/badge/clockblocker-typeprobe" alt="Featured on ClaudeWave: clockblocker/typeprobe" width="320" height="64" /></a>

More MCP Servers

typeprobe alternatives