Skip to main content

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

Project description

jons-mcp-typescript

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

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
  • ESLint Linting - Code 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
  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 ESLint in the TypeScript project you run the server against:
    cd /path/to/typescript/project
    npm install -D prettier eslint
    

The Python package includes the small Node daemon source. The daemon intentionally uses Prettier and ESLint 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

# 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 ESLint
get_prettier_config Get resolved Prettier configuration
get_eslint_config Get resolved ESLint configuration

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 ESLint together and returns one combined summary. Use fix_all when you want automatic ESLint 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 ESLint checks for one file
result = await check_all(
    file_path="/project/src/app.ts"
)
# Returns: {"overallPassed": false, "checks": {...}, "summary": "..."}

Fix Everything

# Run ESLint 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          │    │
│                     │   │  │   ESLintManager            │    │
│                     │   │  └─────────────────────────────┘    │
└─────────────────────┘   └─────────────────────────────────────┘

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.
  • ESLint: Resolves eslint.config.js (flat config) or .eslintrc.*
  • 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
  • vtsls installed globally or in the temporary test project
  • Prettier and ESLint 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.1-py3-none-any.whl (64.4 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for jons_mcp_typescript-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 83965d8972b1222df00863c228a4b24728d188d320c5bbdb10d1b90e35c88ce9
MD5 bf2b19a3c00de8082749403f07611c3d
BLAKE2b-256 85db9a637eeb7a35165502e113e79a330dc49978e80d25f3f742a846e7109559

See more details on using hashes here.

Provenance

The following attestation bundles were made for jons_mcp_typescript-0.0.1-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