diff --git a/.claude/settings.json b/.claude/settings.json index 520e716b..08f7954a 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -15,8 +15,12 @@ "Bash(flow browse:*)", "Bash(flow mcp:*)", "Bash(flow exec:*)", - "Bash(node:*)", - "Bash(npm view:*)", + "mcp__flow__run_command", + "mcp__flow__run_executable", + "mcp__flow__get_execution_logs", + "mcp__flow__sync_executables", + "mcp__flow__write_flowfile", + "mcp__flow__get_workspace_config", "mcp__flow__list_executables", "mcp__flow__get_info", "mcp__flow__get_executable", @@ -24,6 +28,31 @@ "mcp__flow__list_workspaces", "mcp__flow__execute" ], - "deny": [] + "ask": [ + "Bash(git push:*)", + "Bash(git reset --hard:*)", + "Bash(git clean:*)", + "Bash(gh pr create:*)", + "Bash(gh issue create:*)", + "Bash(gh release:*)", + "Bash(flow publish:*)", + "Bash(docker push:*)" + ], + "deny": [ + "Edit(types/**/*.gen.go)", + "Write(types/**/*.gen.go)", + "Edit(docs/cli/**)", + "Write(docs/cli/**)", + "Edit(docs/types/**)", + "Write(docs/types/**)", + "Edit(docs/public/schemas/**)", + "Write(docs/public/schemas/**)", + "Bash(flow secret get:*)", + "Bash(flow secret list:*)", + "Bash(env)", + "Bash(printenv:*)", + "Read(./.env)", + "Read(./.env.*)" + ] } } diff --git a/.claude/skills/new-command/SKILL.md b/.claude/skills/new-command/SKILL.md index a3737526..87b8ef00 100644 --- a/.claude/skills/new-command/SKILL.md +++ b/.claude/skills/new-command/SKILL.md @@ -3,19 +3,22 @@ name: new-command description: Scaffold a new Cobra CLI command following the project's patterns. disable-model-invocation: true argument-hint: " [noun] — what the command does" -allowed-tools: Bash(flow build:*) Bash(go build:*) Read +allowed-tools: mcp__flow__execute, mcp__flow__run_command, mcp__flow__list_executables, Bash(flow build:*), Bash(go build:*), Read --- Scaffold a new Cobra CLI command for: $ARGUMENTS Before writing any code, read a similar existing command to match the exact style: -- Simple verb commands: `cmd/exec.go` -- Noun/verb subcommands: any file under `cmd/workspace/` or `cmd/vault/` +- Simple verb commands: `cmd/internal/exec.go` +- Noun/verb subcommands: `cmd/internal/workspace.go` or `cmd/internal/vault.go` — each groups its + subcommands in a single file rather than a directory Then follow these patterns: -1. **File location**: `cmd/.go` for top-level, or `cmd//.go` for subcommands -2. **Command registration**: register in the parent command's `init()` or `cmd/root.go` +1. **File location**: `cmd/internal/.go`. Only `root.go` lives directly in `cmd/`; every + command handler is under `cmd/internal/`. Shared helpers go in `cmd/internal/helpers.go`, + flags in `cmd/internal/flags/`, output shaping in `cmd/internal/response/`. +2. **Command registration**: register on the parent command, or add to `rootCmd` in `cmd/root.go` 3. **Error handling**: - Runtime errors → `errhandler.HandleFatal(ctx, cmd, err)` - Flag/arg misuse → `errhandler.HandleUsage(ctx, cmd, "message", args...)` @@ -23,4 +26,5 @@ Then follow these patterns: 4. **Context**: resolve workspace context via `pkg/context` before delegating to `internal/services` 5. **Output**: respect `--output` flag (text/json/yaml) for structured responses -After scaffolding, verify it builds: `flow build binary ./bin/flow` +After scaffolding, verify it builds — prefer `mcp__flow__execute` with ref `build binary` and +argument `./bin/flow` over a raw shell call. diff --git a/.claude/skills/new-exec-type/SKILL.md b/.claude/skills/new-exec-type/SKILL.md index 86673052..444f7c21 100644 --- a/.claude/skills/new-exec-type/SKILL.md +++ b/.claude/skills/new-exec-type/SKILL.md @@ -3,26 +3,30 @@ name: new-exec-type description: Add a new executable type to the flow runner (a new kind of automation block users can define in .flow files). disable-model-invocation: true argument-hint: " — description of what this executable type does" -allowed-tools: Bash(flow generate:*) Bash(flow validate:*) Bash(flow build:*) Bash(go test:*) Read +allowed-tools: mcp__flow__execute, mcp__flow__run_command, mcp__flow__list_executables, Bash(flow generate:*), Bash(flow validate:*), Bash(flow build:*), Bash(go test:*), Read --- Add a new executable type to the flow runner for: $ARGUMENTS An "executable type" is a new automation block users can declare in `.flow` files (like `exec`, `serial`, `parallel`, `render`). Follow these steps in order: -1. **Schema first** — add the new type's fields to `types/executable/schema.yaml`. - Read the existing schema to match the structure. Run `flow generate` to regenerate `types/executable/generated.go`. +1. **Schema first** — add the new type's fields to `types/executable/executable_schema.yaml`. + Read the existing schema to match the structure. Regenerate with the `generate` executable + (`mcp__flow__execute`, ref `generate`) — it rewrites `types/executable/executable.gen.go`. + Never edit the `.gen.go` file directly. -2. **Runner handler** — create `internal/runner/.go` implementing the runner interface. - Read `internal/runner/exec.go` or `internal/runner/serial.go` as reference for the exact interface and pattern. +2. **Runner handler** — each type is its own package: create `internal/runner//.go`. + Read `internal/runner/exec/exec.go` or `internal/runner/serial/serial.go` as reference for the + exact interface and pattern. 3. **Register the type** — wire the new handler into `internal/runner/runner.go` (the dispatch table). 4. **Parser support** — update `internal/fileparser/` if needed to recognize and validate the new type during YAML parsing. -5. **Tests** — add unit tests in `internal/runner/_test.go` using Ginkgo. +5. **Tests** — add unit tests in `internal/runner//_test.go` using Ginkgo. Use `Describe`/`It`/`Entry` — never `FDescribe`/`FIt`. Cover happy path and error cases. -6. **Validate** — run `flow validate` to confirm generate, lint, and tests all pass. +6. **Validate** — run the `validate` executable (`mcp__flow__execute`, ref `validate`) to confirm + generate, lint, and tests all pass. Do not skip the schema step — editing generated files directly will cause CI to fail. diff --git a/.claude/skills/pr-ready/SKILL.md b/.claude/skills/pr-ready/SKILL.md index 24c0e842..f1c7553d 100644 --- a/.claude/skills/pr-ready/SKILL.md +++ b/.claude/skills/pr-ready/SKILL.md @@ -2,7 +2,7 @@ name: pr-ready description: Run a pre-PR readiness check and report READY or NOT READY. disable-model-invocation: true -allowed-tools: Bash(git *) Bash(flow validate:*) Bash(flow generate:*) Bash(go test:*) Read +allowed-tools: mcp__flow__execute, mcp__flow__run_command, mcp__flow__list_executables, Bash(git:*), Bash(flow validate:*), Bash(flow generate:*), Bash(go test:*), Read --- Check whether the current branch is ready to open a PR. Work through each item and report PASS or FAIL: @@ -10,7 +10,9 @@ Check whether the current branch is ready to open a PR. Work through each item a 1. **No focus markers** — `grep -rn "FDescribe\|FIt\|FEntry\|FContext\|FWhen" --include="*.go" .` Any match is a FAIL — these silently exclude all other tests in the suite. -2. **Validation passes** — run `flow validate`. All steps must pass. +2. **Validation passes** — run the `validate` executable via `mcp__flow__execute` (ref: `validate`). + All steps must pass. Use `mcp__flow__run_command` for the `git`/`grep` checks below so they land + in flow's history alongside it. 3. **No debug artifacts** — grep for `fmt.Println`, `spew.Dump` in `cmd/`, `internal/`, `pkg/`. Flag anything that looks like leftover debug output (not legitimate logging). diff --git a/.claude/skills/validate/SKILL.md b/.claude/skills/validate/SKILL.md index 0f2247c8..b1719c1d 100644 --- a/.claude/skills/validate/SKILL.md +++ b/.claude/skills/validate/SKILL.md @@ -1,16 +1,22 @@ --- name: validate description: Run flow validate and fix any failures. Invoke after completing a feature or bug fix to confirm the codebase is clean before committing. -allowed-tools: Bash(flow validate:*) Bash(flow generate:*) Bash(flow lint:*) Bash(flow test:*) Bash(go test:*) Read +allowed-tools: mcp__flow__execute, mcp__flow__run_command, mcp__flow__list_executables, mcp__flow__get_execution_logs, Bash(flow validate:*), Bash(flow generate:*), Bash(flow lint:*), Bash(flow test:*), Bash(go test:*), Read --- -Run `flow validate` — it runs these steps in order: `generate` → `lint` → `test` → `validate generated` (checks for uncommitted generated diffs in CI). +Run the `validate` executable via `mcp__flow__execute` (ref: `validate`) rather than a raw shell +call, so the run inherits workspace env/secrets and is captured in flow's history. + +It runs these steps in order: `generate` → `lint` → `test` → `validate generated` (checks for uncommitted generated diffs in CI). For each failure, diagnose and fix before moving on: -- **generate fails**: Schema syntax error in `types/*/schema.yaml` — read and fix the schema +- **generate fails**: Schema syntax error in the source schema — `types/executable/*_schema.yaml`, or `types/{config,workspace,common}/schema.yaml`. Read and fix the schema, never the `.gen.go` output. - **lint fails**: Read the golangci-lint output, fix each violation, re-run - **test fails**: Read the Ginkgo output, identify the failing spec, fix the root cause — do not skip or comment out tests -- **validate generated fails**: Generated files are out of sync — run `flow generate` and stage the regenerated files; this is always the fix +- **validate generated fails**: Generated files are out of sync — re-run the `generate` executable and stage the regenerated files; this is always the fix + +Use `mcp__flow__get_execution_logs` with `mine: true` to re-read output from a run instead of +re-running it. -Do not report done until `flow validate` exits 0 with all steps passing. +Do not report done until `validate` exits 0 with all steps passing. diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 00000000..19fec29f --- /dev/null +++ b/.mcp.json @@ -0,0 +1,9 @@ +{ + "mcpServers": { + "flow": { + "type": "stdio", + "command": "flow", + "args": ["mcp"] + } + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 0bae3c5f..5783599b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,22 +1,29 @@ # flow repo — Claude Code Context -## Project Overview - -**flow** is a workflow automation hub for organizing automation across multiple projects (workspaces) with built-in secrets, templates, and cross-workspace composition. Users define workflows in YAML flow files, discover them visually, and run them anywhere. - -This repo contains the flow CLI (Go). flow itself is used for all dev automation — build, test, generate, lint, release — via `.execs/*.flow` files. +**flow** is a workflow automation hub: automation organized across projects (workspaces), with +built-in secrets, templates, and cross-workspace composition. Users define workflows in YAML flow +files and run them anywhere. This repo is the flow CLI (Go), and flow runs its own dev automation +via `.execs/*.flow`. --- ## Critical Rules -Read these before touching any code: - -1. **NEVER edit generated files** — `types/**/*.go`, `docs/cli/*.md`, `docs/types/*.md` are all auto-generated. Edit the schema source, not the output. -2. **Run `flow generate` after any schema change** in `types/*/schema.yaml` — CI will reject uncommitted generated diffs. -3. **Remove test focus markers before committing** — `FDescribe`, `FIt`, `FEntry` are temporary debugging tools, never ship them. -4. **Never use `logger.Log().FatalErr()` in `cmd/`** — use `errhandler.HandleFatal(ctx, cmd, err)` instead. -5. **`pkg/` is the stable API surface; `internal/` is unexported** — packages in `pkg/` may be imported outside the binary; `internal/` may not. +1. **Only `*.gen.go` is generated — the rest of `types/` is hand-written.** Never edit + `types/**/*.gen.go`, `docs/cli/`, `docs/types/`, or `docs/public/schemas/`; edit the source + schema and run the `generate` executable. Sources are `types/executable/*_schema.yaml` and + `types/{config,workspace,common}/schema.yaml`. CI's `validate generated` fails on uncommitted + diffs. (Permission rules block these writes, so a failed edit here is expected, not a bug.) +2. **Remove `FDescribe`/`FIt`/`FEntry` before committing** — they silently exclude every other + spec in the suite. +3. **In `cmd/`, never `log.Fatal`, `os.Exit`, or `logger.Log().FatalErr()`** — use + `errhandler.HandleFatal(ctx, cmd, err)`, or `HandleUsage` for flag/arg misuse. +4. **`pkg/` is importable API surface; `internal/` is not.** +5. **Run work through flow's MCP tools, not raw Bash** — see Development Workflow. +6. **`go test ./...` without build tags silently skips most tests.** Use the `test` refs. +7. **Never commit directly on `main`.** Before the first commit of any change, create a branch + (`git switch -c /`) so the work lands as a PR. If you're already on `main` with + commits, move them onto a branch and reset `main` back to `origin/main`. --- @@ -24,162 +31,122 @@ Read these before touching any code: ``` flow/ -├── cmd/ # Cobra CLI entry points and command handlers -├── pkg/ # Shared, importable packages -│ ├── cache/ # Workspace and executable cache management -│ ├── cli/ # Shared CLI helpers and flag definitions -│ ├── context/ # Global app context (workspace, config, vault) -│ ├── errors/ # Typed errors with machine-readable codes -│ ├── filesystem/ # Path helpers and workspace file I/O -│ ├── logger/ # Structured logging -│ └── store/ # Persistence layer interfaces and implementations -├── internal/ # App logic NOT exported outside the binary -│ ├── fileparser/ # Flow file YAML parsing and validation -│ ├── io/ # Terminal UI and output rendering (tuikit) -│ ├── mcp/ # MCP server implementation (tools, resources) -│ ├── runner/ # Executable execution engine -│ ├── services/ # Business logic orchestration layer +├── cmd/ # Cobra CLI. Only root.go here; handlers in cmd/internal/ +├── pkg/ # Importable: cache, cli, context, errors, filesystem, +│ # imports, logger, store +├── internal/ # Not importable outside the binary +│ ├── io/ # Terminal UI and output rendering (wraps tuikit) +│ ├── mcp/ # MCP server (tools, resources) +│ ├── runner/ # Execution engine; one subpackage per executable type +│ ├── services/ # Business logic orchestration │ ├── templates/ # Workflow template expansion -│ ├── updater/ # Auto-update logic -│ ├── utils/ # Internal utilities -│ ├── validation/ # Schema and config validation -│ ├── vault/ # Secret management -│ └── version/ # Build version info -├── types/ # Generated Go types from YAML schemas — DO NOT EDIT -├── tests/ # E2E test suite (Ginkgo, -tags=e2e) -├── docs/ # Documentation source (flowexec.io) — CLI/type docs are generated -├── tools/ # Code generation and build tooling -└── .execs/ # flow dev automation executables (build, test, lint, release) +│ ├── vault/ # Thin wrapper over the vault module +│ └── ... # fileparser, updater, utils, validation, version +├── types/ # Schemas + generated types (*.gen.go) + hand-written helpers +├── tests/ # E2E suite (Ginkgo, -tags=e2e) +├── docs/ # flowexec.io source; docs/cli and docs/types are generated +└── .execs/ # flow's own dev automation ``` --- ## Architecture -**CLI execution path:** -``` -cmd/ (Cobra command) → pkg/context (workspace + config resolution) - → internal/services (business logic) → internal/runner (execution engine) - → type-specific handler in internal/runner/ -``` - -**Type generation pipeline:** ``` -types/*/schema.yaml → go-jsonschema → types/*/generated.go (DO NOT EDIT) - → internal/fileparser (YAML parsing and validation) +cmd/internal (Cobra) → pkg/context (workspace + config) → internal/services + → internal/runner → type-specific subpackage ``` -**MCP server:** -`internal/mcp` exposes the same execution pipeline to AI tools over the Model Context Protocol. The `flow mcp` command starts the server. Claude Code, Cursor, and other MCP clients can call `mcp__flow__*` tools to run executables directly. +`internal/mcp` exposes that same pipeline over the Model Context Protocol; `flow mcp` starts the +server. ---- - -## Key Technologies - -### Go CLI -- **Language**: Go 1.25+ (`go.mod:3`) -- **CLI Framework**: Cobra (`github.com/spf13/cobra`) -- **TUI**: Custom tuikit (`github.com/flowexec/tuikit`) built on Bubble Tea -- **Testing**: Ginkgo v2 BDD framework (`github.com/onsi/ginkgo/v2`) +**Scope boundary — flow is an AI *tool provider*, not an AI *consumer*.** The core exposes +deterministic capabilities (MCP server, published JSON schemas, `llms.txt`). Do not add LLM calls, +natural-language command parsing, or AI generation *into* the CLI — that puts vendor keys, +per-call cost, and non-determinism in a task runner's critical path. Anything applying a model to +flow does so from outside, via the MCP surface. Treat "add AI features to the CLI" as out of scope. --- -## Development Workflow +## Sibling Repositories -The project uses flow itself for dev automation: - -```bash -flow build binary ./bin/flow # Build the CLI binary -flow test # Run all tests (unit + e2e) in parallel -flow lint # Run golangci-lint -flow generate # Run all code generation -flow validate # Full check: generate → lint → test → diff validation -flow install tools # Install/update Go tools -flow mcp # Start the MCP server -flow browse # TUI explorer for discovering executables -``` +Two first-party modules carry much of this repo's behavior, and their seam is where most breakage +happens: -### Using flow's MCP Tools in Sessions +- **`flowexec/tuikit`** — all TUI rendering (`flow browse`, logs view, prompts). Apparent + rendering or input bugs usually live here, not in `internal/io`. +- **`flowexec/vault`** — secret storage providers (AES-256, age, keyring, env). `internal/vault` + is a thin type-alias wrapper. -During a Claude Code session, prefer MCP tools over raw shell when possible — they respect workspace config and handle environment setup: +**Read the pinned version, not a local checkout.** There are no `replace` directives, so builds +use the `go.mod` versions from `$(go env GOMODCACHE)/github.com/flowexec/@`. A +sibling working copy is often on a feature branch at a *different* version than what compiles, so +answering an integration question from it yields confidently wrong results. Use a checkout only +when deliberately co-developing upstream. Upgrades here are usually breaking-change adaptations, +not version bumps — check release notes before assuming an API is unchanged. -``` -mcp__flow__list_executables # Browse all available executables -mcp__flow__execute # Run an executable (e.g., ref: "test unit", ref: "lint") -mcp__flow__get_executable # Inspect a specific executable's definition -mcp__flow__get_info # Get current workspace context -mcp__flow__get_workspace # Get workspace details -``` +Same org, not imported: `action` (GitHub Action), `examples`, `homebrew-tap`. --- -## Testing - -- **Unit tests** (`-tags=unit`): Fast, no binary needed. `go test -race -tags=unit ./...` -- **E2E tests** (`-tags=e2e`): Require the `flow` binary on PATH. Build first: `flow build binary ./bin/flow`, then `go test -race -tags=e2e ./tests/...` -- **Focusing tests**: Use `FDescribe`/`FIt`/`FEntry` temporarily to filter — **always remove before committing** -- **Golden file updates**: Set `UPDATE_GOLDEN_FILES=true` when output changes are intentional - -Run both together: `flow test` (parallel, handles tags and env automatically) +## Development Workflow ---- +flow's MCP server is wired up in `.mcp.json`. **Prefer `mcp__flow__*` over raw Bash** so runs get +workspace env/secrets and land in flow's history. The `flow-context` skill has the full guidance. -## Code Generation +`mcp__flow__execute` runs a named executable, `run_command` a one-off shell command, +`run_executable` an inline multi-step spec. Discover names with `mcp__flow__list_executables` — +don't assume them. -The project generates code from YAML schemas. **Always edit schemas, never generated output.** +| Ref | What it does | +|-----|--------------| +| `build binary` | Build the CLI (pass `./bin/flow` as the output arg) | +| `test` | All tests (unit + e2e), parallel | +| `test unit` / `test e2e` | One suite | +| `lint` | golangci-lint | +| `generate` | All code generation | +| `validate` | generate → lint → test → generated-diff check | +| `install tools` | Install/update Go tools | -| Source | Generated output | -|--------|-----------------| -| `types/*/schema.yaml` | `types/**/*.go` | -| Go definitions | `docs/cli/*.md`, `docs/types/*.md` | +`flow browse` and `flow mcp` are interactive — they belong in a real terminal, not a tool call. -After any schema change: `flow generate` — CI runs `validate generated` which fails on uncommitted diffs. +**Testing notes:** e2e needs the binary on PATH (the `test e2e` ref builds it first). Set +`UPDATE_GOLDEN_FILES=true` when output changes are intentional. --- ## Error Handling -The CLI surfaces a structured JSON/YAML error envelope (`{"error":{"code","message","details"}}`) on stderr when the user passes `--output json` or `--output yaml`, and plain-text otherwise. Both paths go through `cmd/internal/errors.HandleFatal`. - -**In `cmd/` handlers:** -- Use `errhandler.HandleFatal(ctx, cmd, err)` — not `logger.Log().FatalErr(err)` -- Use `errhandler.HandleUsage(ctx, cmd, "...", args...)` for flag/arg misuse → callers see `INVALID_INPUT` + exit 2 +The CLI emits a structured error envelope (`{"error":{"code","message","details"}}`) on stderr for +`--output json|yaml`, plain text otherwise. Both paths go through `cmd/internal/errors.HandleFatal`. -**Typed errors in `pkg/errors/errors.go`** implement `Code() string`. Extend that set rather than returning bare `fmt.Errorf` when a stable machine-readable code matters. - -Available codes: `INVALID_INPUT`, `NOT_FOUND`, `EXECUTION_FAILED`, `TIMEOUT`, `CANCELLED`, `VALIDATION_FAILED`, `INTERNAL_ERROR`, `PERMISSION_DENIED` - ---- - -## Common Pitfalls - -- **Editing `types/*.go` directly** → CI fails on `validate generated`. Edit `types/*/schema.yaml` instead. -- **`go test ./...` without build tags** → most tests silently skip. Always use `-tags=unit` or `-tags=e2e`. -- **Running e2e tests without a built binary** → tests panic. Run `flow build binary ./bin/flow` first. -- **Leaving `FDescribe`/`FIt` in committed code** → all other tests in that suite are silently excluded. -- **Adding a Cobra command with bare `log.Fatal`** → breaks structured error output. Use `errhandler`. +Typed errors in `pkg/errors/errors.go` implement `Code() string`. Extend that set rather than +returning bare `fmt.Errorf` when a stable machine-readable code matters. Codes: `INVALID_INPUT`, +`NOT_FOUND`, `EXECUTION_FAILED`, `TIMEOUT`, `CANCELLED`, `VALIDATION_FAILED`, `INTERNAL_ERROR`, +`PERMISSION_DENIED`. --- ## PR & Code Quality -Before marking a PR ready, run `flow validate` — it runs generate, lint, test, and checks for uncommitted generated diffs in one shot. - -- Commit messages: imperative mood, lowercase, ≤72 chars (`fix: ...`, `feat: ...`, `refactor: ...`) -- No WIP code in PRs: remove all `FDescribe`/`FIt` focus markers, debug prints, and open TODOs +Run the `validate` executable before marking a PR ready. Commit messages: imperative, lowercase, +≤72 chars (`fix:`, `feat:`, `refactor:`). No focus markers, debug prints, or open TODOs. --- ## Configuration Files -- **`flow.yaml`**: Workspace configuration for the flow repo itself -- **`go.mod`**: Go dependencies and version (Go 1.25+) -- **`.execs/`**: flow dev workflow definitions (build, test, lint, release, etc.) -- **`.claude/settings.local.json`**: Claude Code permission allowlist for this project +- **`flow.yaml`** — this repo's workspace config +- **`.execs/`** — flow's dev automation definitions +- **`.mcp.json`** — registers the flow MCP server; committed so every clone gets it +- **`.claude/settings.json`** — committed permissions. `deny` blocks generated-file writes and + secret reads; `ask` gates pushes and releases. Keep absolute paths out — it ships to everyone. +- **`.claude/settings.local.json`** — gitignored, per-user. Where absolute paths belong, e.g. + `permissions.additionalDirectories` for the module cache and sibling checkouts. ## Development Setup -1. Prerequisites: Go 1.25+, flow CLI installed +1. Go 1.25+, flow CLI installed 2. `flow workspace add flow . --set` 3. `flow install tools` 4. `flow validate` diff --git a/docs/guides/ai-tools.md b/docs/guides/ai-tools.md index 5cf6c500..bb8070de 100644 --- a/docs/guides/ai-tools.md +++ b/docs/guides/ai-tools.md @@ -27,6 +27,26 @@ Add this to your MCP client configuration (Claude Code, Cursor, Cline, or any MC The server runs over stdio. That's the entire setup. +**Commit it to your repo.** Claude Code and Cursor both read a `.mcp.json` at the repository root, +so checking that file in means every teammate — and every fresh clone — gets flow's tools without +per-person setup. Put the snippet above in `.mcp.json` and commit it: + +```json title=".mcp.json" +{ + "mcpServers": { + "flow": { + "type": "stdio", + "command": "flow", + "args": ["mcp"] + } + } +} +``` + +Each user still approves the server on first use, so committing it grants no access on its own — +it just removes the setup step. Pair it with the skill in [Wiring It Up](#wiring-it-up-for-your-project) +below: the `.mcp.json` supplies the tools, the skill tells the assistant to reach for them. + ### What's available **Tools**