# Plexus RPC Overview

> For AI agents and developers building services on the Plexus RPC stack.

## What is Plexus RPC?

Plexus RPC is a **self-describing, streaming-first** remote procedure call protocol built on **JSON-RPC 2.0 over WebSocket**. Every service exposes JSON schemas at runtime, enabling dynamic discovery without code generation or static configuration.

**Stack position:**
```
┌─────────────────────────────────────────┐
│  Synapse CLI (Haskell)                  │  ← Human/agent interface
├─────────────────────────────────────────┤
│  Your Microservice                      │  ← You are here
│  (DynamicHub + Activations)             │
├─────────────────────────────────────────┤
│  plexus-transport v0.1.7                │  ← WebSocket, stdio, MCP HTTP
├─────────────────────────────────────────┤
│  plexus-core v0.3.12                    │  ← Activation trait, DynamicHub, schemas
├─────────────────────────────────────────┤
│  plexus-macros v0.3.9                   │  ← Procedural macros for codegen
├─────────────────────────────────────────┤
│  jsonrpsee v0.26                        │  ← JSON-RPC 2.0 server
└─────────────────────────────────────────┘
```

**Key properties:**
- **Self-describing**: Services expose JSON schemas for all methods at runtime
- **Streaming-first**: All methods return `Stream<Item = T>`, wrapped with metadata by the framework
- **Tree-structured**: Methods organize hierarchically via dot-separated paths (e.g., `substrate.echo.once`)
- **Caller-wraps**: Activations return plain domain events; the framework adds provenance, timestamps, and Done markers

## Architecture Layers

### plexus-core (lowest level)

Path: `plexus-core/`

Defines the `Activation` trait, `DynamicHub` (the routing hub), `PlexusStream`, schema types, and streaming helpers. This is the foundation everything else builds on.

### plexus-macros

Path: `plexus-macros/`

Procedural macros (`#[hub_methods]`, `#[hub_method]`) that generate:
- `Activation` trait implementation
- RPC trait and server implementation (jsonrpsee)
- Method enum with JSON schemas
- `into_rpc_methods()` for transport integration

### plexus-transport

Path: `plexus-transport/`

`TransportServer` builder that hosts any `Activation` over:
- **WebSocket** (JSON-RPC 2.0, primary transport)
- **Stdio** (line-delimited JSON-RPC, MCP-compatible)
- **MCP HTTP** (with SSE streaming)

## Dependencies (Cargo.toml)

```toml
[dependencies]
plexus-core = "0.3"
plexus-macros = "0.3"
plexus-transport = "0.1"

tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
async-stream = "0.3"
async-trait = "0.1"

serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
schemars = { version = "1.1", features = ["derive", "uuid1"] }

jsonrpsee = { version = "0.26", features = ["server", "macros"] }
uuid = { version = "1.6", features = ["v4", "v5", "serde"] }
chrono = { version = "0.4", features = ["serde"] }
tracing = "0.1"
anyhow = "1.0"
```

## Error Handling

```rust
pub enum PlexusError {
    ActivationNotFound(String),
    MethodNotFound { activation: String, method: String },
    InvalidParams(String),
    ExecutionError(String),
    HandleNotSupported(String),
    TransportError(TransportErrorKind),
}
```

From within a streaming method, yield errors as events in your domain enum, or use `error_stream()` for fatal errors at the dispatch level.

## Checklist: New Microservice

1. **Create event types** — `#[derive(Serialize, Deserialize, JsonSchema)]` enum with `#[serde(tag = "type", rename_all = "snake_case")]`
2. **Create activation struct** — `#[derive(Clone)]` with `pub fn new() -> Self`
3. **Add `#[hub_methods]`** — on the impl block with namespace, version, description
4. **Add `#[hub_method]`** — on each method, returning `impl Stream<Item = YourEvent>`
5. **Register in DynamicHub** — `.register(YourActivation::new())`
6. **Set up TransportServer** — choose WebSocket, stdio, or MCP HTTP
7. **Test with Synapse** — `synapse -P <port> <namespace> <method> --params`

## Testing with Synapse CLI

```bash
# List available activations
synapse -P 4444 myservice

# Show methods for echo
synapse -P 4444 myservice echo

# Invoke a method
synapse -P 4444 myservice echo once --message "Hello"

# Get raw schema
synapse -P 4444 myservice echo --schema

# JSON output (for piping)
synapse -P 4444 --json myservice echo once --message "Hello"
```

## Key Source Paths

| Component | Path |
|-----------|------|
| Activation trait + DynamicHub | `plexus-core/src/plexus/plexus.rs` |
| Streaming helpers | `plexus-core/src/plexus/streaming.rs` |
| Schema types | `plexus-core/src/plexus/schema.rs` |
| PlexusStreamItem types | `plexus-core/src/plexus/types.rs` |
| Bidirectional channels | `plexus-core/src/plexus/bidirectional.rs` |
| hub_methods macro entry | `plexus-macros/src/lib.rs` |
| Activation codegen | `plexus-macros/src/codegen/activation.rs` |
| Method enum codegen | `plexus-macros/src/codegen/method_enum.rs` |
| TransportServer builder | `plexus-transport/src/server.rs` |
| WebSocket transport | `plexus-transport/src/websocket.rs` |
| Stdio transport | `plexus-transport/src/stdio.rs` |
| Echo plugin (reference) | `plexus-substrate/src/activations/echo/` |
| Health plugin (manual impl) | `plexus-substrate/src/activations/health/` |
| Bash plugin (real-world) | `plexus-substrate/src/activations/bash/` |
| Substrate builder | `plexus-substrate/src/builder.rs` |
| Substrate main.rs | `plexus-substrate/src/main.rs` |
| Synapse CLI entry | `synapse/app/Main.hs` |
| Synapse effect stack | `synapse/src/Synapse/Monad.hs` |
| Synapse transport | `synapse/src/Synapse/Transport.hs` |
| Synapse navigation | `synapse/src/Synapse/Algebra/Navigate.hs` |
| Synapse IR types | `synapse/src/Synapse/IR/Types.hs` |
| Synapse IR builder | `synapse/src/Synapse/IR/Builder.hs` |
| Synapse param parsing | `synapse/src/Synapse/CLI/Parse.hs` |
| Synapse templates | `synapse/src/Synapse/CLI/Template.hs` |
| Synapse discovery | `synapse/src/Synapse/Backend/Discovery.hs` |
| Synapse bidir | `synapse/src/Synapse/Bidir.hs` |
