Project Atlantis

Um servidor host MCP em Python que permite a instalação dinâmica de funções e ferramentas MCP de terceiros.

Documentação

terminal

Project Atlantis

Miau! Idealmente, você pode querer criar uma conta primeiro em www.projectatlantis.ai e então fazer o bot guiá-lo pela configuração (assumindo que tudo funcione corretamente)

Basicamente, temos um sistema distribuído estilo Linux que fornece infraestrutura de ferramentas para bots. As ferramentas são organizadas em pastas para facilitar o gerenciamento entre funções e equipes. As equipes podem chamar as funções umas das outras diretamente ou, é claro, os bots podem simplesmente fazer as coisas por conta própria. Nos bastidores, há um sistema compatível com MCP, mas oferecemos suporte a hotloading etc. sem parte da sobrecarga complicada de atualizar constantemente as ferramentas MCP.

Para começar, clone o repositório, configure o ambiente Python, defina suas chaves de API como variáveis de ambiente (OPENROUTER_API_KEY, ANTHROPIC_API_KEY, etc.) e conecte este servidor Python local ao servidor principal (veja runServer). Fornecemos todo o código-fonte para você criar seu próprio chatbot de chamada de ferramentas, como o Claude ou similar. Veja Bot/Kitty/ para exemplos funcionais usando as APIs OpenRouter e Anthropic — o bot descobre ferramentas dinamicamente por busca, em vez de pré-carregá-las.

*observe que o callback @game é executado sempre que um novo chat é criado

Rede Project Atlantis

Cada servidor MCP faz parte de uma rede colaborativa de agentes de IA e desenvolvedores. Usando o Model Context Protocol, a plataforma cria um ecossistema onde agentes podem descobrir e usar as capacidades uns dos outros na rede. Ferramentas e funções podem ser compartilhadas, descobertas e coordenadas entre agentes — seja para desenvolvimento de fronteira orientado por robôs, tarefas de automação ou qualquer outra aplicação. A arquitetura de rede permite que agentes encontrem e aproveitem ferramentas de outros usuários, criando um ecossistema descentralizado de capacidades compartilhadas.

A peça central deste projeto é um host MCP em Python (referido como 'remote') que permite instalar funções e ferramentas MCP de terceiros em tempo real

Início Rápido

  1. Pré-requisitos — é necessário instalar Python para o servidor e Node para o Lobster (o cliente MCP); você também deve instalar uv/uvx e node/npx, pois parece que o MCP precisa de ambos

  2. Python 3.13 parece ser o mais estável no momento por causa do suporte a async

  3. Configure seu ambiente virtual Python e instale as dependências:

cd python-server
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
  1. Edite o script runServer na pasta python-server e defina o e-mail e o nome do serviço (na verdade, é uma boa prática criar uma cópia "runServerFoo" que você pode substituir pelo arquivo runServer quando fizermos atualizações):
python server.py  \
  --email=youremail@gmail.com  \             # email you use for project atlantis
  --api-key=foobar \                         # should change online
  --host=localhost \                         # npx MCP will be looking here to connect to remote (assumes there is at least one running locally)
  --port=8000  \
  --cloud-host=wss://projectatlantis.ai  \   # points to cloud
  --cloud-port=443  \
  --service-name=home                        # remote name, can be anything but must be unique across all machines
  1. O cliente MCP agora é chamado de Lobster. Use a porta configurada por --port no comando de inicialização do servidor Python (por exemplo, seu script runServer). Substitua YOUR_SERVER_PORT abaixo por esse número; não assuma que seja 8000.

Para conectá-lo ao Claude Code:

claude mcp add atlantis_lobster -- npx atlantis-mcp --port YOUR_SERVER_PORT

Para conectar ao Codex:

codex mcp add atlantis_lobster -- npx atlantis-mcp --port YOUR_SERVER_PORT

A porta padrão é 8000 somente quando nenhuma substituição de porta está configurada. Se você alterar a porta do servidor, atualize também o argumento --port na entrada do MCP. Veja o README do cliente Lobster para um modelo de configuração JSON.

Para adicionar o Atlantis Open Weather para testes:

claude mcp add --transport stdio weather_forecast --env OPENWEATHER_API_KEY=mykey123 -- uvx --from atlantis-open-weather-mcp start-weather-server

  1. To connect to Atlantis, sign into https://www.projectatlantis.ai under the same email

  2. Your remote(s) should autoconnect using email and default api key = 'foobar' (see 'api' command to generate a new key later). The first server to connect will be assigned your 'default' unless you manually change it later

  3. Terrain and Chat come pre-installed, along with the Home app, in python-server/dynamic_functions/. On first run, the server also creates a starter Demo app with example functions. No separate installation is needed for these bundled apps. The dynamic_servers/ folder includes an example weather config.

  4. You can run this standalone MCP or accessed from the cloud or both

Architecture

Caveat: MCP terminology is already terrible and calling things 'servers' or 'hosts' just makes it more confusing because MCP is inherently p2p

Pieces of the system:

  • Cloud: our experimental Atlantis cloud server; mostly a place to share tools and let users bang on them
  • Remote: the Python server process found in this repo, officially referred to as an MCP 'host' (you can run >1 either on same box or on different one, just specify different service names)
  • Dynamic Function: a simple Python function that you write, acts as a tool
  • Dynamic MCP Server: any 3rd party MCP, stored as a JSON config file

design

Note that MCP auth and security are still being worked out so using the cloud for auth is easier right now

Directories

  1. Python Remote (MCP P2P server) (python-server/)

    • Location of our 'remote'. Runs locally but can be controlled remotely
  2. Lobster (MCP Client) (client/)

    • lets Claude Code or Codex run Atlantis commands or chat via MCP
    • uses npx (easy to install into Claude Code or Codex)
    • cloud connection not needed - although it may complain
    • only supports a subset of the spec
    • can only see tools on the local box (at least right now) or shared tools set to 'public'

Python Server Layout

Start in python-server/server.py. It is the protocol host: it owns the WebSocket and cloud connections, and MCP tools/call goes through DynamicAdditionServer._handle_tools_call(). From there:

  • DynamicFunctionManager.py loads, validates and calls the Python tools in dynamic_functions/, and defines the decorators.
  • DynamicServerManager.py runs the third-party MCP servers configured in dynamic_servers/.
  • atlantis.py is the runtime API that tool code calls back into.
  • lobster.py holds the local Lobster client's readme / command / chat tools.
  • state.py and utils.py hold config, logging and shared helpers.

Further docs:

Features

Dynamic Functions

Dynamic functions give users the ability to create and maintain custom functions-as-tools. Functions are loaded on start and automatically reloaded when modified.

The python-server/dynamic_functions/ directory includes the pre-installed Terrain, Chat, Bot, and Home apps. These apps are tracked with the server source. Seeing them on a new server is expected.

On first run, the server also creates a starter Demo app with example functions, once per .demo_scaffolded marker. Your own apps and generated runtime data are separate from the bundled code and are ignored by Git by default.

Add your own app in a new subfolder. If you keep its source in a separate repository, symlink just that app into dynamic_functions/:

# After creating your app repository at ~/my-atlantis-app:
cd python-server
ln -s ~/my-atlantis-app dynamic_functions/MyApp

Mantenha as pastas incluídas no lugar. Substituir ou mover o diretório inteiro dynamic_functions/ também removeria os aplicativos pré-instalados deste checkout.

Para informações detalhadas sobre criação e uso de funções dinâmicas, veja a Documentação de Funções Dinâmicas.

Servidores MCP Dinâmicos

  • dá aos usuários a capacidade de instalar e gerenciar ferramentas de servidores MCP de terceiros; arquivos de configuração JSON são mantidos na pasta dynamic_servers/

  • cada servidor MCP precisará ser 'iniciado' primeiro para buscar a lista de ferramentas

  • cada configuração de servidor segue a estrutura JSON usual que contém um elemento 'mcpServers'; por exemplo, isto instala um servidor MCP openweather:

    {
       "mcpServers": {
          "openweather": {
             "command": "uvx",
             "args": [
             "--from",
             "atlantis-open-weather-mcp",
             "start-weather-server",
             "--api-key",
             "<your openweather api key>"
             ]
          }
       }
    }
    

O serviço MCP de clima é apenas um existente que portei para uvx. Veja aqui

Nuvem

O serviço de nuvem em https://www.projectatlantis.ai fornece um hub centralizado para gerenciar seus servidores remotos e compartilhar ferramentas entre máquinas.

Organização de Aplicativos

Funções dinâmicas são organizadas em aplicativos usando estrutura de pastas. Simplesmente coloque seus arquivos .py em subdiretórios:

dynamic_functions/
├── Home/                    # App: "Home"
│   └── kitty.py
├── Accounting/              # App: "Accounting"
│   ├── accounting.py
│   └── foo.py
└── FilmFromImage/          # App: "FilmFromImage"
    └── qwen_image_edit_local.py

O nome da pasta É o nome do aplicativo. Funções na pasta Home são atribuídas de acordo.

Aplicativos Aninhados (Subpastas)

Crie estruturas de aplicativos aninhados usando subpastas:

dynamic_functions/
└── MyApp/
    └── SubModule/
        └── Feature/
            └── my_function.py

Isso cria o nome do aplicativo: MyApp/SubModule/Feature

Melhores Práticas:

  • Mantenha simples — um nível de pastas geralmente é suficiente
  • Use nomes descritivos de pastas (ex.: Chat, Admin, Tools)
  • Agrupe funções relacionadas na mesma pasta
  • A estrutura de pastas mantém seu código organizado e claro

Chamada de Ferramentas com Termos de Busca

Ao chamar ferramentas, você pode usar nomes compostos de ferramentas para desambiguar funções. Inclua apenas o quanto do caminho for necessário para identificar exclusivamente a função.

Formato: remote_owner*remote_name*app*location*function

Princípio-chave: Use a forma mais simples que resolva exclusivamente

# If you have these functions:
# - dynamic_functions/Chat/send_message.py
# - dynamic_functions/Email/send_message.py
# - dynamic_functions/SMS/send_message.py

send_message              ❌ Ambiguous! Which one?
**Chat**send_message      ✅ Clear! The one in Chat
**Email**send_message     ✅ Clear! The one in Email

Exemplos:

update_image                          → Simple call (only works if unique)
**MyApp**update_image                 → Specify app to disambiguate
**MyApp/SubModule**process_data       → Nested app path
alice*prod*Admin**restart             → Full routing: owner + remote + app + function
***office*print                       → Just location context

Como funciona:

  • Campos: remote_owner*remote_name*app*location*function
  • Separe campos com * (asterisco)
  • Omita campos que você não precisa (use strings vazias: **App**func)
  • O campo de aplicativo suporta notação de barra para aplicativos aninhados (MyApp/SubModule)
  • O último campo é sempre o nome da função
  • Sem asteriscos = trate o nome inteiro como nome da função

Quando usar nomes compostos:

  • Conflitos de nome: Vários aplicativos têm funções com o mesmo nome
  • Direcionamento remoto: Chame funções em remotos específicos a partir da nuvem
  • Roteamento de localização: Direcione funções para locais físicos específicos
  • Configurações multiusuário: Especifique proprietário e remoto em ambientes compartilhados

Melhor prática: Comece simples (update_image) e adicione contexto somente quando necessário para resolver ambiguidade (**ImageTools**update_image).

Exemplo:

# File: dynamic_functions/ImageTools/process.py
@visible
async def update_image(image_path: str):
    """Update an image."""
    return "updated"

# If this is the ONLY update_image:
update_image                          ✅ Works fine!

# If Chat app ALSO has update_image:
**ImageTools**update_image            ✅ Now we need to specify the app

Runtime do Bot

O runtime do bot/chat vive neste repositório como um aplicativo de funções dinâmicas:

python-server/dynamic_functions/Chat/

Ele contém as ferramentas de jogo/chat, o runtime do bot, conteúdo estático em Game/ e estado de jogadores ao vivo em Data/. O servidor MCP Atlantis o trata como qualquer outro aplicativo de funções dinâmicas: ele escaneia a pasta, expõe funções decoradas como ferramentas e as recarrega quando os arquivos mudam.

Arquivos Principais

  • python-server/dynamic_functions/Home/ — pequeno aplicativo Home de propriedade da plataforma usado para pontos de entrada do README do Lobster/Multix e o callback de arquivo. Veja o README do Home.
  • python-server/dynamic_functions/Chat/ — o aplicativo de runtime do bot/chat. Veja o README do Chat.
  • python-server/dynamic_functions/Terrain/ — ferramentas de terreno rastreadas, incluindo o ciclo de vida do banco de dados e o esquema; o banco de dados SQLite ao vivo permanece não rastreado. Veja o README do Terrain.
  • python-server/dynamic_functions/Chat/Game/ — conteúdo estático do jogo: locais, cenas. Rastreado.
  • python-server/dynamic_functions/Bot/ — informações estáticas do bot em Bot/<sid>/ (config, prompt, imagem). Rastreado. Mantido separado do Chat para que os bots possam viver em uma máquina diferente do jogo.
  • python-server/dynamic_functions/Chat/Data/ — estado ao vivo por jogo, chaveado por game_key. Não rastreado.

Solução de Problemas

Se as ferramentas MCP não estiverem funcionando (ex.: retornando erros Unknown tool), verifique o log do servidor primeiro. O servidor Python escreve logs detalhados em python-server/runServer.log — este arquivo mostra exatamente o que está acontecendo com chamadas de ferramentas, autenticação na nuvem e conexões de clientes. Ele pode ficar grande, então veja as últimas ~1000 linhas:

tail -1000 python-server/runServer.log

Problemas comuns visíveis no log:

  • ⚠️ Unexpected tool call from local client — o servidor recebeu uma chamada de ferramenta, mas não a reconheceu; verifique se suas ferramentas estão registradas
  • ❌ Authentication failed — as credenciais da nuvem estão erradas ou a conta não existe; verifique seu e-mail/chave de API
  • 🏠 Local MCP tool call intercepted — confirma que o servidor está recebendo chamadas de ferramentas do cliente MCP
  • Erros de handshake do MCP geralmente significam que o cliente está apontado para a porta errada. A porta MCP local padrão é 8000; certifique-se de que o servidor --port e o cliente --port correspondam.

Linhas de log relacionadas a visitantes incluem "Visitor:", "New conversation for" e "Injected time-gap message".

Nosso Servidor de Terreno da Groenlândia

lobby

O objetivo é usar este sistema como a principal infraestrutura de bots (ferramentas etc.) para nosso servidor de terreno da Groenlândia