> ## Documentation Index
> Fetch the complete documentation index at: https://retrievalcontextprotocol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Run a real RCP engine, watch it answer a query, then write your own — no models to download, nothing to configure.

RCP ships **four native SDKs** that speak the identical wire format: a
header-only C++ SDK and dependency-free Python, Node.js, and Rust SDKs. This page
takes you from zero to a working retrieval engine in two steps:

<CardGroup cols={2}>
  <Card title="1. See it run" icon="play" href="#see-it-run">
    Clone the repo and query the reference engine. Real output in under a minute.
  </Card>

  <Card title="2. Write your own" icon="pen-to-square" href="#write-your-own-engine">
    A complete, copy-paste engine you can run and then make real.
  </Card>
</CardGroup>

<Note>
  You only need **Python 3** or **Node.js** installed — the reference engine is a
  toy in-memory index with no models, no vector database, and no network calls. It
  exists to show the *protocol*, not the retrieval math.
</Note>

## See it run

The repo ships a complete example **server** (a tiny retrieval engine) and a
**client** that drives it. Running the client spawns the server, performs the
`initialize` handshake, discovers the server's capabilities, and calls three of
them — all over plain JSON-RPC on stdio.

<Steps>
  <Step title="Clone the repo">
    ```sh theme={null}
    git clone https://github.com/1ay1/rcp.git
    cd rcp
    ```
  </Step>

  <Step title="Run the example client">
    <CodeGroup>
      ```sh Python theme={null}
      python3 examples/example_client.py
      ```

      ```sh Node.js theme={null}
      node sdk/node/examples/example_client.js
      ```
    </CodeGroup>
  </Step>

  <Step title="Read the output">
    ```text theme={null}
    connected to rcp-example v1.0.0 (RCP/1)
    capabilities: ['embed', 'retrieve', 'graph']
    embed      -> 1 vector(s), dim=384
    retrieve   ->
       d1  score=0.248  The Eiffel Tower is a wrought-iron lattice tower
       d2  score=0.135  Photosynthesis converts light energy into chemic
    graph      -> {'summary': 'a global community summary would go here', 'communities': 1}
    ```

    That is a full RCP session. The client never imported the server's code — it
    only spoke the protocol. Swap the server for one backed by real embeddings and
    the client wouldn't change a line.
  </Step>
</Steps>

## Write your own engine

An RCP **server** is just a program that advertises what it can do and answers
method calls. Here is a complete engine backed by a three-document keyword index.
It runs as-is; replace the body of `search` with real vector search and nothing
else changes.

<Tabs>
  <Tab title="Python">
    <Steps>
      <Step title="Save the engine as my_engine.py">
        ```python theme={null}
        import re
        import rcp

        # A toy index: three documents ranked by keyword overlap.
        # Swap `search` for real vector search — the wire contract never changes.
        DOCS = [
            ("d1", "The Eiffel Tower is a wrought-iron tower in Paris, France."),
            ("d2", "Photosynthesis converts light into chemical energy in plants."),
            ("d3", "Mount Everest is Earth's highest mountain above sea level."),
        ]

        def toks(text):
            return set(re.findall(r"[a-z0-9]+", text.lower()))

        def search(query, k):
            q = toks(query)
            ranked = sorted(DOCS, key=lambda d: len(q & toks(d[1])), reverse=True)
            return [
                {"id": doc_id, "score": float(len(q & toks(text))), "text": text}
                for doc_id, text in ranked[:k]
                if q & toks(text)
            ]

        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):
            return {"hits": search(params["query"], params.get("k", 10))}

        s.serve_stdio()
        ```
      </Step>

      <Step title="Save a client as query.py">
        ```python theme={null}
        import rcp

        c = rcp.connect_stdio(["python3", "my_engine.py"])
        for h in c.retrieve("eiffel tower paris", k=3):
            print(h["id"], round(h["score"]), h["text"])
        ```
      </Step>

      <Step title="Run it">
        Install the SDK, then run the client (it launches the engine as a subprocess):

        ```sh theme={null}
        pip install rcp-protocol
        python3 query.py
        ```

        ```text theme={null}
        d1 3 The Eiffel Tower is a wrought-iron tower in Paris, France.
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Node.js">
    <Steps>
      <Step title="Save the engine as my_engine.mjs">
        ```js theme={null}
        import * as rcp from "rcp-protocol";

        // A toy index: three documents ranked by keyword overlap.
        // Swap `search` for real vector search — the wire contract never changes.
        const DOCS = [
          ["d1", "The Eiffel Tower is a wrought-iron tower in Paris, France."],
          ["d2", "Photosynthesis converts light into chemical energy in plants."],
          ["d3", "Mount Everest is Earth's highest mountain above sea level."],
        ];
        const toks = (s) => new Set(s.toLowerCase().match(/[a-z0-9]+/g) ?? []);

        function search(query, k) {
          const q = toks(query);
          return DOCS
            .map(([id, text]) => [[...toks(text)].filter((w) => q.has(w)).length, id, text])
            .filter(([n]) => n > 0)
            .sort((a, b) => b[0] - a[0])
            .slice(0, k)
            .map(([n, id, text]) => ({ id, score: n, text }));
        }

        const s = new rcp.Server();
        s.setInfo("my-engine", "1.0");
        s.advertise(rcp.Capability.Retrieve, { maxK: 100, modes: ["hybrid"] });
        s.on(rcp.Method.RETRIEVE, (params) => ({ hits: search(params.query, params.k ?? 10) }));
        await s.serveStdio();
        ```
      </Step>

      <Step title="Save a client as query.mjs">
        ```js theme={null}
        import * as rcp from "rcp-protocol";

        const c = await rcp.connectStdio(["node", "my_engine.mjs"]);
        for (const h of await c.retrieve("eiffel tower paris", 3))
          console.log(h.id, h.score, h.text);
        await c.shutdown();
        ```
      </Step>

      <Step title="Run it">
        Install the SDK, then run the client (it launches the engine as a subprocess):

        ```sh theme={null}
        npm install rcp-protocol
        node query.mjs
        ```

        ```text theme={null}
        d1 3 The Eiffel Tower is a wrought-iron tower in Paris, France.
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

<Note>
  **Rust and C++ follow the identical shape** — `Server::new()`, advertise a
  capability, register a handler, `serve_stdio()`. Complete, compiler-verified
  engines live at `sdk/rust/examples/example_server.rs` and
  `sdk/cpp/examples/example_server.cpp`; the [Rust](/sdks/rust) and
  [C++](/sdks/cpp) SDK pages walk through them.
</Note>

## Go further — two runnable demos

Once the basics click, two self-contained programs show off the parts of RCP
that sell it. Both run with only Python 3, no models, no config:

<CardGroup cols={2}>
  <Card title="Streaming (HTTP + SSE)" icon="wave-square" href="/features/streaming-progress">
    ```sh theme={null}
    python3 examples/example_streaming.py
    ```

    A real HTTP server streams `notifications/progress` frames as a 3-stage
    retrieve funnel fills, then the final response — over one SSE connection.
  </Card>

  <Card title="Federation (fan out + fuse)" icon="diagram-project" href="/features/federation">
    ```sh theme={null}
    python3 examples/example_federation.py
    ```

    One command spawns two independent engines, fans a query out, and fuses
    their rankings with `rcp.rrf_fuse` — origin tags and per-engine weights.
  </Card>
</CardGroup>

## What just happened

Every RCP session is the same three beats, in every language:

<Steps>
  <Step title="Initialize" icon="handshake">
    The client connects and sends `initialize`. The server replies with the
    negotiated protocol version, its name, and its **capabilities** — the exact
    set of things it can do. See [Initialization](/concepts/initialization).
  </Step>

  <Step title="Gate on capabilities" icon="filter">
    The client checks a capability (`c.supports(...)`) before calling a method.
    Calling an unadvertised capability fails **client-side, before any I/O** —
    no wasted round trip. See [Capabilities](/concepts/capabilities).
  </Step>

  <Step title="Call methods" icon="bolt">
    The client calls capability-gated methods like `retrieve` and reads back
    normalized hits. The server ran whatever pipeline it wanted behind that one
    call. See [the retrieval pipeline](/concepts/pipeline).
  </Step>
</Steps>

Notice what the client *didn't* do: it didn't know the server's language, its
index, or its ranking math. It only spoke the wire. That decoupling is the whole
point — read [Why RCP](/get-started/introduction) for the motivation.

## Installing the SDK

The SDKs are published to their registries — install the one you need:

<CodeGroup>
  ```sh Python theme={null}
  pip install rcp-protocol          # imports as `import rcp`
  ```

  ```sh Node.js theme={null}
  npm install rcp-protocol
  ```

  ```sh Rust theme={null}
  cargo add rcp-protocol             # crate is `rcp`
  ```

  ```sh C++ theme={null}
  # header-only, C++23 — via CMake:
  #   find_package(rcp CONFIG REQUIRED)
  #   target_link_libraries(app PRIVATE rcp::rcp)
  ```
</CodeGroup>

Each [SDK page](/sdks/overview) has the full install and API details.

## Where to go next

<CardGroup cols={2}>
  <Card title="The method set" icon="list" href="/methods/overview">
    Every method at a glance, and the capability that gates it.
  </Card>

  <Card title="Core concepts" icon="book-open" href="/concepts/message-format">
    The wire format, capabilities, and errors — one concept per page.
  </Card>

  <Card title="Federation & Selector" icon="diagram-project" href="/features/federation">
    Target one engine or fuse many from a single registry.
  </Card>

  <Card title="SDKs" icon="code" href="/sdks/overview">
    The full API of each native SDK.
  </Card>
</CardGroup>
