Funzionalità

Server MCP condivisi

Ultimo aggiornamento: 19 ottobre 2026
Verificato con ccam 0.6.0 e Claude Code 2.1.302

Questa pagina è stata tradotta automaticamente dall'inglese. Le correzioni sono benvenute. Modifica questa pagina su GitHub

In questa pagina

Claude Code salva i server MCP utente in .claude.json, lo stesso file che contiene il login dell'account, quindi quel file non può essere condiviso tra account. ccam tiene i server condivisi in un file del gruppo, mcp.json, e lo passa all'avvio a ogni account del gruppo. Usa ccam mcp per aggiungere un server una sola volta per tutti i tuoi account, e ccam mcp import per portare agli altri un server che hai aggiunto all'interno di una sessione.

Utilizzo

ccam mcp add fs -- npx -y @modelcontextprotocol/server-filesystem ~/code   # a local (stdio) server
ccam mcp add ctx --url https://mcp.context7.com/mcp --header 'Authorization: Bearer …'
ccam mcp add docs --url https://example.com/sse --transport sse
ccam mcp add db -e PGHOST=localhost -- pg-mcp                    # with an environment variable
ccam mcp add-json gh '{"type":"http","url":"https://api.githubcopilot.com/mcp/"}'
ccam mcp add tools -g team -- tools-mcp                           # into the group team
ccam mcp list                                                     # every group, and servers only one account has
ccam mcp remove ctx
ccam mcp import work                                              # move work's own servers into its group
ccam mcp import work gh --force                                   # replace the group's different gh

Una modifica vale dal successivo avvio di ogni account; le sessioni in esecuzione mantengono i server con cui sono partite:

$ ccam mcp add fs -- npx -y @modelcontextprotocol/server-filesystem ~/code
✓ fs added in group default — applies from the next launch
$ ccam mcp list
group default (work, side)
  ctx                  http https://mcp.context7.com/mcp
  fs                   stdio npx -y @modelcontextprotocol/server-filesystem /home/me/code
only in account work: pg

Aggiungere un nome che il gruppo ha già ne sostituisce la definizione e stampa updated invece di added. I server arrivano a un account solo se condivide gli MCP con quel gruppo (ccam share <name> --mcp on); quando nessun account condivide ancora gli MCP, add lo segnala.

Opzioni

Opzione Cosa fa Predefinito
-g, --group <group> gruppo di destinazione per add, add-json e remove l'unico gruppo tramite cui qualche account condivide gli MCP, altrimenti default
-- <command> [args…] (add) esegue questo comando come server stdio
--url <url> (add) URL del server remoto (http/sse)
--transport <stdio|http|sse> (add) trasporto di un server --url http
--header <'Name: value'> (add) intestazione HTTP, ripetibile nessuna
-e, --env <KEY=VALUE> (add) variabile d'ambiente per un server stdio, ripetibile nessuna
--force (import) sostituisce un server del gruppo con lo stesso nome ma diverso; del vecchio mcp.json viene fatto un backup disattivata
--keep-local (import) mantiene le voci nel .claude.json dell'account disattivata
-h, --help aiuto per ogni comando
--dry-run (globale) rispettata solo da mcp list; add, add-json, remove e import la rifiutano e non modificano nulla disattivata

add richiede un comando dopo -- oppure --url; altrimenti fallisce con a command to run (after --) or --url is required. --header vale per i server --url e --env per i server a comando. add-json accetta lo stesso JSON di claude mcp add-json, e la definizione deve essere un oggetto con un command o un url. import usa sempre il gruppo tramite cui l'account condivide gli MCP, e list mostra tutti i gruppi, quindi -g non li modifica.

Come funziona

I file coinvolti:

  • ~/.local/share/ccam/groups/<group>/mcp.json: i server condivisi, {"mcpServers": {…}}, il formato letto da --mcp-config. Viene scritto con fsutil.AtomicWrite e modalità 0600, perché le voci dei server contengono spesso chiavi API.
  • ~/.local/share/ccam/profiles/<name>/.claude.json: il file di Claude Code con i server dell'account. ccam legge solo il suo valore mcpServers con lo scanner profile.TopLevelValue e sul percorso di avvio non analizza mai l'intero file.
  • ~/.local/state/ccam/mcp/<name>/: il file seen, il sync-stamp e i backup di .claude.json.

Ci sono due strategie, impostate da mcp_strategy in ~/.config/ccam/config.toml. Quella predefinita è la strategia flag:

  1. launcher.applyMCP trova il gruppo MCP dell'account. mcp.FlagArgs verifica con un solo stat che il mcp.json del gruppo esista, senza analizzarlo.
  2. Plan.InsertArgs mette --mcp-config=<path> subito dopo claude, prima dei tuoi argomenti, così le tue opzioni --mcp-config o --strict-mcp-config continuano a valere in aggiunta.
  3. mcp.NewLocal controlla se il .claude.json dell'account è cambiato dall'ultimo avvio, e solo in quel caso ne analizza i server.
  4. syscall.Exec sostituisce ccam con Claude Code.

Il percorso viene passato come un solo argomento, --mcp-config=<path>, non come due. L'opzione --mcp-config di Claude Code accetta più valori, quindi claude --mcp-config a.json "prompt" leggerebbe il prompt come secondo file di configurazione e fallirebbe con MCP config file not found. La forma con un solo argomento si ferma lì, e un prompt o un sottocomando come mcp list che segue funziona. Claude Code carica i server di --mcp-config in aggiunta a quelli dell'account; in caso di nomi uguali prevale la voce in .claude.json. La strategia flag non scrive mai .claude.json.

Un server aggiunto all'interno di una sessione con claude mcp add finisce solo nel .claude.json di quell'account. In quel momento ccam non può vederlo, perché Claude Code lo ha sostituito, quindi controlla all'avvio successivo. Il file seen contiene l'ora di modifica di .claude.json e i nomi dei server già segnalati. Quando l'ora è diversa, ccam confronta i nomi con il gruppo e stampa una sola volta un suggerimento per ogni nuovo server, senza attendere input:

ccam: MCP servers only account work has: pg
      To share them with other accounts: ccam mcp import work pg

Con mcp_strategy = "sync", i server compaiono in claude mcp list e /mcp come normali server utente, e ccam li scrive nel .claude.json di ogni account prima dell'avvio:

  1. mcp.Sync confronta l'ora di modifica del mcp.json del gruppo con sync-stamp. Se non è cambiata, il .claude.json dell'account non viene aperto.
  2. Prende il lock di Claude Code stesso, la cartella .claude.json.lock accanto al file, creata con mkdir. Attende fino a 2 secondi e considera scaduto un lock più vecchio di 10 secondi, come fa la libreria di lock di Claude Code.
  3. Salva il .claude.json attuale in backups/ nella cartella di stato e conserva i 5 più recenti.
  4. Imposta ogni server del gruppo in mcpServers, rimuove i server che aveva scritto in precedenza e che il gruppo non ha più, mantiene i server propri dell'account e scrive il file in modo atomico con la sua modalità originale.
  5. Registra il nuovo stamp e i nomi che gestisce, e Claude Code si avvia senza --mcp-config.

La sincronizzazione viene saltata, con ccam: account work is already running, skipping MCP sync, quando è in esecuzione una sessione dell'account, perché Claude Code riscrive .claude.json mentre è in esecuzione. Una sincronizzazione fallita stampa ccam: MCP sync failed (launching anyway): … e avvia comunque. Il suggerimento sui server aggiunti all'interno di una sessione riguarda solo la strategia flag.

ccam mcp import sposta i server propri di un account nel suo gruppo:

ccam legge i server dell'account con mcp.LocalServers e confronta ciascuno con il server del gruppo con lo stesso nome usando mcp.SameDef, che ignora l'ordine delle chiavi e gli spazi. Un server che il gruppo non ha, o che ha con la stessa definizione, viene copiato. Uno diverso viene saltato, perché la definizione del gruppo è quella usata da tutti gli altri account:

Skipped gh: group default already has a different gh (`ccam mcp import work gh --force` replaces it)
✓ Copied to group default: pg
✓ Removed account work's own entries (.claude.json backed up)

Con --force il server del gruppo viene sostituito, e il mcp.json precedente viene prima salvato in .ccam-backup/<time>/mcp.json dentro la cartella del gruppo. Poi mcp.RemoveLocal rimuove le voci copiate dal .claude.json dell'account, con lo stesso lock e dopo un backup nella cartella di stato. Serve perché, in caso di nomi uguali, la voce dell'account prevarrebbe su quella del gruppo. --keep-local le lascia dove sono.

Sicurezza e casi limite

  • Accessi. I server che accedono con OAuth conservano i loro token nel .credentials.json di ogni account (mcpOAuth), non nell'elenco dei server, quindi condividere un server non ne condivide l'accesso. Accedi una volta per account con /mcp, oppure copia gli accessi da ~/.claude con ccam migrate. Il gruppo non riceve mai un file di login.
  • Account in esecuzione. import copia nel gruppo ma lascia le voci proprie di un account in esecuzione e lo segnala; eseguilo di nuovo dopo la fine della sessione. La sincronizzazione salta gli account in esecuzione.
  • File danneggiati. Se .claude.json non è un JSON valido, la sincronizzazione non lo tocca e segnala l'errore. Se non riesce a prendere il lock entro 2 secondi, ccam segnala could not lock … (Claude Code is writing the file).
  • Account che non condividono gli MCP. import si rifiuta e ti dice di eseguire prima ccam share side --mcp on.
  • Nomi dei gruppi. -g accetta solo un nome di gruppo; diventa una cartella sotto groups/, quindi nomi come ../x vengono rifiutati.