Skip to main content

rcp — Retrieval Context Protocol, Python SDK

A native, pure-standard-library Python SDK for RCP — the open, versioned JSON-RPC protocol that lets any RAG engine expose embed / rerank / retrieve / graph / index / catalog, and any client consume it uniformly.

No dependencies, no compiler, no build step — just subprocess, http, socket, and json from the standard library. It speaks the exact same wire format as the C++, Node.js, and Rust SDKs, so a Python client and a C++/Node/Rust server (or vice-versa) interoperate byte-for-byte.

Install

pip install rcp-protocol

Requires Python ≥ 3.9. The import name is rcp:

import rcp

Client

Connect to any RCP server over a subprocess (stdio) or HTTP, then make typed, capability-gated calls.

import rcp

c = rcp.connect_stdio(["python3", "my_server.py"])
# or: c = rcp.connect_http("http://127.0.0.1:8000/rcp")

print(c.server(), c.protocol_version(), list(c.capabilities()))

if c.supports(rcp.Capability.Retrieve):
    for hit in c.retrieve("eiffel tower", k=3):
        print(hit["id"], hit["score"], hit["text"])

if c.supports(rcp.Capability.Embed):
    (vec,) = c.embed(["hello world"])
    print("dim", len(vec))

c.shutdown()

A call to a capability the server never advertised raises before any I/O:

try:
    c.rerank("q", ["a", "b"])
except rcp.RcpError as e:
    # e.code == rcp.Errc.CAPABILITY_MISSING  (-32003)
    ...

Client methods: embed, embed_sparse, embed_multi, rerank, retrieve, search (returns hits + usage + nextCursor), graph, transform, index_add, index_delete, feedback, memory_build, memory_recall, catalog, info, ping, call, shutdown.

Agentic & frontier RAG

The SDK carries the full spec surface for 2024–2026 RAG. retrieve accepts unit / level (granularity — chunk…subgraph…tree-node), tokenBudget (long-context packing), and sessionId (agentic trajectories) in its opts, and each returned hit preserves confidence (normalised [0,1]), unit / level, provenance (graph/tree lineage), trust (provenance + safety), and per-stage scores. Two dedicated methods complete the loop:

# RL / corrective / integrity signals back to the retriever (spec §7.16)
c.feedback([{"hitId": hit["id"], "used": True, "cited": True, "reward": 0.9}])

# MemoRAG / HippoRAG memory -> clues you fan out over retrieve/graph (spec §7.17)
mem = c.memory_build(scope="global")
for clue in c.memory_recall("my question", memory_id=mem["memoryId"])["clues"]:
    hits = c.retrieve(clue.get("query", ""), k=5, opts={"sessionId": "traj-1"})

Each surface is capability-gated (Capability.Feedback, Capability.Memory, Capability.Session) — a server that never advertised it fails fast, client-side.

Server

Expose a Python RAG engine as an RCP server.

import rcp

s = rcp.Server()
s.set_info("my-engine", "1.0")
s.advertise(rcp.Capability.Retrieve, {"maxK": 100, "modes": ["hybrid"]})

@s.on(rcp.Method.RETRIEVE)
def _(params):
    hits = my_index.search(params["query"], params.get("k", 10))
    return {"hits": [{"id": h.id, "score": h.score, "text": h.text} for h in hits]}

s.serve_stdio()          # or: s.serve_http(8000)

The Server owns the initialize handshake, capability gating, JSON-RPC framing and batching, and error mapping. It answers initialize / info / ping / shutdown itself; a gated call before initialize is -32001, an unadvertised or unimplemented method is -32003, an unknown method is -32004.

Selecting a backend

Pick one engine from a registry — by id, by required capability, or by priority with liveness fallback. Connection is lazy.

sel = rcp.Selector.loads('''{
  "engines": [
    {"id": "docs", "transport": "stdio", "command": ["python3", "server.py"], "priority": 10},
    {"id": "web",  "transport": "http",  "url": "http://127.0.0.1:8000/rcp",   "priority": 5}
  ]
}''')

c = sel.select_capable(rcp.Capability.Retrieve)

Federation fusion & the vector codec

Merge per-engine ranked lists with the reference Reciprocal Rank Fusion (spec §16.3) — deterministic tie-break, richest-body dedup, origin tags in meta.engine:

fused = rcp.rrf_fuse({"dense": dense_hits, "sparse": sparse_hits}, k=10,
                     weights={"dense": 1.0, "sparse": 0.7})
# or rcp.weighted_fuse(...) when engine scores are comparable

Encode embeddings compactly for the wire (spec §7.3.1, ~4× smaller than JSON numbers):

payload, meta = rcp.encode_vectors(vectors, "f32-base64")
vectors = rcp.decode_vectors(payload, meta["encoding"], meta["dimension"])

Streaming (SSE)

A generator handler yields rcp.Progress events and returns the final result; serve_http streams notifications/progress frames then the response over one text/event-stream connection (spec §9/§13), and the same handler answers a plain unary POST:

def retrieve(params):
    yield rcp.Progress(0.5, "recall")
    yield rcp.Progress(1.0, "rerank")
    return {"hits": hits}

s.advertise(rcp.Capability.Streaming)
s.stream("retrieve", retrieve)

Examples & tests

python3 examples/example_server.py            # stdio (default)
python3 examples/example_server.py --http 8000
python3 examples/example_client.py            # drives the example server
python3 examples/example_streaming.py         # HTTP+SSE progress, end to end
python3 examples/example_federation.py        # two engines fanned out + RRF-fused

python3 test_bindings.py                      # smoke test incl. Python client ↔ C++ server

License

MIT © 2026 Ayush Bhat.

Metadata

Release files for rcp-protocol 1.0.1

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

Source distribution (sdist)

Source distribution for rcp-protocol 1.0.1
File Size Uploaded
rcp_protocol-1.0.1.tar.gz 28.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rcp-protocol 1.0.1
File Interpreter ABI Platform
rcp_protocol-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 59.3 kB

Release files / rcp_protocol-1.0.1.tar.gz

Download URL rcp_protocol-1.0.1.tar.gz
Size 28.9 kB
Tags Source
SHA-256 checksum
How to use checksums
31cf5c6d368a1d4afa50a25f8ca9cf83f26247e229bec1866178d9aeb665ce59
BLAKE2b-256 checksum
How to use checksums
114806b34c5b9a53a90f79fef6853d17f9ed6486359d2a13e9cdae82d04833cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Release files / rcp_protocol-1.0.1-py3-none-any.whl

Download URL rcp_protocol-1.0.1-py3-none-any.whl
Size 30.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d15f8b7873512f86478e11f25ce400d32213367d8fcb28e77f82fce18c5a281
BLAKE2b-256 checksum
How to use checksums
1067056b6854080f682f10d5b947ac276a308563d55411c8bfa85cc3593e3860
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

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