Project Atlantis

by ProjectAtlantis-dev

231 downloads
Not rated
GitHub

About

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

Details

Author
ProjectAtlantis-dev
Downloads
231
Categories
Developer Tools, Automation, API, Other

- Dynamic functions as hot‑reloaded Python tools
- Dynamic MCP server management via JSON config
- Cloud‑connected for auth and tool sharing
- Supports multiple remote instances
- Local MCP client for use with Claude or Cursor

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Project Atlantis
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Install Python 3.12 and Node, then configure the runServer script with your email and API key, and sign in at projectatlantis.ai. Run the Python server process, which will auto-connect to the cloud.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "project atlantis": {
            "atlantis-mcp-server": {
                "command": "python",
                "args": [
                    "server.py",
                    "\\"
                ]
            }
        }
    }
}

McpServers

{
    "atlantis-mcp-server": {
        "command": "python",
        "args": [
            "server.py",
            "\\"
        ]
    }
}

Meow! Ideally, you may want to create an account first atwww.projectatlantis.aiand 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. SeeBot/Kitty/for working examples using OpenRouter and Anthropic APIs — the bot discovers tools dynamically via search 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

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
-

Prerequisites - need to install Python for the server and Node for Lobster (the MCP client); you should also install uv/uvx and node/npx since it seems that MCP needs both

Python 3.13 seems to be most stable right now because of async support

Set up your Python virtual environment and install dependencies:

cd python-server python3 -m venv venv source venv/bin/activate pip install -r requirements.txt

- Edit the runServer script in thepython-serverfolder and set the email and service name (it's actually best practice to create a copy "runServerFoo" that you can replace the runServer file with when we do updates):

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

- The MCP client is now calledLobster. To connect it to Claude Code:

claude mcp add atlantis -- npx atlantis-mcp --port 8000

codex mcp add atlantis -- npx atlantis-mcp --port 8000

The default local MCP port is8000. If the client reports handshake errors, first check that the Python server and the MCP client are using the same port.

To add Atlantis Open Weather for testing:

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

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

Thedynamic_functions/directory does not ship with this repo — on first run, the server auto-scaffolds a starterDemoapp with example functions. We recommend moving these into your own git repo and symlinking back (seeDynamic Functionsbelow). Thedynamic_servers/folder will be empty except for an example weather config

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

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

- 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

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

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

- Location of our 'remote'. Runs locally but can be controlled remotely

- 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'

If you are trying to understand the Python source, start inpython-server/server.pyand then branch out from there:

- server.py- main entry point and protocol host. It starts the Starlette app, owns theDynamicAdditionServerclass, manages WebSocket and cloud Socket.IO connections, and wires together the function/server managers. If you are tracing a tool invocation, the consolidated MCPtools/callhandler lives here inDynamicAdditionServer._handle_tools_call(), which then delegates to_execute_tool().
- DynamicFunctionManager.py- owns the dynamic Python tool system underdynamic_functions/. This is where function decorators are defined (@visible,@public,@protected, etc.), files are scanned and validated, Python modules are loaded/reloaded, and tool calls are dispatched into user code.
- DynamicServerManager.py- manages third-party MCP server configs underdynamic_servers/. It saves/loads JSON configs, starts stdio MCP servers, keeps sessions alive, and fetches their tool lists.
- atlantis.py- the dynamic function harness/runtime API injected into dynamic functions. This is the bridge that tool code uses forclient_log, streaming, HTML/image/video responses, click/upload callbacks, request context, and persistent shared state. See the
Dynamic Functions Documentationfor the function-authoring side of this API.
- lobster.py- compatibility layer for the local Atlantis MCP client. It defines thereadme/command/chattools and translates those local calls into the cloud-backed command flow.
- state.py- central configuration and process-wide state. It sets up logging, definesFUNCTIONS_DIRandSERVERS_DIR, and stores base server constants like host/port and request timeout.
- utils.py- low-level helpers shared across the server and dynamic functions. It contains search-term parsing, JSON/log formatting, the global server-instance bridge, and client command/log plumbing used byatlantis.py.
- PIDManager.py- single-instance guard for the Python server process via PID files.
- ColoredFormatter.py- logging formatter and request-context filter used bystate.py.
- server.pyreceives MCP traffic.
- server.pyroutes MCPtools/callthroughDynamicAdditionServer._handle_tools_call().
- _handle_tools_call()delegates Python tool execution toDynamicFunctionManager.pyand proxied MCP tool execution toDynamicServerManager.py.
- Dynamic functions call back into the host throughatlantis.pyandutils.py.

For dynamic function authoring details, seeDynamic Functions Documentation. For wiring browser callbacks (button clicks, uploads) into Python functions, seeOnclick Callbacks. For auth and trust boundaries, seeSecurity Model.

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

Thedynamic_functions/directory isnot 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 underdynamic_functions/isyour 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 starterDemoapp with example functions so you have something to play with immediately (this runs once, gated by a.demo_scaffoldedmarker 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 theDynamic Functions Documentation. For an example of wiring a UI button back into a Python callback, seeOnclick Callbacks.

-

gives users the ability to install and manage third-party MCP server tools; JSON config files are kept in thedynamic_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. Seehere

The cloud service athttps://www.projectatlantis.aiprovides a centralized hub for managing your remote servers and sharing tools across machines.

Dynamic functions are organized into apps usingfolder structure. Simply place your.pyfiles 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 inHomefolder are assigned accordingly.

Create nested app structures using subfolders:

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

This creates the app name:MyApp/SubModule/Feature

- 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

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

Format:remote_ownerremote_nameapplocationfunction

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? Chatsend_message ✅ Clear! The one in Chat Emailsend_message ✅ Clear! The one in Email
update_image → Simple call (only works if unique) MyAppupdate_image → Specify app to disambiguate MyApp/SubModuleprocess_data → Nested app path aliceprodAdminrestart → Full routing: owner + remote + app + function officeprint → Just location context

- Fields:remote_ownerremote_nameapplocationfunction
- Separate fields with
(asterisk)
- Omit fields you don't need(use empty strings:Appfunc)
- 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

- 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 (ImageToolsupdate_image).

# 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: ImageToolsupdate_image ✅ Now we need to specify the app

The bot/chat runtime lives in this repo as a dynamic-functions app:

It holds the game/chat tools, bot runtime, static content underGame/, and live player state underData/. The Atlantis MCP server treats it like any other dynamic-functions app: it scans the folder, exposes decorated functions as tools, and reloads them when files change.

- python-server/dynamic_functions/Home/— small platform-owned Home app used for Lobster/Multix readme entry points.
- python-server/dynamic_functions/Chat/— the bot/chat runtime app.
- python-server/dynamic_functions/Terrain/— tracked terrain tooling, including the database lifecycle and schema; the live SQLite database remains untracked.
- python-server/dynamic_functions/Chat/Game/— static content: bots, locations, scenes. Tracked.
- python-server/dynamic_functions/Chat/Data/— live per-game state, keyed bygame_key. Not tracked.

If MCP tools aren't working (e.g. returningUnknown toolerrors),check the server log first. The Python server writes detailed logs topython-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:

- ⚠️ 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 is8000; make sure the server--portand client--portmatch.

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

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

This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.

The MCP server for Bitrix24 provides AI assistants with structured access to the Bitrix24 API. It delivers up-to-date method descriptions, parameters, and valid values, allowing assistants to work with precise data instead of guesswork. This reduces code errors and accelerates Bitrix24 integration development.

One remote MCP server for 500+ production APIs — Stripe, HubSpot, Postgres, Gmail, and more. OAuth and API key auth, credential management, and a CLI.

Single tool to control all 100+ API integrations, and UI components

Agent-native developer Q&A API with MCP + A2A endpoints for citations, job pickup, and answer submission.

Self-hosted MCP gateway: convert REST/SOAP/GraphQL/SQL APIs into MCP tools with 29 pre-built adapters, OAuth2, RBAC and audit log.

A universal bridge to convert any web API into an MCP server, supporting multiple transport types.

Dynamically creates MCP servers from web API configurations, integrating any REST API, GraphQL endpoint, or web service into MCP-compatible tools.

Hosted MCP server and coordination layer for AI coding agents — live API contracts, database schema, frontend/backend mismatch detection, and shared handoff tickets for Claude Code, Cursor, Codex, and Lovable.

An MCP server that dynamically loads tools from an external JSON file configured via an environment variable.

A lightweight server exposing Axone's capabilities through the Model-Context Protocol.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.