TypeScript type inference inspection tool for AI coding assistants
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add typeprobe -- npx -y typeprobe{
"mcpServers": {
"typeprobe": {
"command": "npx",
"args": ["-y", "typeprobe"]
}
}
}Resumen de MCP Servers
<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 }`, tLo que la gente pregunta sobre typeprobe
¿Qué es clockblocker/typeprobe?
+
clockblocker/typeprobe es mcp servers para el ecosistema de Claude AI. TypeScript type inference inspection tool for AI coding assistants Tiene 1 estrellas en GitHub y su última actualización registrada es del 2026-10-10.
¿Cómo se instala typeprobe?
+
Puedes instalar typeprobe clonando el repositorio (https://github.com/clockblocker/typeprobe) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar clockblocker/typeprobe?
+
Nuestro agente de seguridad ha analizado clockblocker/typeprobe y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene clockblocker/typeprobe?
+
clockblocker/typeprobe es mantenido por clockblocker. La última actividad registrada en GitHub es del 2026-10-10, con 0 issues abiertos.
¿Hay alternativas a typeprobe?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega typeprobe en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](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>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
The fastest path to AI-powered full stack observability, even for lean teams.