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-1.0.1.tar.gz (23.5 kB view details)

Uploaded Source

Built Distribution

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

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

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for callite-1.0.1.tar.gz
Algorithm Hash digest
SHA256 560bb4b4c5c8f8d3b1a7180cee7954370db89a86c51352a6fd927ec061cae535
MD5 933b9a4e86d11a917c4c9acbf13bed87
BLAKE2b-256 45dbd62a5ecba12419d55b67bfcfb421750a565ac51ee6bea9c3e8073eeeae85

See more details on using hashes here.

Provenance

The following attestation bundles were made for callite-1.0.1.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-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: callite-1.0.1-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-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b4bf5d18967e0c6b4cd338a9fa3ad14a16c55806fc9337411d2cbef0c8532858
MD5 8c492c19c5ce014434befd03101edb93
BLAKE2b-256 3e60c02a4d8a7de5a45f6cbd2695f5d6f7fde0a94ff92f0d420f4dfe6b2beab3

See more details on using hashes here.

Provenance

The following attestation bundles were made for callite-1.0.1-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