Claw2Immich

claw2immich é um servidor Python MCP (Model Context Protocol) que expõe o aplicativo de fotos Immich selecionado,

Documentação

claw2immich

Docker GitHub Workflow Status

claw2immich é um servidor MCP (Model Context Protocol) em Python que expõe endpoints selecionados da API REST do Immich. Ele usa a especificação OpenAPI do Immich para metadados da API e disponibiliza um conjunto pequeno de ferramentas cientes de permissões para verificações comuns somente de leitura.

Status

  • O servidor MCP principal e a filtragem de capacidades estão implementados.
  • A exposição de ferramentas é controlada pelas permissões da API do Immich.
  • Os testes de integração cobrem a listagem de ferramentas e sondagens de permissões.

Ferramentas disponíveis

  • ping_server
  • get_server_version
  • tool_access_report
  • write_capability_report
  • get_current_user (somente quando permitido pela chave/token da API)
  • downloadAsset (somente quando a chave/token da API está configurada; retorna payloads base64 seguros para transporte e suporta modo de entrega immich_link opcional)

Todos os endpoints OpenAPI são expostos como ferramentas nomeadas immich_<operation> ou immich_<method>_<path>. As ferramentas são filtradas com base na presença de autenticação, marcadores somente de administrador e sondagens de capacidade de escrita (padrão POST /api/assets).

As descrições das ferramentas OpenAPI incluem:

  • params: resumo dos campos obrigatórios de caminho/consulta/corpo
  • example: esboço curto de chamada para entradas obrigatórias
  • returns: título do esquema de resposta e campos principais quando disponíveis

As respostas das ferramentas OpenAPI para ativos, álbuns, pessoas e locais incluem um campo web_url com um link direto para o item na interface web do Immich (quando IMMICH_EXTERNAL_DOMAIN está configurado ou descoberto nas configurações do servidor).

Os parâmetros das ferramentas OpenAPI usam campos explícitos com prefixo para que os clientes MCP possam descobrir o que definir:

  • path_<name> para parâmetros de caminho
  • query_<name> para parâmetros de consulta
  • header_<name> para parâmetros de cabeçalho
  • cookie_<name> para parâmetros de cookie
  • body para corpos de solicitação JSON

Os campos legados path_params, query_params, headers e json_body ainda são aceitos para compatibilidade.

downloadAsset é destinado a clientes que não podem acessar a chave da API do Immich diretamente. O modo de entrega padrão é shared_link: o servidor retorna um link tokenizado de curta duração (30 minutos) sem dados de payload inline quando suportado pela API de links compartilhados do Immich. Para segurança JSON do MCP, a entrega de payload inline (inline_base64) permanece codificada em base64. O modo de compatibilidade opcional immich_link retorna uma URL autenticada direta do Immich.

Superfícies de documentação MCP

  • As instruções do servidor são enviadas durante a inicialização. Use-as como um guia rápido e aponte para o recurso do guia de uso.
  • As instruções de inicialização agora destacam a descoberta de externalDomain, grupos de fluxo de trabalho, orientações de o que fazer/não fazer e uma string de instrução de exemplo.
  • Recurso: docs://usage-guide contém um guia de fluxo de trabalho detalhado com exemplos.
  • Prompts: modelos de fluxo de trabalho estão disponíveis sob títulos como "Immich: Get image", "Immich: Find person" e "Immich: Share album".

Configuração

Variáveis de ambiente:

  • IMMICH_BASE_URL (padrão http://localhost:2283)
  • IMMICH_API_KEY
  • IMMICH_API_TOKEN
  • IMMICH_EXTERNAL_DOMAIN (opcional: domínio para links da interface web como https://immich.example.com; se não definido, descoberto de /api/server-config)
  • IMMICH_PROFILE (opcional: read_only, read_write ou full_scope)
  • IMMICH_WRITE_PROBE_PATH (padrão /api/assets)
  • IMMICH_WRITE_PROBE_METHOD (padrão POST)
  • IMMICH_DOWNLOAD_ASSET_DELIVERY (opcional: shared_link (padrão), inline_base64 ou immich_link)

Variáveis de ambiente do servidor MCP:

  • MCP_TRANSPORT (stdio, sse ou streamable-http; padrão stdio)
  • MCP_HOST (padrão 127.0.0.1)
  • MCP_PORT (padrão 8000)
  • MCP_MOUNT_PATH (caminho de montagem opcional para transporte SSE)
  • MCP_LOG_LEVEL (padrão INFO)

Fonte da especificação OpenAPI: Especificação com versão correspondente (após /api/health e /api/server/version): https://raw.githubusercontent.com/immich-app/immich/v{VERSION}/open-api/immich-openapi-specs.json

Perfis de Acesso

Os perfis de acesso fornecem níveis de permissão predefinidos para simplificar o gerenciamento de chaves de API e reduzir o risco de configuração incorreta. Defina IMMICH_PROFILE para um dos seguintes valores:

read_only

Caso de uso: Navegação segura, pesquisa e relatórios sem risco de modificação.

Permissões necessárias:

  • asset.read - Visualizar fotos e vídeos
  • album.read - Visualizar álbuns
  • library.read - Navegar em bibliotecas
  • timeline.read - Acessar linha do tempo e memórias

Ferramentas típicas expostas:

  • immich_getAllAssets, immich_getAssetById, immich_searchAssets
  • immich_getAllAlbums, immich_getAlbumInfo
  • immich_getMyUserInfo, immich_getServerVersion
  • Todos os endpoints GET para leitura de dados

Ferramentas bloqueadas:

  • Upload, atualização e exclusão de ativos
  • Criação e modificação de álbuns
  • Gerenciamento de usuários
  • Configuração do servidor

Exemplo de configuração do Claude Desktop (trecho mcporter.json):

{
  "mcpServers": {
    "claw2immich-readonly": {
      "command": "python",
      "args": ["c:\\path\\to\\claw2immich\\main.py"],
      "env": {
        "IMMICH_BASE_URL": "https://immich.example.com",
        "IMMICH_API_KEY": "your-read-only-key",
        "IMMICH_PROFILE": "read_only"
      }
    }
  }
}

read_write

Caso de uso: Gerenciamento completo de ativos e álbuns sem privilégios de administrador.

Permissões necessárias:

  • Todas as permissões de read_only mais:
  • asset.create - Enviar fotos/vídeos
  • asset.update - Editar metadados, favoritos
  • asset.delete - Remover ativos
  • album.create - Criar álbuns
  • album.update - Modificar álbuns
  • album.delete - Remover álbuns

Ferramentas típicas expostas:

  • Todas as ferramentas somente leitura mais:
  • immich_uploadAsset, immich_updateAsset, immich_deleteAssets
  • immich_createAlbum, immich_addAssetsToAlbum, immich_removeAssetFromAlbum
  • immich_updateUser (somente usuário próprio)
  • Todos os endpoints POST, PUT, PATCH, DELETE exceto somente administrador

Ferramentas bloqueadas:

  • Administração de usuários (getAllUsers, createUser, deleteUser)
  • Configuração do servidor (setServerConfig, updateServerConfig)
  • Manutenção do sistema (runJobs, validateStorage)
  • Gerenciamento de chaves de API

Exemplo de configuração do Claude Desktop:

{
  "mcpServers": {
    "claw2immich-readwrite": {
      "command": "python",
      "args": ["c:\\path\\to\\claw2immich\\main.py"],
      "env": {
        "IMMICH_BASE_URL": "https://immich.example.com",
        "IMMICH_API_KEY": "your-readwrite-key",
        "IMMICH_PROFILE": "read_write"
      }
    }
  }
}

full_scope

Caso de uso: Tarefas administrativas, gerenciamento de usuários, configuração do servidor.

Permissões necessárias:

  • Todas as permissões de read_write mais:
  • admin.user - Administração de usuários
  • admin.config - Configuração do servidor
  • admin.jobs - Gerenciamento de trabalhos
  • admin.apiKey - Gerenciamento de chaves de API

Ferramentas típicas expostas:

  • Todas as ferramentas de read_write mais:
  • immich_getAllUsers, immich_createUser, immich_updateUser, immich_deleteUser
  • immich_getServerConfig, immich_updateServerConfig
  • immich_getAllJobs, immich_runJob
  • immich_createApiKey, immich_updateApiKey, immich_deleteApiKey

Exemplo de configuração do Claude Desktop:

{
  "mcpServers": {
    "claw2immich-admin": {
      "command": "python",
      "args": ["c:\\path\\to\\claw2immich\\main.py"],
      "env": {
        "IMMICH_BASE_URL": "https://immich.example.com",
        "IMMICH_API_KEY": "your-admin-key",
        "IMMICH_PROFILE": "full_scope"
      }
    }
  }
}

Sem perfil (padrão)

Quando IMMICH_PROFILE não está definido, a filtragem de ferramentas depende exclusivamente de sondagens de capacidade e das permissões reais da chave de API. Isso é compatível com configurações existentes.

Diretrizes de seleção de perfil:

  • Use read_only para assistentes de IA que realizam pesquisa e análise sem necessidade de modificação
  • Use read_write para fluxos de trabalho gerais de gerenciamento de ativos e álbuns
  • Use full_scope somente quando acesso administrativo for necessário
  • Sempre crie uma chave de API dedicada do Immich com permissões mínimas para cada perfil

Execução

python main.py

Script auxiliar: CLI de pesquisa inteligente

Para depuração local rápida sem configuração de cliente MCP, use o script auxiliar:

python helper/smart_search_cli.py --list-envs
python helper/smart_search_cli.py --env .env --query "golden retriever on beach" --size 25 --order desc

Comportamento:

  • Lista os arquivos .env disponíveis no diretório atual (.env, .env_*).
  • Carrega IMMICH_BASE_URL e IMMICH_API_KEY ou IMMICH_API_TOKEN do arquivo env selecionado.
  • Chama POST /api/search/smart e imprime a resposta JSON diretamente no stdout.

Testes

Os testes de integração usam o executor unittest da biblioteca padrão (pytest também pode descobri-los).

Os motivos de ferramentas bloqueadas agora incluem detalhes de status HTTP ou erros de rede para ajudar a solucionar verificações de capacidade.

Configuração do teste de integração:

  1. Garanta que um servidor Immich esteja em execução e acessível.
  2. Crie .env_test com credenciais somente leitura.
  3. Crie .env com credenciais de acesso total, ou defina IMMICH_ENV_FULL para outro arquivo.

Os testes de cliente MCP iniciam um servidor em segundo plano usando SSE. Você pode substituir os padrões:

  • MCP_TEST_HOST (padrão 127.0.0.1)
  • MCP_TEST_PORT (padrão 0 para atribuição automática)
  • MCP_TEST_TIMEOUT (padrão 20 segundos)
  • MCP_LOG_LEVEL (padrão DEBUG para logs do servidor de teste)

Execute:

python -m unittest discover -s tests -v

Opcional com pytest:

pytest tests/

Você pode substituir os locais dos arquivos env:

  • IMMICH_ENV_TEST para o arquivo de credenciais restritas (padrão .env_test)
  • IMMICH_ENV_FULL para o arquivo de credenciais de acesso total (padrão .env)

Testes de integração de acesso por URL (test_integration_url_access.py)

Verifica se os campos web_url gerados pela camada de decoração de URL são acessíveis em uma instância Immich ativa (requer credenciais de login de sessão além de uma chave de API).

Crie .env_web na raiz do projeto (excluído por .gitignore):

IMMICH_BASE_URL=https://your-immich.example.com
IMMICH_API_KEY=<api-key-with-read-access>
IMMICH_EMAIL=<user@example.com>
IMMICH_PASSWORD=<your-password>
VariávelFinalidade
IMMICH_BASE_URLURL base da sua instância Immich
IMMICH_API_KEYChave de API para chamadas autenticadas
IMMICH_EMAILE-mail da conta para POST /api/auth/login
IMMICH_PASSWORDSenha da conta para login de sessão

IMMICH_EXTERNAL_DOMAIN também pode ser incluído para substituir a base de decoração de URL; se omitido, ele recorre à cadeia de descoberta de /api/server-config.

Execute:

pytest tests/test_integration_url_access.py -v

Os testes são ignorados automaticamente quando .env_web está ausente, o servidor está inacessível ou a instância não tem dados desse tipo. Substitua o caminho do arquivo com IMMICH_ENV_WEB:

IMMICH_ENV_WEB=/path/to/other.env pytest tests/test_integration_url_access.py -v
TesteEndpointPadrão de URL esperadoRegressão para
test_asset_web_url_accessibleGET /api/assets (fallback: POST /api/search/assets).../photos/{id}
test_album_web_url_accessibleGET /api/albums.../albums/{id}
test_person_web_url_accessibleGET /api/people.../people/{id} (não /photos/{id})item 49
test_place_web_url_accessibleGET /api/places.../explore...
test_newest_image_search_web_url_accessiblePOST /api/search/assets.../photos/{id}
test_random_person_web_url_accessibleGET /api/people (seleção aleatória).../people/{id}
test_random_album_web_url_accessibleGET /api/albums (seleção aleatória).../albums/{id}
test_random_video_web_url_accessiblePOST /api/search/assets tipo=VIDEO (seleção aleatória).../photos/{id}

Docker

Construir e executar localmente

Construa e execute com Docker Compose:

docker compose build
docker compose up

Nota: o contêiner executa main.py, que importa o pacote claw2immich. Se você alterar o layout do pacote, reconstrua a imagem para que o pacote atualizado seja copiado para o contêiner.

As variáveis de ambiente são passadas do seu shell ou arquivo .env:

  • IMMICH_BASE_URL (padrão http://host.docker.internal:2283)
  • IMMICH_API_KEY
  • IMMICH_API_TOKEN
  • IMMICH_WRITE_PROBE_PATH (padrão /api/assets)
  • IMMICH_WRITE_PROBE_METHOD (padrão POST)

Configurações do servidor MCP para Docker Compose:

  • MCP_TRANSPORT (padrão sse no compose; use streamable-http para HTTP)
  • MCP_HOST (padrão 0.0.0.0 no compose)
  • MCP_PORT (padrão 8000; publicado como porta do host)

Usar imagens pré-construídas do GitHub Container Registry

Imagens Docker pré-construídas são publicadas automaticamente no GitHub Container Registry (GHCR) para cada push nos branches main e develop, bem como para releases.

Baixar a imagem:

# Latest build from main branch
docker pull ghcr.io/joeru/claw2immich:latest

# Latest build from develop branch
docker pull ghcr.io/joeru/claw2immich:develop

# Specific version (e.g., 0.1.0)
docker pull ghcr.io/joeru/claw2immich:0.1.0

Executar a imagem:

docker run -e IMMICH_BASE_URL=https://immich.example.com \
           -e IMMICH_API_KEY=your-api-key \
           -p 8000:8000 \
           ghcr.io/joeru/claw2immich:latest

Executar com transporte SSE (HTTP):

docker run -e IMMICH_BASE_URL=https://immich.example.com \
           -e IMMICH_API_KEY=your-api-key \
           -e MCP_TRANSPORT=sse \
           -e MCP_HOST=0.0.0.0 \
           -p 8000:8000 \
           ghcr.io/joeru/claw2immich:latest

Executar com perfil somente leitura:

docker run -e IMMICH_BASE_URL=https://immich.example.com \
           -e IMMICH_API_KEY=your-readonly-api-key \
           -e IMMICH_PROFILE=read_only \
           -p 8000:8000 \
           ghcr.io/joeru/claw2immich:latest

As imagens suportam múltiplas arquiteturas (amd64, arm64) e são selecionadas automaticamente com base na sua plataforma.