Skip to main content

Gym MCP Client

A unified Python interface for working with both local and remote Gymnasium environments via gym-mcp-server.

Goal: Write code once, seamlessly switch between local development and remote execution.

Features

  • 🎮 Unified API: Same Gymnasium interface for both local and remote environments
  • 🔄 Seamless Switching: Change modes with a single parameter
  • 🌐 Remote Execution: Connect to gym-mcp-server instances over HTTP
  • 🔧 Full Compatibility: Supports all Gymnasium environment types (Box, Discrete, MultiBinary, etc.)
  • 🐍 Modern Python: Python 3.12+ with complete type hints
  • 📦 Easy Setup: Managed with uv for fast dependency management
  • ✅ Well Tested: 14 comprehensive tests, all passing

Installation

# Clone the repository
git clone <your-repo-url>
cd gym-mcp-client

# Install with uv (recommended)
uv sync

# Or with pip
pip install -e .

Quick Start

Local Mode

from gym_mcp_client import GymMCPClient

# Create a local environment
env = GymMCPClient("CartPole-v1", mode="local")

# Use standard Gymnasium API
observation, info = env.reset(seed=42)
action = env.action_space.sample()
observation, reward, terminated, truncated, info = env.step(action)

env.close()

Remote Mode

First, start a gym-mcp-server:

python -m gym_mcp_server --env CartPole-v1 --transport streamable-http --port 8000

Then connect to it:

from gym_mcp_client import GymMCPClient

# Create a remote environment
env = GymMCPClient(
    "CartPole-v1",
    mode="remote",
    gym_server_url="http://localhost:8000"
)

# Use the exact same API as local mode!
observation, info = env.reset(seed=42)
action = env.action_space.sample()
observation, reward, terminated, truncated, info = env.step(action)

env.close()

Context Manager

from gym_mcp_client import GymMCPClient

# Automatic cleanup
with GymMCPClient("CartPole-v1", mode="local") as env:
    observation, info = env.reset()
    action = env.action_space.sample()
    observation, reward, terminated, truncated, info = env.step(action)
    # env.close() called automatically

Switching Between Modes

The main benefit: write once, run anywhere!

import os
from gym_mcp_client import GymMCPClient

# Configuration from environment variables
MODE = os.getenv("GYM_MODE", "local")
SERVER_URL = os.getenv("GYM_SERVER_URL", "http://localhost:8000")

# Create environment based on mode
if MODE == "local":
    env = GymMCPClient("CartPole-v1", mode="local")
else:
    env = GymMCPClient(
        "CartPole-v1",
        mode="remote",
        gym_server_url=SERVER_URL,
        gym_server_key=os.getenv("GYM_API_KEY")
    )

# Your code works the same regardless of mode!
observation, info = env.reset()
for _ in range(1000):
    action = env.action_space.sample()
    observation, reward, terminated, truncated, info = env.step(action)
    if terminated or truncated:
        observation, info = env.reset()

env.close()

Switch modes via command line:

# Run locally
export GYM_MODE=local
python your_training_script.py

# Run remotely
export GYM_MODE=remote
export GYM_SERVER_URL=http://gpu-server:8000
python your_training_script.py

API Reference

GymMCPClient

GymMCPClient(
    env_id: str,
    mode: str = "local",
    render_mode: str | None = None,
    gym_server_url: str | None = None,
    gym_server_key: str | None = None,
    **kwargs
)

Parameters:

  • env_id: Gymnasium environment ID (e.g., "CartPole-v1")
  • mode: Either "local" or "remote"
  • render_mode: Render mode ("rgb_array", "human", etc.)
  • gym_server_url: URL of gym-mcp-server (required for remote mode)
  • gym_server_key: Optional API key for authentication
  • **kwargs: Additional arguments passed to gym.make() in local mode

Methods:

  • reset(seed=None, options=None) → (observation, info)
  • step(action) → (observation, reward, terminated, truncated, info)
  • render() → render_output
  • close() → None

Properties:

  • observation_space: The observation space
  • action_space: The action space
  • reward_range: The reward range
  • metadata: Environment metadata

Architecture

┌─────────────────┐
│  Your Code      │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ GymMCPClient    │
└────────┬────────┘
         │
    ┌────┴────┐
    ▼         ▼
┌────────┐ ┌──────────────┐
│ Local  │ │ Remote       │
│ Gym    │ │ HTTP Client  │
└────────┘ └──────┬───────┘
              │
              ▼
         ┌──────────────┐
         │ gym-mcp-     │
         │ server       │
         └──────┬───────┘
                │
                ▼
           ┌────────┐
           │ Gym    │
           │ Env    │
           └────────┘

Supported Space Types

Space Type Local Remote Serialization
Box ✅ ✅ array ↔ list
Discrete ✅ ✅ int ↔ int
MultiBinary ✅ ✅ array ↔ list
MultiDiscrete ✅ ✅ array ↔ list
Tuple ✅ ✅ recursive
Dict ✅ ✅ recursive

Examples

See the examples/ directory:

  • local_example.py: Local mode usage
  • remote_example.py: Remote mode usage
  • context_manager_example.py: Context manager pattern

Run examples:

# Local mode
uv run python examples/local_example.py

# Remote mode (start server first!)
python -m gym_mcp_server --env CartPole-v1 --transport streamable-http --port 8000
uv run python examples/remote_example.py

# Demo CLI tool
python main.py --mode local --episodes 3

Development

Setup

git clone <your-repo-url>
cd gym-mcp-client
make install

Available Commands

make help       # Show all commands
make test       # Run test suite (14 tests)
make lint       # Run ruff linter
make format     # Format code with ruff
make typecheck  # Run mypy type checker
make check      # Run all checks (lint + typecheck + test)
make all        # Format, then run all checks
make demo       # Run local demo
make clean      # Clean build artifacts

Running Tests

make test
# Or: uv run pytest tests/ -v
# 14 tests, all passing ✅

Use Cases

  1. Development → Production: Develop locally, deploy remotely
  2. Distributed Training: Multiple processes connecting to remote environments
  3. Resource Management: Run expensive simulations on dedicated servers
  4. Testing: Test locally before remote deployment

Performance

Local Mode

  • Overhead: Minimal (thin wrapper)
  • Best for: Development, testing, lightweight environments

Remote Mode

  • Overhead: HTTP round-trip (1-10ms on localhost)
  • Best for: Expensive environments, distributed training, resource sharing

Error Handling

from gym_mcp_client import GymMCPClient
import httpx

try:
    env = GymMCPClient(
        "CartPole-v1",
        mode="remote",
        gym_server_url="http://localhost:8000"
    )
    observation, info = env.reset()
    # ... your code ...
except ValueError:
    # Invalid mode, missing URL, etc.
    pass
except RuntimeError:
    # Environment initialization failed, remote call failed
    pass
except httpx.HTTPError:
    # Network error (remote mode only)
    pass
finally:
    if 'env' in locals():
        env.close()

Troubleshooting

Remote Connection Issues

  1. Ensure the gym-mcp-server is running and accessible
  2. Check URL is correct (including protocol: http:// or https://)
  3. Verify firewall/network settings
  4. Check server logs for errors

Environment Not Found

# For Atari environments
uv add "gymnasium[atari]"

# For Box2D environments
uv add "gymnasium[box2d]"

# For MuJoCo environments
uv add "gymnasium[mujoco]"

Requirements

  • Python 3.12+
  • gymnasium >= 1.2.1
  • httpx >= 0.28.1
  • numpy >= 2.0.0
  • gym-mcp-server (from GitHub)

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run make check to verify all tests pass
  5. Submit a Pull Request

See CONTRIBUTING.md for detailed guidelines.

License

MIT License - see LICENSE file for details.

Related Projects

Support

  • Issues: Open a GitHub issue
  • Questions: Start a GitHub discussion
  • Documentation: See examples/ directory

Status: ✅ Production Ready | Version: 0.1.0 | Python: 3.12+

Metadata

Release files for gym-mcp-client 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gym-mcp-client 0.1.0
File Size Uploaded
gym_mcp_client-0.1.0.tar.gz 12.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gym-mcp-client 0.1.0
File Interpreter ABI Platform
gym_mcp_client-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.7 kB

Release files / gym_mcp_client-0.1.0.tar.gz

Download URL gym_mcp_client-0.1.0.tar.gz
Size 12.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f432bafcd227da9f627f66d8e8cc6bd14f8fe3b8df451e600f52cb0d3791f17c
BLAKE2b-256 checksum
How to use checksums
a82e3b366894d7a082f36f31828c0992ae2a5087b25cb20f8d4afe6aff5bb76c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release files / gym_mcp_client-0.1.0-py3-none-any.whl

Download URL gym_mcp_client-0.1.0-py3-none-any.whl
Size 9.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c1fb0e89af4aa05b74f1c6e800db1084459e54aadc9dbff13bf69d0e361453b
BLAKE2b-256 checksum
How to use checksums
45ae0fdecda9f88359cd8ecd60c71549116e30a063102a04fc50d7b3460a3995
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page