npm package: @schlegel/mcp-sync
Description: Project-first MCP server manager. Like dotenv + Homebrew for MCP servers.
Author: schlegel
Latest version: 0.2.0

<div align="center">

# mcp-sync

**Like `.env` + Homebrew for MCP servers.**

[![npm](https://img.shields.io/npm/v/@schlegel/mcp-sync?color=58A6FF&style=flat-square)](https://www.npmjs.com/package/@schlegel/mcp-sync)
[![CI](https://img.shields.io/github/actions/workflow/status/schlegel/mcp-sync/ci.yml?style=flat-square&label=CI)](https://github.com/schlegel/mcp-sync/actions)
[![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-3FB950?style=flat-square)](https://opensource.org/licenses/MIT)
[![MCP](https://img.shields.io/badge/MCP-Model%20Context%20Protocol-BC8CFF?style=flat-square)](https://modelcontextprotocol.io)
[![Node](https://img.shields.io/badge/Node-%3E%3D20-339933?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org/)

</div>

---

## The Problem

MCP configs are a mess:

- Scattered across Claude Desktop, Cursor, and Claude Code
- Global configs pollute every project with irrelevant servers
- No version control -- team members set up MCP manually
- Absolute paths break across machines
- No way to check if your servers actually work

## The Solution

One `mcps.json` per project. Version controlled. Synced everywhere.

```bash
npx @schlegel/mcp-sync init
```

Or use a custom config filename:

```bash
npx @schlegel/mcp-sync --config .mcp-sync.json init
```

---

## Quickstart

```bash
# Initialize in your project (creates mcps.json)
npx @schlegel/mcp-sync init

# Start with a template (web, python, fullstack, devops, data, minimal)
npx @schlegel/mcp-sync use fullstack

# Or add servers manually
npx @schlegel/mcp-sync add-json filesystem '{"command":"npx","args":["-y","@modelcontextprotocol/server-filesystem","${workspaceFolder}"]}'

# See what you've got
npx @schlegel/mcp-sync list

# Sync to all your AI tools
npx @schlegel/mcp-sync sync

# Health check
npx @schlegel/mcp-sync doctor
```

### Using a Custom Config Filename

By default, mcp-sync uses `mcps.json`. You can specify a custom filename with the `--config` flag:

```bash
# Use .mcp-sync.json instead
npx @schlegel/mcp-sync --config .mcp-sync.json init
npx @schlegel/mcp-sync --config .mcp-sync.json add-json myserver '{"command":"echo"}'
npx @schlegel/mcp-sync --config .mcp-sync.json sync

# Or any other filename you prefer
npx @schlegel/mcp-sync --config my-servers.json init
```

The `--config` flag must come **before** the command name.

---

## CLI Preview

<div align="center">
<img src="assets/demo.svg" alt="mcp-sync CLI demo" width="680">
</div>

---

## How It Works

```
mcps.json (in your project root)
    |
    |--- mcp-sync sync --->  Claude Desktop config
    |--- mcp-sync sync --->  Cursor .cursor/mcp.json
    |--- mcp-sync sync --->  Claude Code .mcp.json
```

1. Define MCP servers in `mcps.json` (default) or use `--config` for a custom filename
2. Use workspace variables for portability (`${workspaceFolder}`, `${env:API_KEY}`)
3. Commit to git -- your whole team gets the same MCP setup
4. Run `mcp-sync sync` to push configs to all your AI tools
5. Run `mcp-sync doctor` to verify everything works

---

## Config Format

The config file (default: `mcps.json`) uses this format:

```json
{
  "$schema": "https://raw.githubusercontent.com/schlegel/mcp-sync/main/schema/mcp-sync.schema.json",
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "${workspaceFolder}"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
      }
    }
  },
  "sync": {
    "clients": ["claude-desktop", "cursor", "claude-code"]
  }
}
```

**Note:** You can name your config file anything you want using the `--config` flag. For backward compatibility with older projects, you might use `.mcp-sync.json`, or choose any name that fits your workflow.

### Workspace Variables

| Variable | Resolves To |
|----------|------------|
| `${workspaceFolder}` | Directory containing config file (e.g., `mcps.json`) |
| `${env:VAR_NAME}` | Environment variable value |
| `${home}` | User home directory |
| `${platform}` | `win32`, `darwin`, or `linux` |

Variables stay as templates in your config file and are resolved at sync time -- making configs portable across machines.

---

## Commands

### Global Options

| Option | Description |
|--------|-------------|
| `-c, --config <filename>` | Config filename (default: `mcps.json`) |
| `-V, --version` | Show version number |

### Command List

| Command | Description |
|---------|-------------|
| `mcp-sync init` | Create `mcps.json` in current project |
| `mcp-sync add <name>` | Add server interactively |
| `mcp-sync add-json <name> <json>` | Add server from JSON string |
| `mcp-sync remove <name>` | Remove a server |
| `mcp-sync list` | List all configured servers |
| `mcp-sync status` | Quick status overview |
| `mcp-sync sync` | Sync to Claude Desktop / Cursor / Claude Code |
| `mcp-sync sync --dry` | Preview sync without writing files |
| `mcp-sync doctor` | Health check all servers + system deps |
| `mcp-sync import` | Import from existing client configs |
| `mcp-sync use <template>` | Apply preset template |
| `mcp-sync env` | Audit environment variables referenced in config |
| `mcp-sync diff` | Show diff between config and client configs |
| `mcp-sync enable <name>` | Enable a disabled server |
| `mcp-sync disable <name>` | Disable a server without removing it |
| `mcp-sync export` | Export resolved config as JSON (pipe-friendly) |

---

## Templates

Get started fast with prebuilt server bundles:

```bash
npx @schlegel/mcp-sync use web        # filesystem + GitHub + Puppeteer
npx @schlegel/mcp-sync use python     # filesystem + GitHub + memory
npx @schlegel/mcp-sync use fullstack  # filesystem + GitHub + Postgres + Puppeteer + memory
npx @schlegel/mcp-sync use devops     # filesystem + GitHub + Docker
npx @schlegel/mcp-sync use data       # filesystem + Postgres + SQLite + memory
npx @schlegel/mcp-sync use minimal    # filesystem + memory
```

Templates merge into your existing config -- they never overwrite servers you already have.

---

## Comparison

| Feature | mcp-sync | MCPM.sh | mcptools | MetaMCP |
|---------|-------|---------|----------|---------|
| **Project-first config** | `mcps.json` per project (customizable) | Global profiles | Global aggregation | Docker proxy |
| **Multi-client sync** | Claude Desktop + Cursor + Claude Code | Partial | No | No |
| **Git-friendly** | Workspace variables | No | No | No |
| **Zero install** | `npx @schlegel/mcp-sync` | `pip install` | Go binary | Docker |
| **Health checks** | JSON-RPC ping | No | No | No |
| **Import existing** | From all clients | No | Scan only | No |
| **Templates** | 6 presets | No | No | No |

---

## Sync Targets

| Client | Config Path |
|--------|-------------|
| **Claude Desktop** | `%APPDATA%\Claude\claude_desktop_config.json` (Win) / `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) |
| **Cursor** | `.cursor/mcp.json` (project) |
| **Claude Code** | `.mcp.json` (project) |

mcp-sync **merges** your servers into existing configs -- it never deletes servers you added manually.

---

## Migration from .mcp-sync.json

If you have an existing project using `.mcp-sync.json`:

**Option 1: Continue using .mcp-sync.json**
```bash
# Always specify --config flag
npx @schlegel/mcp-sync --config .mcp-sync.json list
npx @schlegel/mcp-sync --config .mcp-sync.json sync
```

**Option 2: Rename to mcps.json**
```bash
# Simply rename the file
mv .mcp-sync.json mcps.json

# Then use without --config flag
npx @schlegel/mcp-sync list
npx @schlegel/mcp-sync sync
```

**Option 3: Use shell alias**
```bash
# Add to your .bashrc or .zshrc
alias mcp-sync='npx @schlegel/mcp-sync --config .mcp-sync.json'
```

---

## Requirements

- **Node.js** >= 20.0.0
- **npm** >= 8.0.0

---

## License

MIT

---

<div align="center">

**Built by [Aditya Gaurav](https://github.com/schlegel)**

</div>