Lesson 1
Overview
What problem MCPUP solves
MCPUP gives you one central place to define MCP servers and then decide which clients should receive them. It stops you from manually editing multiple client config files by hand.
One tool -> one central config -> many client config files
Real current snapshot
- Version in repo:
0.1.0 - Commands:
add remove list enable disable sync - Implemented adapter keys: 4
- Test status checked locally: 52 passing
Most important mental rule:
MCPUP has two layers of truth:
Layer 1: MCPUP central config Layer 2: client-native config files Commands change layer 1 first. Only sync pushes into layer 2.
Lesson 2
Mental Model
Whole-system flow
mp add -> save server definition to ~/.mcpup/config.json mp enable / mp disable -> set per-client enabled flags in ~/.mcpup/config.json mp list -> read central config and print a table mp sync -> read central config -> choose adapters -> write client config files
Server type explorer
Lesson 3
Config Structure
The central config shape
{
"version": 1,
"servers": { ... },
"clients": { ... }
}
`servers` stores the actual server definitions. `clients` stores enabled or disabled state per client.
Config explorer
Validation rule that matters
A server must have: command OR url not both not neither
This rule is enforced by the Pydantic `Server` model, so bad server definitions are rejected early.
Lesson 4
Command Lifecycle
Select a command
`add`
Creates or rejects server definitions. It does not touch any client file.
`enable` and `disable`
These only change the enabled flag per client in MCPUP's own config.
`sync`
This is the only command that writes outside
~/.mcpup/.
Lesson 5
Sync Pipeline
Generic adapter flow
sync() -> detect() -> read() -> build() -> write()
Every client adapter follows the same contract from
clients/base.py. That is the main abstraction
that keeps MCPUP consistent across clients.
Walk the sync steps
Lesson 6
Client Adapters
Choose a client
Honest current-state note:
Plan says 5 supported clients. Current registry keys in code: 4 claude-code claude-desktop cursor codex
There is no separate `codex-desktop` adapter key in the current code. The single `codex` adapter handles the Codex config file.
Lesson 7
Current Reality
What is already solid
- Data validation for server definitions
- Atomic writes for MCPUP config and adapters
- Consistent adapter contract
- Config tests, CLI tests, adapter tests
- Dry-run support in `sync`
Important caveats
- `enable --client something` can create arbitrary client names, but `sync` only knows registry-backed adapters
- If no clients exist in config, `enable` and `disable` with no `--client` just warn and stop
- CLI `sync` tests are lighter than adapter unit tests
Best mental summary
MCPUP v0.1 is: centralized config management + per-client enable flags + adapter-based file writing It is not yet: auto-discovery + auto-sync + universal client abstraction
Lesson 8
Practice + Quiz
Think through these scenarios
1. You run `mp add github ...`. Which file changes?
2. You run `mp enable github --client cursor`. Does Cursor get updated immediately?
3. What command is the boundary between planning state and real client-file writes?
Quick quiz
Sources
What This Course Was Derived From
pyproject.tomlsrc/mcpup/main.pysrc/mcpup/config/models.pysrc/mcpup/config/store.pysrc/mcpup/cli/*.pysrc/mcpup/clients/*.py
tests/config/*.pytests/cli/*.pytests/clients/*.py- Local command check:
uv run mp --help - Local test run:
uv run pytest -q