@mokivan/mcpmatrix
v2.0.4
Published
Define MCP servers once and generate configs for Codex, Claude Code, and Gemini from a canonical MCP configuration
Maintainers
Readme
mcpmatrix
Define MCP servers once and generate client configs from a single canonical configuration.
This version supports:
- Codex CLI
- Claude Code CLI
- Gemini CLI
- config import from existing client files
- explicit config validation
doctordiagnostics- interactive TUI
- versioned backups with retention
Install
Global install from npm:
npm install -g @mokivan/mcpmatrixAvailable binaries:
mcpmatrixmmx
Minimum Node.js version:
20
Package contract:
- supported public interface:
mcpmatrix,mmx, and documented CLI flags - unsupported: programmatic imports from package internals or
dist/*
Quick Start
- Create the default config:
mcpmatrix init- Edit
~/.mcpmatrix/config.ymlwith your MCP servers and scopes:
servers:
github:
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: ${env:GITHUB_TOKEN}
medusa:
transport: remote
protocol: http
url: https://docs.medusajs.com/mcp
scopes:
global:
enable:
- github
tags:
ecommerce:
enable:
- medusa
repos:
"/Users/ivan/dev/store":
tags: ["ecommerce"]
enable: []- Validate, preview, and apply:
mcpmatrix validate
mcpmatrix doctor
mcpmatrix schema
mcpmatrix plan
mcpmatrix apply
mcpmatrix backups list
mcpmatrix rollback --client codexOptional interactive workflow:
mcpmatrix tuiImport Existing Configs
Import MCP servers from the supported client files into ~/.mcpmatrix/config.yml:
mcpmatrix importDetected sources:
- Codex:
~/.codex/config.toml - Claude Code:
~/.claude.json - Gemini:
~/.gemini/settings.json
Import rules:
- import fails if
~/.mcpmatrix/config.ymlalready exists - imported servers become
servers - imported server names are enabled in
scopes.global.enable - Codex imports
commandastransport: stdioandurlastransport: remote - Claude imports stdio, remote HTTP, and remote SSE entries
- Gemini imports stdio and remote HTTP entries using
httpUrl - conflicting canonical definitions for the same server name cause import to fail
Commands
mcpmatrix init
Creates the initial config file at ~/.mcpmatrix/config.yml.
mcpmatrix import
Imports existing MCP client configs into the canonical YAML file.
mcpmatrix schema
Prints the packaged JSON Schema path and file:// URI for ~/.mcpmatrix/config.yml.
This is useful when your editor does not automatically pick up the schema header or when you want to configure schema association manually.
mcpmatrix validate
Validates:
- YAML syntax
- env reference syntax
- scope references to defined servers
- stdio commands available in PATH or by executable path
- remote MCP URLs and auth structure
mcpmatrix doctor [--repo <path>]
Runs a fuller diagnostic pass:
- MCP commands resolve locally
- remote MCP URLs are structurally valid
- referenced environment variables are defined
- configured repo paths are accessible
- the detected repo can be resolved and inspected
- stack files suggest tags without modifying config automatically
- compatibility is reported for Codex, Claude, and Gemini
Suggested stack tags:
package.json->nodepom.xml->java.csproj->dotnet
mcpmatrix plan [--repo <path>]
Resolves the active server set for the current repository and shows:
- detected repo path
- active tags
- active servers
- global vs repo-scoped server partitions
- transport and per-client compatibility
- files that would be updated
- estimated diff size
Repository detection order:
--repo <path>- search upward for
.git - current working directory
mcpmatrix apply [--repo <path>]
Resolves the same server set and writes client configs.
Client outputs:
- Codex global:
~/.codex/config.toml - Codex repo-scoped:
<repo>/.codex/config.toml - Claude Code global:
~/.claude.json - Claude Code repo-scoped:
<repo>/.mcp.json - Gemini global:
~/.gemini/settings.json - Gemini repo-scoped:
<repo>/.gemini/settings.json
Write behavior:
- global scope writes only servers resolved from
scopes.global.enable - repo scope writes only servers resolved from the matched repo's
tagsandenable, excluding names already active globally - Codex updates only a managed
mcpmatrixblock inside eachconfig.toml, using named TOML tables undermcp_servers - Claude updates only the
mcpServerssection inside.claude.jsonand.mcp.json - Gemini updates only the
mcpServerssection insidesettings.json - stdio and supported remote transports are rendered per client format
applyfails before writing if any active server cannot be represented by Codex, Claude, or Gemini- existing content outside those managed areas is preserved
- existing files are backed up before overwrite
applyis transactional across all selected targets: either all global and repo-scoped files are updated or the previous state is restored
Backup files:
- stored in
~/.mcpmatrix/backups/ - filenames are versioned by client and scope, for example
codex-global-YYYY-MM-DD-HH-MM.toml - each backup stores metadata for the exact live target path
- latest 3 backups are retained per exact target file
Rollback behavior:
- if any target write fails,
mcpmatrix applyexits non-zero - mcpmatrix restores all selected client files to their pre-apply state
- a failed apply should never leave a mixed client state behind
Compatibility note:
- mcpmatrix tolerates UTF-8 BOM-prefixed YAML, TOML, and JSON config files when loading canonical config or importing/updating client configs
mcpmatrix backups list [--client <codex|claude|gemini>] [--repo <path>]
Lists versioned backups stored in ~/.mcpmatrix/backups/.
Output includes:
- client group
- scope
- backup file name
- inferred timestamp
- live target path
- full backup path
If no backups exist, the command prints an empty-state message and exits successfully.
mcpmatrix rollback [--client <codex|claude|gemini>] [--backup <name-or-path>] [--repo <path>]
Restores versioned backups into the live client config files.
Behavior:
- without flags, restores the latest global backup for Codex, Claude, and Gemini
- with
--client, restores only the latest backup for that client in the selected scope - with
--repo, restores the latest repo-scoped backups for that repository - with
--backup, restores a specific backup file by base name from~/.mcpmatrix/backups/or by absolute path - when
--backupand--clientare both provided, the backup must belong to that client - when
--backupand--repoare both provided, the backup must belong to that repo and be repo-scoped
Failure rules:
- global rollback is strict: if any required client backup is missing, nothing is restored
- repo rollback is strict: if any required repo-scoped client backup is missing, nothing is restored
- single-client rollback fails when no backup exists for that client
- an invalid or mismatched backup argument exits non-zero
- rollback does not create a new backup entry for the restored files
mcpmatrix tui [--repo <path>]
Opens an interactive terminal UI for the detected repo. The TUI can:
- visualize active MCP servers
- inspect repo status and
doctoroutput - open
~/.mcpmatrix/config.ymlin$EDITOR - enable or disable repo-local MCPs in
scopes.repos.<repo>.enable
Keyboard shortcuts:
↑/↓move the selectionEnterorSpacetoggles the selected repo-local MCP/filters the server list by namedopens the structureddoctorreporteopens the canonical config in$EDITORand reloads on exitrrefreshes repo detection and resolved server stateqorEscexits the current view or closes the TUI
Current limitation from the canonical schema:
- inherited servers from
globalortagsare visible in the TUI but cannot be disabled there, because scope merging is additive only
Configuration
Global config location:
~/.mcpmatrix/config.ymlAutocomplete support:
mcpmatrix initwrites ayaml-language-serverschema header into the generated config filemcpmatrix schemaprints the packaged schema path and URI for manual editor setup- packaged schema file:
schemas/mcpmatrix-config.schema.json
Public schema:
servers:
<server-name>:
transport: stdio
command: string
args: string[]
env:
<ENV_NAME>: string
<server-name>:
transport: remote
protocol: auto | http | sse
url: string
headers:
<HEADER_NAME>: string
auth:
type: none | bearer | oauth
scopes:
global:
enable: string[]
tags:
<tag-name>:
enable: string[]
repos:
<absolute-path>:
tags: string[]
enable: string[]Rules:
- server names must be unique
stdioservers usecommand,args, andenvremoteservers useprotocol,url,headers, andauth- scopes are additive
- resolution order is
global -> tags -> repo - duplicate server names are removed while preserving first appearance
- env references must use
${env:VAR_NAME}when interpolation syntax is used - interpolation may appear in any string field
- repo matching uses normalized absolute paths across Windows, Linux, and macOS
Development
Install dependencies:
npm installBuild:
npm run buildRun checks:
npm run lint
npm run typecheck
npm test
npm run test:docs
npm run test:release
npm run test:smoke
npm run pack:checkRelease
The public scoped package @mokivan/mcpmatrix is published from GitHub Actions, either after merges to master or from a manual run of the Release workflow. The workflow is guarded by version and registry checks. Release workflow details live in docs/releasing.md.
Compatibility
- supported runtime: Node.js
20+ - supported clients: Codex CLI, Claude Code CLI, Gemini CLI
- semver applies to the documented CLI only
- importing package internals is outside the support contract and may break without notice
Troubleshooting
validatefailing on a command usually means the executable is not available in localPATHor is not an executable file pathvalidatefailing on a remote server usually means theurl,protocol, orauthblock is malformeddoctorfails when a referenced env var is missing or a configured repo path no longer existsdoctoralso reports active servers that cannot be applied to Codex, Claude, or Geminiimportfails when~/.mcpmatrix/config.ymlalready exists or when the same server name has conflicting canonical definitions across clientsapplyfailures should restore the previous client state; inspect the reported target path and backup files if the error persists- if a client config contains a UTF-8 BOM on Windows, mcpmatrix should still parse it correctly; if it does not, treat that as a bug
- use
mcpmatrix backups listto inspect available restore points before runningmcpmatrix rollback
Documentation Guard
When a roadmap phase is implemented or the supported client matrix changes, update this README in the same change.
Minimum README updates for that case:
- supported clients
- user-facing commands or setup changes
- release and install instructions if package metadata changes
- keep
docs/specs/spec-cli.mdaligned with the public CLI surface - keep
npm run test:docspassing - when
package.json.versionchanges, add the matchingCHANGELOG.mdsection and keepnpm run test:releasepassing
Source of Truth
Implementation follows this order:
- roadmap documents in
docs/ - canonical specifications in
docs/specs/ - code in
src/
Canonical specs are the files prefixed with spec-.
