Simple and efficient RPC framework for AI agents
Project description
Remotable Function
Simple and efficient RPC framework for AI agents
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 patternsdemo/- Full-featured demo applicationagent_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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f80fddabfad9cdd1d40c1d8343f3d32179cedf23e7d4c2af77b429877834add
|
|
| MD5 |
4b4c6382dede730a7084ca32c849f100
|
|
| BLAKE2b-256 |
841bb855e486e1c01a9d0e371a775c356c5bb98ee46b2f2d8c3ee7f9ea59b9e4
|
Provenance
The following attestation bundles were made for remotable_function-2.0.0.tar.gz:
Publisher:
publish.yml on StarAniseStudio/remotable-function
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
remotable_function-2.0.0.tar.gz -
Subject digest:
1f80fddabfad9cdd1d40c1d8343f3d32179cedf23e7d4c2af77b429877834add - Sigstore transparency entry: 745719429
- Sigstore integration time:
-
Permalink:
StarAniseStudio/remotable-function@37073af7ce546fe1b158be6b45641749ef9d2b0a -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/StarAniseStudio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@37073af7ce546fe1b158be6b45641749ef9d2b0a -
Trigger Event:
release
-
Statement type:
File details
Details for the file remotable_function-2.0.0-py3-none-any.whl.
File metadata
- Download URL: remotable_function-2.0.0-py3-none-any.whl
- Upload date:
- Size: 60.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65636c8d4634f5d44fb83e265c38bc6b84d96275845565f678b2882e6cf97689
|
|
| MD5 |
9c19dac064cc295e7bd72950f6474ad6
|
|
| BLAKE2b-256 |
0a138d1d6a1a5e452f90c2bd5a466ff0a0c2b9b171b89b164577051bae5f04d0
|
Provenance
The following attestation bundles were made for remotable_function-2.0.0-py3-none-any.whl:
Publisher:
publish.yml on StarAniseStudio/remotable-function
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
remotable_function-2.0.0-py3-none-any.whl -
Subject digest:
65636c8d4634f5d44fb83e265c38bc6b84d96275845565f678b2882e6cf97689 - Sigstore transparency entry: 745719511
- Sigstore integration time:
-
Permalink:
StarAniseStudio/remotable-function@37073af7ce546fe1b158be6b45641749ef9d2b0a -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/StarAniseStudio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@37073af7ce546fe1b158be6b45641749ef9d2b0a -
Trigger Event:
release
-
Statement type: