# cdp-protocol
`cdp-protocol` exposes the raw, type-safe Chrome DevTools Protocol (CDP) surface area for Rust. The crate is auto-generated from the Chrome 140.0.7339.186 protocol definition and is used by `cdp-core`, but it can also be consumed directly anywhere you need fine-grained CDP access.
## Highlights
- **Complete domain coverage** – Every domain published by Chrome at the tracked version is generated into its own Rust module.
- **Strongly typed commands & events** – Each command implements `cdp_protocol::types::Method`, and every CDP event is represented by `cdp_protocol::types::Event` for ergonomic deserialization.
- **Serde-first design** – Structs derive `Serialize`/`Deserialize`, so you can plug them into any transport that speaks JSON over WebSocket or Chrome's browser protocol pipes.
- **Version-locked output** – Code is produced by the internal `gen_cdp` generator, keeping the crate synchronized with official Chrome releases.
- **Zero runtime dependencies** – Aside from `serde`/`serde_json`, no extra dependencies are pulled into your project.
## Installation
Add the crate to your `Cargo.toml`:
```toml
[dependencies]
cdp-protocol = "0.1.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
```
## Sending commands
Each command struct can be turned into a JSON-RPC payload via the `Method` trait:
```rust
use cdp_protocol::{page, types::Method};
use std::io::Write;
fn navigate<W: Write>(socket: &mut W) -> anyhow::Result<()> {
let navigate = page::Navigate {
url: "https://example.com".into(),
referrer: None,
transition_type: None,
frame_id: None,
referrer_policy: None,
};
let call = navigate.to_method_call(1); // 1 == JSON-RPC id; track however you prefer
let payload = serde_json::to_vec(&call)?;
socket.write_all(&payload)?;
socket.write_all(b"\n")?; // depends on your transport
Ok(())
}
```
The `types::MethodCall` helper simply wraps the command with the CDP method name and call id. You can now forward the serialized payload to a WebSocket connected to Chrome's remote-debugging endpoint.
## Listening for events
Incoming JSON messages can be parsed into the unified `Event` enum, making it easy to fan out processing logic:
```rust
fn handle_event(raw: &str) -> anyhow::Result<()> {
match serde_json::from_str::<cdp_protocol::types::Event>(raw)? {
cdp_protocol::types::Event::PageLoadEventFired(evt) => {
println!("Page load fired at {:?}", evt.params.timestamp);
}
cdp_protocol::types::Event::NetworkRequestWillBeSent(evt) => {
let url = &evt.params.request.url;
println!("Network request: {url}");
}
_ => {}
}
Ok(())
}
```
Because each domain module re-exports its event payloads, you can drill into strongly typed fields instead of handling raw JSON maps.
## Relationship to `cdp-core`
`cdp-core` builds a high-level browser automation API on top of this crate. If you need a batteries-included experience (page automation, element handles, networking utilities, etc.), reach for `cdp-core`. If you want to craft custom CDP flows, integrate with bespoke transports, or experiment with upcoming protocol changes, `cdp-protocol` lets you work directly with low-level commands.
## Updating the protocol definition
The source files in `src/` are generated by the internal `gen_cdp` tool. When Chrome publishes a new stable protocol JSON, re-run the generator and commit the refreshed modules. Keeping the generator inputs in sync ensures the crate's `types::Event` and domain modules line up with Chrome's expectations.
## Contributing & License
- Contributions are welcome—see the repository-wide `CONTRIBUTING.md` for guidelines.
- `cdp-protocol` is distributed under the [MIT License](../../LICENSE).