Skip to main content

Slim Redis RPC implementation

Project description

Callite

Callite is a lightweight Remote Procedure Call (RPC) library over Redis, designed for communication between components of a distributed system. It uses Redis Streams for request transport and Redis Pub/Sub for response delivery, with pickle serialization.

Installation

pip install callite

To use the MCP bridge (for AI agent integration):

pip install callite[mcp]

Prerequisites

A running Redis instance is required. You can start one locally:

docker run -d -p 6379:6379 redis:alpine

Or use the included Docker Compose setup for a full development environment:

docker-compose up

Usage

Request/Response (register + execute)

The most common pattern: the client sends a request and waits for a response.

Server:

from callite.server import RPCServer

server = RPCServer("redis://localhost:6379/0", "my_service")

@server.register
def healthcheck():
    return "OK"

@server.register
def add(a, b):
    return a + b

server.run_forever()

Client:

from callite.client import RPCClient

client = RPCClient("redis://localhost:6379/0", "my_service")

# Positional arguments
result = client.execute("add", 1, 2)
print(result)  # 3

# Keyword arguments
result = client.execute("add", a=10, b=20)
print(result)  # 30

# No arguments
status = client.execute("healthcheck")
print(status)  # "OK"

# Close when done
client.close()

execute() blocks until the server responds or the timeout is reached (default: 30 seconds). If the server-side handler raises an exception, execute() re-raises it on the client side.

Fire-and-Forget (subscribe + publish)

For one-way messages where the client does not need a response.

Server:

from callite.server import RPCServer

server = RPCServer("redis://localhost:6379/0", "my_service")

@server.subscribe
def log(message):
    print(f"Received: {message}")

server.run_forever()

Client:

from callite.client import RPCClient

client = RPCClient("redis://localhost:6379/0", "my_service")

# publish() returns immediately without waiting for a response
client.publish("log", "Something happened")

Combining Both Patterns

A single service can use both register and subscribe:

from callite.server import RPCServer

server = RPCServer("redis://localhost:6379/0", "my_service")

@server.register
def add(a, b):
    return a + b

@server.subscribe
def log(message):
    print(message)

server.run_forever()
from callite.client import RPCClient

client = RPCClient("redis://localhost:6379/0", "my_service")

# Request/response
result = client.execute("add", 3, 4)

# Fire-and-forget
client.publish("log", f"Result was {result}")

MCP Integration (AI Agent Integration)

Callite includes three MCP (Model Context Protocol) components for bridging AI agents to RPC services. All three are available from callite.mcp:

from callite.mcp import MCPBridge, MCPHTTPProxy, MCPProxy

Defining Tools and Prompts

register_tool works like register but extracts type hints and docstrings to generate rich metadata for MCP tool discovery:

from callite.server import RPCServer

server = RPCServer("redis://localhost:6379/0", "data_service")

@server.register_tool(description="Add two numbers together")
def add(a: int, b: int) -> int:
    """Add two numbers.

    Args:
        a: The first number.
        b: The second number.
    """
    return a + b

server.run_forever()

register_prompt registers prompt templates that AI agents can discover and invoke:

@server.register_prompt(description="Analyze a dataset")
def analyze(data: str, focus: str = "general") -> str:
    return f"Please analyze the following data with focus on {focus}:\n{data}"

MCPBridge

A multi-service MCP gateway that discovers callite services via their __describe__ endpoint and registers all tools, prompts, and resources as MCP primitives. Tool names are prefixed with the service name (e.g. data_service_add).

From the command line:

mcp-callite-bridge --redis redis://localhost:6379/0 --services data_service

Or programmatically:

from callite.mcp import MCPBridge

bridge = MCPBridge("redis://localhost:6379/0", ["data_service", "auth_service"])
bridge.run()  # stdio transport by default

CLI options:

Flag Description Default
--redis Redis connection URL redis://localhost:6379/0
--services Comma-separated service names (required)
--transport stdio or streamable-http stdio
--name MCP server display name callite-bridge
--timeout RPC execution timeout (seconds) 30
--queue-prefix Redis key prefix /callite

MCPHTTPProxy

An HTTP server that exposes a single callite service over Streamable HTTP. Unlike MCPBridge, tool names are not prefixed with the service name, making it suitable for single-service deployments.

from callite.client import RPCClient
from callite.mcp import MCPHTTPProxy

client = RPCClient("redis://localhost:6379/0", "data_service")
proxy = MCPHTTPProxy(client, host="0.0.0.0", port=8080)
proxy.run()  # serves at /mcp

MCPProxy

A client-side proxy that manages an external MCP server subprocess (e.g. uvx mcp-server-sqlite) over stdio and exposes its tools through a synchronous Python API. Use register_proxy on an RPCServer to re-publish external MCP tools as callite RPC methods.

from callite.mcp import MCPProxy
from callite.server import RPCServer

server = RPCServer("redis://localhost:6379/0", "my_service")

proxy = MCPProxy("uvx", ["mcp-server-sqlite", "--db-path", "test.db"])
server.register_proxy(proxy, prefix="sqlite")

server.run_forever()

The proxy auto-reconnects if the subprocess crashes, caches the tool list, and is thread-safe.

Configuration

Environment Variables

Variable Description Default
LOG_LEVEL Logging verbosity (DEBUG, INFO, ERROR, etc.) ERROR (server), INFO (client)
EXECUTION_TIMEOUT Client-side timeout in seconds for execute() 30
REDIS_URL Redis URL (used by the MCP bridge CLI) redis://localhost:6379/0

Constructor Options

RPCServer:

RPCServer(
    conn_url="redis://localhost:6379/0",
    service="my_service",
    queue_prefix="/callite",       # Redis key prefix
    xread_groupname="generic",     # Consumer group name
)

RPCClient:

RPCClient(
    conn_url="redis://localhost:6379/0",
    service="my_service",
    execution_timeout=30,          # Timeout in seconds
    queue_prefix="/callite",       # Redis key prefix
)

Docker Development

The included docker-compose.yml starts Redis, a sample server, and a sample client:

docker-compose up

This runs the example main.py (server) and healthcheck.py (client stress test with 100 concurrent threads).

License

Proprietary

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

callite-0.2.12.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

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

callite-0.2.12-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file callite-0.2.12.tar.gz.

File metadata

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

File hashes

Hashes for callite-0.2.12.tar.gz
Algorithm Hash digest
SHA256 9169a2924ebe9d43c652aa431d291a1852ce48b487a043a6050afb8d5c4ff910
MD5 4c40e327ffc4afa22c0d2066e77c3254
BLAKE2b-256 ea7681aba8130668ccb1bffe54fc5baf9944e6cc27195dcc2c8837e838d3e576

See more details on using hashes here.

Provenance

The following attestation bundles were made for callite-0.2.12.tar.gz:

Publisher: python-publish.yml on gri-ai/callite

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

File details

Details for the file callite-0.2.12-py3-none-any.whl.

File metadata

  • Download URL: callite-0.2.12-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for callite-0.2.12-py3-none-any.whl
Algorithm Hash digest
SHA256 0b2ca496da871ba7620f26c677a71269bac3eb5c16827801a7d68caf1e29ef46
MD5 6c4c7fa64a5fd70c0d4d6beca4f417c6
BLAKE2b-256 f5f9466079d20c9c9fbc24cbfec33189ca79d10491ba56db24c32e2807d9308a

See more details on using hashes here.

Provenance

The following attestation bundles were made for callite-0.2.12-py3-none-any.whl:

Publisher: python-publish.yml on gri-ai/callite

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