Skip to main content

Simple and efficient RPC framework for AI agents

Project description

Remotable Function

Simple and efficient RPC framework for AI agents

Python 3.8+ License: MIT Version


What is Remotable Function?

Remotable Function is a lightweight RPC framework that makes it easy for servers to call tools on remote clients, perfect for AI agents that need to execute code, access files, or run commands on user machines.

Architecture

┌─────────────────┐     WebSocket + JSON-RPC 2.0     ┌─────────────────┐
│   Gateway       │ ◄─────────────────────────────► │   Client        │
│   (Server)      │                                  │                 │
│                 │  1. Client registers tools       │  Tools:         │
│  await call_tool│ ◄── register: [read, write, ...] │  - FileSystem   │
│                 │                                  │  - Shell        │
│                 │  2. Gateway calls tool           │  - Custom       │
│  "read_file"    │ ──► execute: read_file          │                 │
│                 │ ◄── result: "file content"       │  execute()      │
└─────────────────┘                                  └─────────────────┘

✨ Key Features

🚀 Dead Simple - 2 Lines to Start

# Server
import remotable_function
server = await remotable_function.start_server(port=8000)

# Client
import remotable_function
client = await remotable_function.connect_client("ws://localhost:8000")

🔧 Built-in Tools

Ready-to-use tools for common operations:

  • FileSystemTool - Read, write, list files safely
  • ShellTool - Execute commands with control

🎯 Easy to Extend

class MyTool(remotable_function.Tool):
    name = "my_tool"

    async def execute(self, **kwargs):
        return {"result": "success"}

⚡ Production Ready

  • Authentication - Token-based auth
  • Compression - Automatic message compression
  • Caching - Response caching with TTL
  • Rate Limiting - Protect against abuse
  • Auto-reconnect - Handle network issues
  • TLS/SSL - Secure connections

Installation

pip install remotable-function

Or install from source:

git clone https://github.com/StarAniseStudio/remotable-function.git
cd remotable-function
pip install -e .

Quick Start

Basic Example

Server (Gateway):

import remotable_function
import asyncio

async def main():
    # Start server
    gateway = await remotable_function.start_server(port=8000)
    print("Server running on ws://localhost:8000")

    # List connected clients
    clients = gateway.list_clients()
    print(f"Connected clients: {clients}")

    # Call a tool on client
    if clients:
        client_id = list(clients.keys())[0]
        result = await gateway.call_tool(
            client_id=client_id,
            tool="read_file",
            args={"path": "/tmp/test.txt"}
        )
        print(f"File content: {result}")

    await asyncio.Event().wait()

asyncio.run(main())

Client:

import remotable_function
import asyncio

async def main():
    # Connect with built-in tools
    client = await remotable_function.connect_client(
        "ws://localhost:8000",
        tools=[
            remotable_function.FileSystemTool(),
            remotable_function.ShellTool()
        ]
    )
    print("Client connected with tools")

    # Keep running
    await client.wait_closed()

asyncio.run(main())

Advanced Usage

Configuration

Use configuration objects for production settings:

from remotable_function import Gateway, GatewayConfig

# Production configuration
config = GatewayConfig.production()
gateway = Gateway(config)
await gateway.start()

# This automatically enables:
# ✅ Authentication required
# ✅ Rate limiting (100 req/min)
# ✅ Response caching
# ✅ Message compression
# ✅ Size limits (10MB)

Custom Tools

Create your own tools:

from remotable_function import Tool

class DatabaseTool(Tool):
    """Query database tool."""
    name = "database"

    def __init__(self, connection_string):
        self.db = connect(connection_string)

    async def execute(self, query: str, **kwargs):
        return await self.db.execute(query)

# Register on client
client.register_tool(DatabaseTool("postgres://..."))

Event System

React to events:

# Server events
@gateway.on("client_connected")
def on_connect(client_id, tools):
    print(f"Client {client_id} connected with {len(tools)} tools")

@gateway.on("tool_called")
def on_tool_call(client_id, tool, args, result):
    print(f"Called {tool} on {client_id}: {result}")

# Client events
@client.on("connected")
async def on_connected():
    print("Connected to server!")

@client.on("tool_executed")
async def on_execute(tool, args, result):
    print(f"Executed {tool}: {result}")

Authentication

Secure your connections:

# Server with auth
server = await remotable_function.start_server(
    port=8000,
    auth_token="secret-key"
)

# Client with auth
client = await remotable_function.connect_client(
    "ws://localhost:8000",
    auth_token="secret-key"
)

TLS/SSL Support

For production environments:

# Server with SSL
gateway = remotable_function.Gateway(
    host="0.0.0.0",
    port=8000,
    ssl_certfile="/path/to/cert.pem",
    ssl_keyfile="/path/to/key.pem"
)

# Client connecting to wss://
client = remotable_function.Client(
    server_url="wss://example.com:8000",
    verify_ssl=True  # Default
)

Real-World Example: AI Agent Integration

# Server: AI Agent with tool execution
import remotable_function
import openai

class AIAgent:
    def __init__(self, gateway):
        self.gateway = gateway
        self.llm = openai.Client()

    async def process_request(self, user_request: str, client_id: str):
        # AI decides what tool to use
        response = self.llm.chat.completions.create(
            model="gpt-4",
            messages=[{"role": "user", "content": user_request}],
            tools=[...] # Tool descriptions
        )

        # Execute tool on client
        if response.tool_calls:
            tool_call = response.tool_calls[0]
            result = await self.gateway.call_tool(
                client_id=client_id,
                tool=tool_call.function.name,
                args=json.loads(tool_call.function.arguments)
            )

            # Process result
            return f"Executed {tool_call.function.name}: {result}"

# Start agent server
async def main():
    gateway = await remotable_function.start_server(port=8000)
    agent = AIAgent(gateway)

    # Handle user requests
    @gateway.on("client_connected")
    async def on_client(client_id, tools):
        result = await agent.process_request(
            "Read the config.json file",
            client_id
        )
        print(result)

Performance

v2.0 Improvements

  • 62.5% less code - From ~4000 to ~1500 lines
  • Unified implementation - Single code path, less overhead
  • Smart caching - ~80% reduction in repeated calls
  • Message compression - ~98% bandwidth savings for large payloads
  • Async I/O - ~130 MB/s concurrent throughput

Benchmarks

Operation Latency Throughput
Tool call (local) <10ms 100/s
Tool call (remote) <50ms 20/s
File read (1MB) <100ms 10 MB/s
File read (async) <100ms 130 MB/s

API Reference

Gateway (Server)

# Create and start
gateway = Gateway(config)
await gateway.start()

# Call tools
result = await gateway.call_tool(client_id, tool, args, timeout=30)

# List resources
clients = gateway.list_clients()
tools = gateway.list_tools(client_id)

# Events
gateway.on(event, callback)

Client

# Create and connect
client = Client(config)
client.register_tool(tool)
await client.connect()

# Properties
client.is_connected
client.list_tools()

# Events
client.on(event, callback)

Tool

class MyTool(Tool):
    name = "tool_name"

    async def execute(self, **kwargs):
        return result

Examples

Check out the /samples/ directory:

  • simple/ - Basic examples showing all patterns
  • demo/ - Full-featured demo application
  • agent_demo/ - AI agent integration example

Testing

# Run all tests
./run_tests.sh

# Run specific tests
pytest tests/unit/
pytest tests/integration/
pytest tests/security/

# With coverage
pytest --cov=remotable

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.


License

MIT License - see LICENSE for details.


FAQ

Q: How is this different from other RPC frameworks?

A: Remotable Function is specifically designed for AI agents to call tools on remote clients. It's simpler than gRPC, more focused than JSON-RPC libraries, and includes built-in tools for common operations.

Q: Is it production-ready?

A: Yes! v2.0 is stable and includes authentication, rate limiting, caching, compression, and comprehensive error handling. Many teams use it in production.

Q: Can I use it without AI/LLMs?

A: Absolutely! While designed with AI agents in mind, Remotable Function is a general-purpose RPC framework suitable for any server-client tool execution scenario.

Q: What about security?

A: Remotable Function includes authentication, TLS support, rate limiting, path traversal prevention, command filtering, and message size limits. Always review security practices for your use case.


Support


Built with ❤️ for the AI agent community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

remotable_function-2.0.0.tar.gz (55.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

remotable_function-2.0.0-py3-none-any.whl (60.2 kB view details)

Uploaded Python 3

File details

Details for the file remotable_function-2.0.0.tar.gz.

File metadata

  • Download URL: remotable_function-2.0.0.tar.gz
  • Upload date:
  • Size: 55.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for remotable_function-2.0.0.tar.gz
Algorithm Hash digest
SHA256 1f80fddabfad9cdd1d40c1d8343f3d32179cedf23e7d4c2af77b429877834add
MD5 4b4c6382dede730a7084ca32c849f100
BLAKE2b-256 841bb855e486e1c01a9d0e371a775c356c5bb98ee46b2f2d8c3ee7f9ea59b9e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for remotable_function-2.0.0.tar.gz:

Publisher: publish.yml on StarAniseStudio/remotable-function

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file remotable_function-2.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for remotable_function-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65636c8d4634f5d44fb83e265c38bc6b84d96275845565f678b2882e6cf97689
MD5 9c19dac064cc295e7bd72950f6474ad6
BLAKE2b-256 0a138d1d6a1a5e452f90c2bd5a466ff0a0c2b9b171b89b164577051bae5f04d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for remotable_function-2.0.0-py3-none-any.whl:

Publisher: publish.yml on StarAniseStudio/remotable-function

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page