Skip to main content

Model Context Protocol (MCP) server for TypeScript tooling via vtsls, Prettier, ESLint, and oxlint

Project description

jons-mcp-typescript

Model Context Protocol (MCP) server for TypeScript tooling via vtsls, Prettier, ESLint, and oxlint.

Features

  • TypeScript Language Server Integration - Full LSP support via vtsls for code navigation, symbol information, and type checking
  • Prettier Formatting - Code formatting with automatic config resolution
  • Configured Linting - ESLint or oxlint linting with auto-fix support
  • Unified Operations - Combined check and fix tools for efficient workflows

Installation

Install or run from PyPI:

uvx jons-mcp-typescript /path/to/typescript/project

To run the latest source from GitHub instead of the published package:

uvx --from git+https://github.com/jonmmease/jons-mcp-typescript.git \
  jons-mcp-typescript /path/to/typescript/project

Prerequisites

  1. Python 3.10+ with uv
  2. Node.js 18.18+, Node.js 20.9+, or a newer supported Node.js release. If your target project uses oxlint, use a Node.js version supported by that project-local oxlint release.
  3. vtsls - TypeScript language server, installed globally or in the TypeScript project:
    # Global install
    npm install -g @vtsls/language-server
    
    # Or project-local install
    cd /path/to/typescript/project
    npm install -D @vtsls/language-server
    
  4. Project-local Prettier and configured linter dependencies in the TypeScript project you run the server against:
    cd /path/to/typescript/project
    npm install -D prettier eslint
    # Or, for oxlint-only projects:
    npm install -D prettier oxlint
    

The Python package includes the small Node daemon source. The daemon intentionally uses Prettier, ESLint, and oxlint from your target project's node_modules so formatting and linting match that project.

Usage

Running the Server

# Run from PyPI against the current directory
uvx jons-mcp-typescript .

# Run from PyPI against a specific project root
uvx jons-mcp-typescript /path/to/typescript/project

# Run unreleased source from GitHub
uvx --from git+https://github.com/jonmmease/jons-mcp-typescript.git \
  jons-mcp-typescript .

Local Development (Running from Source)

To run the server locally during development:

# Clone and setup
git clone https://github.com/jonmmease/jons-mcp-typescript.git
cd jons-mcp-typescript
uv sync --group dev

# Install TypeScript project dependencies used by the server
cd /path/to/your/typescript/project
npm install -D @vtsls/language-server prettier eslint
# Or replace eslint with oxlint for oxlint-only projects

# Run against current directory
uv run jons-mcp-typescript

# Run against a specific TypeScript project
uv run jons-mcp-typescript /path/to/your/typescript/project

# Run from anywhere using uv's --project flag (uses cwd as TypeScript project)
cd /path/to/your/typescript/project
uv run --project /path/to/jons-mcp-typescript jons-mcp-typescript .

MCP Client Configuration

Claude Code

From the TypeScript project root, add the server to Claude Code:

cd /path/to/typescript/project
claude mcp add typescript --scope local -- \
  uvx jons-mcp-typescript .

Use --scope project instead of --scope local if you want Claude Code to write a shared .mcp.json file in the project. A shared project config should look like this:

{
  "mcpServers": {
    "typescript": {
      "command": "uvx",
      "args": [
        "jons-mcp-typescript",
        "."
      ]
    }
  }
}

Verify it with:

claude mcp get typescript

Codex CLI

From the TypeScript project root, add the server to Codex:

cd /path/to/typescript/project
codex mcp add typescript -- \
  uvx jons-mcp-typescript .

This writes an MCP server entry to Codex's config. The equivalent TOML is:

[mcp_servers.typescript]
command = "uvx"
args = [
  "jons-mcp-typescript",
  ".",
]

Verify it with:

codex mcp get typescript

If you want the MCP server to always target one specific TypeScript project, replace the final "." with an absolute project path in the CLI command or config.

Local Checkout Configuration

For active development on this MCP server, clone the repo and point your MCP client at the checkout:

git clone https://github.com/jonmmease/jons-mcp-typescript.git
cd jons-mcp-typescript
uv sync --group dev

Then configure your MCP client to run:

{
  "mcpServers": {
    "typescript": {
      "command": "uv",
      "args": [
        "run",
        "--project", "/path/to/jons-mcp-typescript",
        "jons-mcp-typescript",
        "."
      ]
    }
  }
}

This tells uv to use the Python environment from /path/to/jons-mcp-typescript and run jons-mcp-typescript against the current working directory, which should be your TypeScript project.

Available Tools

Navigation & Discovery

Tool Purpose
document_symbols List all symbols defined in a file
definition Jump to where a symbol is defined
type_definition Jump to the type definition of a symbol
implementation Find implementations of interfaces/abstract classes
references Find all usages of a symbol

Understanding Code

Tool Purpose
type_info_of_reference Get TypeScript display info and accessible members for a value reference
symbol_info Get type signature and docs for any symbol

Type Checking

Tool Purpose
diagnostics Get fresh type errors and warnings for one file

Refactoring

Tool Purpose
preview_rename Preview a symbol rename across the project without writing files

Formatting & Linting

Tool Purpose
format_code Format code using Prettier
check_formatting Check if code is formatted correctly
lint_code Lint code using the configured ESLint or oxlint runner
get_prettier_config Get resolved Prettier configuration
get_eslint_config Get selected linter config information; ESLint projects return resolved config, oxlint projects return config-file metadata

Unified Operations

Tool Purpose
check_all Run all checks (formatting, linting, types) on a file
fix_all Apply all automatic fixes to a file

Server Management

Tool Purpose
restart_server Restart TypeScript language server and formatter/linter daemon

Tool Examples

Recommended Workflow

For most single-file quality checks, start with check_all. It runs TypeScript diagnostics, Prettier, and the configured lint runner together and returns one combined summary. The lint step uses ESLint when an ESLint config is nearest, uses oxlint when an oxlint config is nearest and no ESLint config applies, and skips cleanly when no linter config exists. Use fix_all when you want automatic linter fixes followed by Prettier formatting, optionally writing the result back to disk.

format_code, check_formatting, and lint_code remain available as lower level tools when you need only one formatter or linter operation. For project-wide symbol-name discovery, start with text search to find candidate files, then use document_symbols or the semantic position-based tools.

preview_rename is safe to inspect: it returns edits, a flat list of file URI, one-based replacement range, and newText values, plus totalEdits. It does not write to disk by itself.

In monorepos, semantic tools such as references, implementation, and preview_rename are limited to the TypeScript project scope that vtsls can see for the probed file. A root solution tsconfig.json or editor-equivalent project setup can make more packages visible, but the server does not auto-index or preload every workspace package. Without that TypeScript project coverage, sibling or downstream packages may be omitted from semantic results. TypeScript project loading is lazy, so the first call against a newly probed package can occasionally report that the project is not ready; retrying the same tool shortly is usually enough once vtsls finishes loading that project.

Position Inputs And Results

Tools such as definition, references, symbol_info, type_info_of_reference, and preview_rename use one-based positions for both inputs and returned ranges. If your editor, terminal listing, or agent Read output shows line 28, pass line=28; returned ranges also use line 28 for that same source line. When you do not already know a position, document_symbols returns one-based ranges for the symbols in a file.

Navigate to Definition

# Find where a function is defined
result = await definition(
    file_path="/project/src/index.ts",
    line=10,
    character=15,
)
# Returns: {"items": [{"uri": "file:///project/src/utils.ts", "range": {...}}], "totalItems": 1}

Get Type Information

# Get TypeScript display info plus fields and methods of a value reference
result = await type_info_of_reference(
    file_path="/project/src/app.ts",
    line=5,
    character=8,
)
# Returns: {"displayString": "const user: User", "kind": "const", "fields": [...], "methods": {...}}

Check Everything

# Run TypeScript, Prettier, and configured linter checks for one file
result = await check_all(
    file_path="/project/src/app.ts"
)
# Returns: {"overallPassed": false, "checks": {...}, "summary": "..."}

Fix Everything

# Run configured linter fixes, then Prettier formatting
result = await fix_all(
    file_path="/project/src/app.ts",
    write=True,
)
# Returns: {"finalCode": "...", "totalChanges": 2, "written": true}

Preview Rename

# Preview a project-scoped symbol rename without writing files
result = await preview_rename(
    file_path="/project/src/app.ts",
    line=12,
    character=8,
    new_name="newName",
)
# Returns:
# {
#   "edits": [{"uri": "file:///project/src/app.ts", "range": {...}, "newText": "newName"}],
#   "totalEdits": 1,
# }

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        MCP Client                               │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    FastMCP Server (Python)                      │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │                    Tool Handlers                          │   │
│  │  language.py  intelligence.py  formatting.py  linting.py │   │
│  └──────────────────────────────────────────────────────────┘   │
│                   │                    │                        │
│                   ▼                    ▼                        │
│  ┌─────────────────────┐   ┌─────────────────────────────────┐ │
│  │    VtslsClient      │   │   FormatterLinterDaemon        │  │
│  │  (LSP over stdio)   │   │   (JSON Lines over stdio)      │  │
│  └─────────────────────┘   └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
           │                            │
           ▼                            ▼
┌─────────────────────┐   ┌─────────────────────────────────────┐
│       vtsls         │   │         Node.js Daemon              │
│  (TypeScript LSP)   │   │  ┌─────────────────────────────┐    │
│                     │   │  │   PrettierManager          │    │
│                     │   │  │   LinterManager            │    │
│                     │   │  │   ESLint / oxlint          │    │
│                     │   │  └─────────────────────────────┘    │
└─────────────────────┘   └─────────────────────────────────────┘

Configuration

Environment Variables

Variable Description Default
VTSLS_PATH Path to vtsls executable Auto-detected
LOG_LEVEL Logging level (DEBUG, INFO, etc.) INFO

Config Resolution

  • Prettier: Resolves .prettierrc, .prettierrc.json, .prettierrc.js, etc.
  • Linting: Walks from the file directory to the project root. At each directory, ESLint configs (eslint.config.*, .eslintrc*, or package.json eslintConfig) win over oxlint configs (.oxlintrc.json, .oxlintrc.jsonc, or oxlint.config.*). If no lint config exists, lint tools return a skipped result instead of failing.
  • TypeScript: Uses vtsls and the TypeScript project that vtsls associates with the probed file. In monorepos, cross-package semantic coverage depends on your tsconfig.json/project-reference setup rather than server-side workspace preloading.

Development

Setup

git clone https://github.com/jonmmease/jons-mcp-typescript.git
cd jons-mcp-typescript
uv sync --group dev

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=src/jons_mcp_typescript

# Run specific test file
uv run pytest tests/test_utils.py -v

Test Requirements

Integration tests require:

  • Node.js 18.18+, Node.js 20.9+, or a newer supported Node.js release
  • Node.js 20.19+ for oxlint integration tests when using current oxlint releases
  • vtsls installed globally or in the temporary test project
  • Prettier plus ESLint or oxlint available to the temporary test project

Tests will skip gracefully if dependencies are missing.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jons_mcp_typescript-0.0.2-py3-none-any.whl (71.4 kB view details)

Uploaded Python 3

File details

Details for the file jons_mcp_typescript-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for jons_mcp_typescript-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0c84d0a6bfedc9ec2f8792bb5b136ab2d1aeaa6fe755b05989746775a7791693
MD5 52e8654c87689c0ae5a3cbc169e4995e
BLAKE2b-256 e15b1b5394eb0f41ac12238e15095432540827579087817cdf17cfd025a08cf9

See more details on using hashes here.

Provenance

The following attestation bundles were made for jons_mcp_typescript-0.0.2-py3-none-any.whl:

Publisher: release.yml on jonmmease/jons-mcp-typescript

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page