1use std::path::Path;
5
6pub fn scaffold(force: bool) -> Result<(), String> {
7 let cwd = std::env::current_dir().map_err(|e| format!("cwd: {e}"))?;
8 write_agents_md(&cwd, force)?;
9 write_claude_mcp(&cwd, force)?;
10 println!();
11 println!(" boost installed.");
12 println!(" AGENTS.md — written");
13 println!(" .mcp.json — written (Claude Code / Cursor MCP config)");
14 println!();
15 println!(" start the MCP server:");
16 println!(" anvil mcp");
17 println!();
18 println!(" list available tools (from an MCP client):");
19 println!(" tools/list");
20 Ok(())
21}
22
23fn write_agents_md(root: &Path, force: bool) -> Result<(), String> {
24 let path = root.join("AGENTS.md");
25 if path.exists() && !force {
26 println!(" AGENTS.md already exists; skipping (re-run with --force to overwrite)");
27 return Ok(());
28 }
29 let content = AGENTS_MD_TEMPLATE;
30 std::fs::write(&path, content).map_err(|e| format!("write AGENTS.md: {e}"))?;
31 Ok(())
32}
33
34fn write_claude_mcp(root: &Path, force: bool) -> Result<(), String> {
35 let path = root.join(".mcp.json");
36 if path.exists() && !force {
37 println!(" .mcp.json already exists; skipping (re-run with --force to overwrite)");
38 return Ok(());
39 }
40 let json = serde_json::json!({
41 "mcpServers": {
42 "anvilforge-boost": {
43 "command": "cargo",
44 "args": ["run", "--quiet", "--", "mcp"],
45 "env": {}
46 }
47 }
48 });
49 let pretty = serde_json::to_string_pretty(&json).unwrap_or_else(|_| json.to_string());
50 std::fs::write(&path, pretty).map_err(|e| format!("write .mcp.json: {e}"))?;
51 Ok(())
52}
53
54const AGENTS_MD_TEMPLATE: &str = r#"# Agent guide — Anvilforge project
55
56This is an Anvilforge (Rust web framework) project. Anvilforge mirrors
57Laravel's developer experience but compiles to a single native binary.
58
59## CLI
60
61Every framework operation runs through the `anvil` binary (Anvilforge's
62equivalent of `php artisan`):
63
64```bash
65anvil --help # full command list
66anvil serve # run the dev server
67anvil dev # serve + file-watch reload
68anvil routes # list every registered route
69anvil migrate # run pending migrations
70anvil make:model Post --with-migration
71anvil make:component Counter
72anvil bench # HTTP load test
73anvil bench:micro # criterion benches
74anvil test # cargo test
75```
76
77If `anvil` is not on PATH yet, run `cargo install --path crates/smith` first,
78or use `cargo a <subcommand>` (cargo alias) / `./bin/anvil <subcommand>`
79(shell wrapper) from the workspace root.
80
81## MCP server
82
83`anvil mcp` exposes structured project introspection to AI agents via the
84Model Context Protocol. Tools include:
85
86- `list-routes` — every HTTP route the app serves.
87- `list-migrations` — applied vs. pending migrations.
88- `list-models` — every `#[derive(Model)]` cast model + its table.
89- `list-components` — every `#[spark_component]` reactive component.
90- `application-info` — environment, driver, version.
91- `get-config` — read named config values.
92- `database-schema` — live DB schema (information_schema / sqlite_master).
93- `database-query` — execute read-only SELECT statements.
94- `read-log-entries` / `last-error` — tail recent log output.
95- `search-docs` — grep `docs/` for any string.
96- `list-available-commands` — full `anvil` subcommand catalogue.
97
98The `.mcp.json` file at the project root configures this server for Claude
99Code, Cursor, Continue, and other MCP-aware editors.
100
101## Code conventions
102
103- Models live in `app/Models/` and derive `cast::Model`.
104- Spark components live in `app/Spark/` and use `#[spark_component(template = "spark/<name>")]`.
105- Migrations live in `database/migrations/` and derive `cast::Migration`.
106- Routes are registered in `src/routes/web.rs` and `src/routes/api.rs`.
107- Server config (TLS, body limits, CORS, rate limits, virtual hosts, proxy
108 rules) lives in `config/anvil.toml`.
109
110## When in doubt
111
112- Use the MCP tools to inspect the live app rather than guessing.
113- `anvil routes` is faster than grepping for routes.
114- `database-schema` is faster than reading every migration file.
115- `database-query` lets you preview data without writing throwaway code.
116"#;