1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* bevy_fairy - an agentic debugger for Bevy games
* Copyright (C) 2025 ladvien
*
* Licensed under either of MIT (LICENSE-MIT) or Apache-2.0 (LICENSE-APACHE), at your option.
*
* Relicensed from GPL-3.0 when this crate was adopted into Ladvien/foundation_vs_slop: a GPL
* crate in the Bevy ecosystem cannot be adopted, and being adoptable is why it is published.
*/
//! # bevy_fairy
//!
//! An agentic debugger for Bevy games. It has two halves, and a game uses one of them while
//! an agent uses the other.
//!
//! - **The plugin** ([`plugin`]) is what a *game* links. It registers BRP methods
//! (`bevy_fairy/status`, `commands`, `screenshot`, `capture`, `input`, `scene`, `guide`,
//! `quit`) and lets the game register its own typed commands.
//! - **The server** ([`server`]) is the `bevy-fairy` binary. It speaks the Model Context
//! Protocol to a coding agent and the Bevy Remote Protocol to a running game.
//!
//! The two halves do not depend on each other. A game that has never heard of this crate can
//! still be inspected with Bevy's own BRP methods, and a game that links the plugin can be
//! driven by any BRP client, not only this one.
//!
//! ## Which feature do I want?
//!
//! | you are | you want | your dependency |
//! |---|---|---|
//! | a game | the plugin | `bevy_fairy = { version = "0.2", default-features = false, features = ["plugin"] }` |
//! | an agent | the server | `cargo install bevy_fairy` |
//!
//! A game that takes the plugin as a dependency compiles **none** of the server's
//! dependencies. That is not a promise about the future; `tests/plugin_leaf.rs` fails the
//! build if it stops being true.
//!
//! ## Quick start: a game
//!
//! ```toml
//! [dependencies]
//! bevy = { version = "0.20", features = ["default"] }
//! bevy_fairy = { version = "0.2", default-features = false, features = ["plugin"] }
//! ```
//!
//! This example belongs to the *game*, not to this crate: it uses `bevy`, which this crate
//! only depends on when the `plugin` feature is on, so it is shown rather than compiled.
//!
//! ```text
//! use bevy::prelude::*;
//! use bevy::remote::http::RemoteHttpPlugin;
//! use bevy_fairy::plugin::DebuggerPlugin;
//!
//! fn main() {
//! App::new()
//! .add_plugins(DefaultPlugins)
//! // Owns the BRP RemotePlugin. Never add a second RemotePlugin next to it.
//! .add_plugins(DebuggerPlugin::default())
//! .add_plugins(RemoteHttpPlugin::default())
//! .run();
//! }
//! ```
//!
//! `DebuggerPlugin` needs `bevy::input::InputPlugin` in the app. `DefaultPlugins` includes it;
//! `MinimalPlugins` does not.
//!
//! ## Quick start: an agent
//!
//! ```sh
//! cargo install bevy_fairy
//! bevy-fairy --help
//! ```
//!
//! Then point it at a running game. The game listens on `127.0.0.1:15702` by default; set
//! `BEVY_BRP_HOST` and `BEVY_BRP_PORT` to change that.
//!
//! ## The tool contract
//!
//! Every tool's advertised schema is generated from the same Rust type its handler parses, so
//! the two cannot drift apart. Every result carries the frame it was observed on. A value that
//! cannot be measured is refused with a reason, never answered with a plausible number.
/// The Bevy plugin: what a game links.
/// The MCP server: what an agent talks to.
// The plugin's own items are re-exported at the root, so a game writes
// `use bevy_fairy::DebuggerPlugin` rather than `use bevy_fairy::plugin::DebuggerPlugin`. The
// module is still there for anyone who wants to be explicit.
pub use ;
// The guide overlay and the capture target, which are their own features.
pub use ;
pub use ;
pub use prelude;
pub use brp as brp_messages;