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

Answer the quiz and check your score.

Sources

What This Course Was Derived From

  • pyproject.toml
  • src/mcpup/main.py
  • src/mcpup/config/models.py
  • src/mcpup/config/store.py
  • src/mcpup/cli/*.py
  • src/mcpup/clients/*.py
  • tests/config/*.py
  • tests/cli/*.py
  • tests/clients/*.py
  • Local command check: uv run mp --help
  • Local test run: uv run pytest -q