Labsco
ProjectAtlantis-dev logo

Project Atlantis

β˜… 8

from ProjectAtlantis-dev

A Python MCP host server that allows for dynamic installation of functions and third-party MCP tools.

πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedFreeAdvanced setup

terminal

Project Atlantis

Meow! Ideally, you may want to create an account first at www.projectatlantis.ai and then have the bot walk you through setup (assuming everything works okay)

Basically we have a distributed linux-style system that provides tool infra for bots. Tools are arranged in folders for easy management across functions and teams. Teams can call each other's functions directly or of course the bots can just do things themselves. Under the covers is an MCP-compliant system but we support hotloading etc. without some of the clunky overhead of constantly updating MCP tools.

To get started, clone the repo, do the Python env stuff, set up your API keys as environment variables (OPENROUTER_API_KEY, ANTHROPIC_API_KEY, etc.) and connect this local Python server to the main server (see runServer). We give you all the source code to build your own tool-calling chatbot just like Claude or whatever. See Bot/Kitty/ for working examples using OpenRouter and Anthropic APIs β€” the bot discovers tools dynamically via search/dir rather than pre-loading them.

*note that Home/game.py is run whenever a new chat is created and will set the default chat tool

Project Atlantis Network

Each MCP server is part of a collaborative network of AI agents and developers. Using the Model Context Protocol, the platform creates an ecosystem where agents can discover and use each other's capabilities across the network. Tools and functions can be shared, discovered, and coordinated between agentsβ€”whether for robot-driven frontier development, automation tasks, or any other application. The network architecture enables agents to find and leverage tools from other users, creating a decentralized ecosystem of shared capabilities.

The centerpiece of this project is a Python MCP host (referred to as a 'remote') that lets you install functions and 3rd party MCP tools on the fly

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 dynamic_functions/ directory is not part of this repo β€” it is gitignored. You are expected to maintain your own functions in a separate repository and symlink it in.

Why the separation matters: Everything in this repo is Atlantis platform code β€” the MCP server, runtime, client. Everything under dynamic_functions/ is your code β€” your tools, your apps, your data. Keeping them in separate repos makes this boundary explicit, which is especially important when working with AI coding agents (Claude Code, Codex, etc.) that need to understand what is platform infrastructure vs. what is user-authored tool code they can freely create and modify. It also means you can update the Atlantis server without touching your functions, and version your functions independently.

cd python-server

# create your own repo for your functions (or use an existing one)
git init ~/my-atlantis-functions

# symlink it into the server
ln -s ~/my-atlantis-functions dynamic_functions

The first time the server starts, it auto-scaffolds a starter Demo app with example functions so you have something to play with immediately (this runs once, gated by a .demo_scaffolded marker file β€” not by whether the directory exists). From there, we recommend moving those files into your own repo and symlinking back:

cd python-server
mv dynamic_functions ~/my-atlantis-functions
git -C ~/my-atlantis-functions init
ln -s ~/my-atlantis-functions dynamic_functions

The server doesn't care where the symlink points as long as the directory structure follows the expected layout (see below).

For detailed information about creating and using dynamic functions, see the Dynamic Functions Documentation. For an example of wiring a UI button back into a Python callback, see Onclick Callbacks.

Dynamic MCP Servers

  • gives users the ability to install and manage third-party MCP server tools; JSON config files are kept in the dynamic_servers/ folder

  • each MCP server will need to be 'started' first to fetch the list of tools

  • each server config follows the usual JSON structure that contains an 'mcpServers' element; for example, this installs an openweather MCP server:

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

The weather MCP service is just an existing one I ported to uvx. See here

Cloud

The cloud service at https://www.projectatlantis.ai provides a centralized hub for managing your remote servers and sharing tools across machines.

App Organization

Dynamic functions are organized into apps using folder structure. Simply place your .py files in subdirectories:

dynamic_functions/
β”œβ”€β”€ Home/                    # App: "Home"
β”‚   └── kitty.py
β”œβ”€β”€ Accounting/              # App: "Accounting"
β”‚   β”œβ”€β”€ accounting.py
β”‚   └── foo.py
└── FilmFromImage/          # App: "FilmFromImage"
    └── qwen_image_edit_local.py

The folder name IS the app name. Functions in Home folder are assigned accordingly.

Nested Apps (Subfolders)

Create nested app structures using subfolders:

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

This creates the app name: MyApp/SubModule/Feature

Best Practices:

  • Keep it simple - one level of folders is usually enough
  • Use descriptive folder names (e.g., Chat, Admin, Tools)
  • Group related functions together in the same folder
  • The folder structure keeps your code organized and clear

Tool Calling with Search Terms

When calling tools, you can use compound tool names to disambiguate functions. Only include as much of the path as needed to uniquely identify the function.

Format: remote_owner*remote_name*app*location*function

Key Principle: Use the simplest form that resolves uniquely

# 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

Examples:

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

How it works:

  • Fields: remote_owner*remote_name*app*location*function
  • Separate fields with * (asterisk)
  • Omit fields you don't need (use empty strings: **App**func)
  • The app field supports slash notation for nested apps (MyApp/SubModule)
  • The last field is always the function name
  • No asterisks = treat entire name as function name

When to use compound names:

  • Name conflicts: Multiple apps have functions with the same name
  • Remote targeting: Call functions on specific remotes from the cloud
  • Location routing: Target functions at specific physical locations
  • Multi-user setups: Specify owner and remote in shared environments

Best practice: Start simple (update_image) and add context only when needed to resolve ambiguity (**ImageTools**update_image).

Example:

# 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

Bot Runtime

The bot/chat runtime is not platform code in this repo. It lives in a separate dynamic-functions repo, normally linked into:

python-server/dynamic_functions/atlantis-mcp-chat -> /path/to/atlantis-mcp-chat

That repo contains the game/chat tools, bot runtime, content, and player data helpers. The Atlantis MCP server treats it like any other dynamic-functions app: it scans the linked folder, exposes decorated functions as tools, and reloads them when files change.

Key Files

  • python-server/dynamic_functions/Home/ β€” small platform-owned Home app used for Lobster/Multix readme entry points.
  • python-server/dynamic_functions/atlantis-mcp-chat/ β€” symlink to the separate bot/chat dynamic-functions repo.
  • python-server/dynamic_functions/atlantis-mcp-chat/Home/ β€” chat/game app code in the external repo.
  • python-server/dynamic_functions/atlantis-mcp-chat/Data/ β€” data helpers and player/session state in the external repo.

Troubleshooting

If MCP tools aren't working (e.g. returning Unknown tool errors), check the server log first. The Python server writes detailed logs to python-server/runServer.log β€” this file shows exactly what's happening with tool calls, cloud auth, and client connections. It can get large, so tail the last ~1000 lines:

tail -1000 python-server/runServer.log

Common issues visible in the log:

  • ⚠️ Unexpected tool call from local client β€” the server received a tool call but didn't recognize it; check that your tools are registered
  • ❌ Authentication failed β€” cloud credentials are wrong or the account doesn't exist; check your email/api-key
  • 🏠 Local MCP tool call intercepted β€” confirms the server is receiving tool calls from the MCP client
  • MCP handshake errors usually mean the client is pointed at the wrong port. The default local MCP port is 8000; make sure the server --port and client --port match.

Visitor-related log lines include "Visitor:", "New conversation for", and "Injected time-gap message".

Our Greenland Terrain Server

lobby

The goal is to use this system as the main bot infrastructure (tool etc.) for our Greenland terrain server