LLAMA Hot Swap

Servidor MCP para troca a quente de modelos llama.cpp no Claude Code - launchctl (macOS) + systemd (Linux)

Documentação

mcp-llama-swap

PyPI version License Python 3.10+

Troque modelos llama.cpp dentro de uma sessão ativa do Claude Code. Sem perda de contexto. Um único comando.

Planeje com um modelo de raciocínio. Implemente com um modelo de codificação. Mesma sessão, mesmo contexto, zero trabalho manual.

Suporta macOS (launchctl) e Linux (systemd).

Por quê

Executar LLMs locais significa escolher entre um modelo de raciocínio forte e um modelo de codificação rápido. Você não pode carregar ambos em uma única máquina. Trocar modelos manualmente destrói o contexto e o fluxo da sua conversa.

O mcp-llama-swap resolve isso dando ao Claude Code uma ferramenta para trocar o modelo por trás do llama-server via gerenciador de serviços do seu sistema (launchctl no macOS, systemd no Linux), preservando todo o histórico da conversa no lado do cliente.

Início Rápido

Instalação

# Option A: Run directly with uvx (no install needed)
uvx mcp-llama-swap

# Option B: Install from PyPI
pip install mcp-llama-swap

Configure o Claude Code

Adicione em ~/.claude.json:

{
  "mcpServers": {
    "llama-swap": {
      "command": "uvx",
      "args": ["mcp-llama-swap"],
      "env": {
        "LLAMA_SWAP_CONFIG": "/path/to/config.json"
      }
    }
  }
}

Configure os Modelos

Crie config.json (macOS):

{
  "plists_dir": "~/.llama-plists",
  "health_url": "http://localhost:8000/health",
  "health_timeout": 30,
  "models": {
    "planner": "qwen35-thinking.plist",
    "coder": "qwen3-coder.plist",
    "fast": "glm-flash.plist"
  }
}

Ou no Linux:

{
  "services_dir": "~/.llama-services",
  "health_url": "http://localhost:8000/health",
  "health_timeout": 30,
  "models": {
    "planner": "llama-server-planner.service",
    "coder": "llama-server-coder.service"
  }
}

Uso

Dentro do Claude Code:

You: list models
You: swap to planner
You: <discuss architecture, define interfaces>
You: swap to coder and implement the plan

É isso. O contexto é preservado entre as trocas.

Você também pode gerar novas configurações de modelo diretamente:

You: create a model config named "reasoning" for /models/qwen3-30b.gguf with 8192 context

Como Funciona

Claude Code CLI
    |
    | Anthropic Messages API
    v
LiteLLM Proxy (:4000)         <-- translates Anthropic -> OpenAI format
    |
    | OpenAI Chat Completions API
    v
llama-server (:8000)          <-- model weights swapped via service manager
    ^
    |
mcp-llama-swap                <-- this project (launchctl or systemd)

O Claude Code fala o formato Anthropic. O LiteLLM traduz para o formato OpenAI para o llama-server. Este servidor MCP gerencia qual serviço de modelo está carregado via launchctl (macOS) ou systemd (Linux).

O contexto da conversa sobrevive às trocas porque o Claude Code mantém todo o histórico de mensagens no lado do cliente e o reenvia a cada requisição.

Configuração de Modelos

Modo Mapeado (recomendado)

Defina aliases para seus modelos. Apenas modelos mapeados ficam disponíveis. Outras configurações de serviço no diretório são ignoradas.

macOS:

{
  "plists_dir": "~/.llama-plists",
  "health_url": "http://localhost:8000/health",
  "health_timeout": 30,
  "models": {
    "planner": "qwen35-35b-a3b-thinking.plist",
    "coder": "qwen3-coder.plist",
    "fast": "glm-4-7-flash.plist"
  }
}

Linux:

{
  "services_dir": "~/.llama-services",
  "health_url": "http://localhost:8000/health",
  "health_timeout": 30,
  "models": {
    "planner": "llama-server-planner.service",
    "coder": "llama-server-coder.service"
  }
}

Troque usando seus aliases: "swap to coder", "swap to planner".

Modo Diretório

Defina "models": {} para descobrir automaticamente todas as configurações de serviço. Os nomes de arquivo (sem extensão) se tornam os aliases.

macOS:

{
  "plists_dir": "~/.llama-plists",
  "models": {}
}

Linux:

{
  "services_dir": "~/.llama-services",
  "models": {}
}

Ferramentas MCP

FerramentaDescrição
list_modelsLista todos os modelos configurados com status de carregamento e modo atual
get_current_modelRetorna o alias do modelo atualmente carregado
swap_modelDescarrega o modelo atual, carrega o especificado e aguarda a verificação de saúde
create_model_configGera um novo launchd plist (macOS) ou systemd unit (Linux) para um modelo

Recursos MCP

RecursoDescrição
llama-swap://configConfiguração atual como JSON
llama-swap://statusStatus atual do modelo, saúde e informações da plataforma

Prompts MCP

PromptDescrição
swap-workflowModelo de fluxo de trabalho guiado de planejar-depois-implementar

Guia Completo de Configuração

Pré-requisitos

  • macOS com launchctl, ou Linux com systemd
  • llama-server (llama.cpp) instalado
  • Configurações de modelo como arquivos de serviço (launchd plists ou systemd units)
  • Python 3.10+
  • CLI do Claude Code apontando para um proxy LiteLLM

1. Instale o mcp-llama-swap

pip install mcp-llama-swap

2. Instale e inicie o proxy LiteLLM

pip install litellm

Crie litellm_config.yaml:

model_list:
  - model_name: "*"
    litellm_params:
      model: "openai/*"
      api_base: "http://localhost:8000/v1"
      api_key: "sk-none"

litellm_settings:
  drop_params: true
  request_timeout: 300

Inicie-o:

litellm --config litellm_config.yaml --port 4000

No macOS, você pode usar o ai.litellm.proxy.plist.template incluído para executá-lo como um serviço launchd persistente (veja setup.sh).

3. Aponte o Claude Code para o LiteLLM

Adicione em ~/.zshrc (macOS) ou ~/.bashrc (Linux):

export ANTHROPIC_BASE_URL="http://localhost:4000"
export ANTHROPIC_API_KEY="sk-none"
export ANTHROPIC_MODEL="local"

4. Adicione o servidor MCP ao Claude Code

Adicione em ~/.claude.json:

{
  "mcpServers": {
    "llama-swap": {
      "command": "uvx",
      "args": ["mcp-llama-swap"],
      "env": {
        "LLAMA_SWAP_CONFIG": "/absolute/path/to/config.json"
      }
    }
  }
}

5. Crie seu config.json

Copie config.example.json (macOS) ou config.example.linux.json (Linux) e edite com seus aliases de modelo e nomes de arquivo de serviço.

6. Crie configurações de serviço de modelo

Você pode criar configurações de serviço manualmente ou usar a ferramenta MCP create_model_config dentro do Claude Code:

You: create a model config named "coder" for /path/to/model.gguf with 8192 context

Isso gera o launchd plist (macOS) ou systemd unit file (Linux) apropriado no seu diretório de serviços.

Configuração Automatizada (macOS)

Se você preferir uma configuração única no macOS, clone este repositório e execute:

git clone https://github.com/oussama-kh/mcp-llama-swap.git ~/mcp-llama-swap
cd ~/mcp-llama-swap
chmod +x setup.sh
./setup.sh

O script cria um ambiente virtual, instala dependências, configura o serviço launchd do LiteLLM e imprime a configuração exata a ser adicionada.

Referência de Configuração

Campos de config.json:

CampoPadrãoDescrição
services_dir~/.llama-plists (macOS) / ~/.llama-services (Linux)Diretório contendo configurações de serviço de modelo
plists_dir—Alias do macOS para services_dir (compatível com versões anteriores)
units_dir—Alias do Linux para services_dir
health_urlhttp://localhost:8000/healthEndpoint de saúde do llama-server
health_timeout30Segundos para aguardar a verificação de saúde após o carregamento
models{}Mapa de alias para nome de arquivo. Vazio = modo diretório
platformautoGerenciador de serviços: auto, launchctl ou systemd
launchctl_modelegacySomente macOS: legacy (load/unload) ou modern (bootstrap/bootout)

Substitua o caminho da configuração via a variável de ambiente LLAMA_SWAP_CONFIG.

Detalhes da Plataforma

macOS (launchctl)

Os modelos são gerenciados como serviços launchd via arquivos plist. Dois modos de launchctl estão disponíveis:

  • Legacy (padrão): Usa launchctl load/unload/list. Funciona em todas as versões do macOS.
  • Modern: Usa launchctl bootstrap/bootout/print. A API oficialmente suportada em macOS mais recentes. Ative com "launchctl_mode": "modern" na configuração.

Linux (systemd)

Os modelos são gerenciados como serviços de usuário do systemd. Arquivos unit em services_dir são vinculados simbolicamente a ~/.config/systemd/user/ e gerenciados via systemctl --user start/stop.

Solução de Problemas

LiteLLM não está traduzindo corretamente: Verifique /tmp/litellm.stderr.log. Confirme se o llama-server está em execução: curl http://localhost:8000/health.

A troca de modelo expira: Aumente health_timeout em config.json. Modelos grandes podem precisar de 30+ segundos para carregar os pesos na memória.

O Claude Code não encontra o servidor MCP: Verifique se o caminho LLAMA_SWAP_CONFIG é absoluto. Teste diretamente: python -m mcp_llama_swap.

Modelo mapeado não encontrado: O nome do arquivo de serviço em models deve corresponder a um arquivo real no seu diretório de serviços.

O serviço systemd não inicia: Verifique journalctl --user -u llama-server-<name> para erros. Garanta que llama-server esteja no seu PATH.

Problemas com o modo moderno do launchctl: Se os comandos bootstrap/bootout falharem, volte para "launchctl_mode": "legacy" na configuração.

Desenvolvimento

# Install with test dependencies
pip install -e ".[test]"

# Run tests
pytest -v

Caso de Uso

Este projeto permite um fluxo de trabalho de codificação com IA em duas fases, inteiramente em hardware local:

  1. Fase de planejamento: Carregue um modelo de raciocínio (ex.: Qwen3.5-35B-A3B com thinking). Discuta a arquitetura, defina interfaces, decomponha requisitos.
  2. Fase de implementação: Troque para um modelo de codificação (ex.: Qwen3-Coder-30B). Execute o plano arquivo por arquivo com todo o contexto da conversa da fase de planejamento.

Sem APIs na nuvem. Sem dados saindo da sua máquina. Sem perda de contexto entre as fases.

Licença

Apache-2.0