codebrain_init
Initialize a .brain/context.md file for a repository. Detects the tech stack, generates an overview, and writes a pre-populated template to guide further scanning.
Instructions
Seed .brain/context.md for a repo — one-time setup before scanning.
Detects the stack (python / js / ts / rust / go / java) from marker
files, counts source-file extensions, asks Qwen for a short overview,
and writes .brain/context.md with a pre-populated template. The user
is expected to edit the ## Notes for Claude section afterwards.
Idempotent: existing context.md is not overwritten unless force=True.
Args:
root: Directory to initialise.
force: If true, overwrite an existing .brain/context.md.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| root | Yes | ||
| force | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- codebrain/server.py:284-298 (handler)MCP tool handler for 'codebrain_init'. Decorated with @mcp.tool(), it accepts a root directory and optional force flag, delegating to brain_init.init_repo().
@mcp.tool() async def codebrain_init(root: str, force: bool = False) -> str: """Seed `.brain/context.md` for a repo — one-time setup before scanning. Detects the stack (python / js / ts / rust / go / java) from marker files, counts source-file extensions, asks Qwen for a short overview, and writes `.brain/context.md` with a pre-populated template. The user is expected to edit the `## Notes for Claude` section afterwards. Idempotent: existing `context.md` is not overwritten unless `force=True`. Args: root: Directory to initialise. force: If true, overwrite an existing `.brain/context.md`. """ return await brain_init.init_repo(root, force=force) - codebrain/server.py:284-298 (schema)The tool's input schema is defined by the function signature: root (str, required) and force (bool, default False). The docstring serves as the description.
@mcp.tool() async def codebrain_init(root: str, force: bool = False) -> str: """Seed `.brain/context.md` for a repo — one-time setup before scanning. Detects the stack (python / js / ts / rust / go / java) from marker files, counts source-file extensions, asks Qwen for a short overview, and writes `.brain/context.md` with a pre-populated template. The user is expected to edit the `## Notes for Claude` section afterwards. Idempotent: existing `context.md` is not overwritten unless `force=True`. Args: root: Directory to initialise. force: If true, overwrite an existing `.brain/context.md`. """ return await brain_init.init_repo(root, force=force) - codebrain/server.py:284-284 (registration)Registration via @mcp.tool() decorator on line 284 of server.py registers 'codebrain_init' as an MCP tool.
@mcp.tool() - codebrain/brain_init.py:150-207 (helper)Core implementation: init_repo() function that creates .brain/context.md — detects stack, counts extensions, queries Qwen for overview, writes template.
async def init_repo(root: str, force: bool = False) -> str: """Create `.brain/context.md` for the repo rooted at `root`. Returns a human-readable status report ending with a recommended next-step command, or `[codebrain error] ...` on failure. """ root_path = Path(root) if not root_path.exists(): return f"[codebrain error] root not found: {root}" if not root_path.is_dir(): return f"[codebrain error] root is not a directory: {root}" brain_dir = root_path / ".brain" context_path = brain_dir / "context.md" if context_path.exists() and not force: return ( f"already initialized: {context_path} exists. " "Pass `force=True` to overwrite." ) extension_counts = count_extensions(root_path) total_source_files = sum(extension_counts.values()) top_extensions = extension_counts.most_common(TOP_EXTENSIONS_REPORTED) markers = detect_markers(root_path) stacks = infer_stacks(markers) top_dirs = list_top_level_dirs(root_path)[:TOP_DIRS_REPORTED] project_name = root_path.resolve().name overview = await _qwen_overview( project_name, stacks, markers, top_extensions, top_dirs ) generated_at = dt.datetime.now(dt.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") content = build_context_md( project_name=project_name, overview=overview, stacks=stacks, markers=markers, top_extensions=top_extensions, total_source_files=total_source_files, generated_at=generated_at, ) brain_dir.mkdir(exist_ok=True) context_path.write_text(content, encoding="utf-8") stack_report = ", ".join(stacks) if stacks else "unknown" ext_report = ", ".join(f"{ext} ({n})" for ext, n in top_extensions) or "none" return ( f"Initialized `.brain/` for {project_name}.\n\n" f"Stack: {stack_report}\n" f"Top extensions: {ext_report}\n" f"Total source files: {total_source_files}\n\n" f"Written: {context_path}\n\n" f"Recommended next step:\n" f' codebrain_scan_repo("{root_path}")' ) - codebrain/brain_init.py:33-48 (helper)Helper count_extensions() used by init_repo to tally source file extensions in the repo.
def count_extensions( root: Path, extensions: frozenset[str] | None = None, exclude_dirs: frozenset[str] | None = None, ) -> Counter[str]: """Return a counter of source-file extensions under `root`.""" ext_set = extensions if extensions is not None else DEFAULT_SOURCE_EXTENSIONS exclude_set = exclude_dirs if exclude_dirs is not None else DEFAULT_EXCLUDE_DIRS counter: Counter[str] = Counter() for dirpath, dirnames, filenames in os.walk(root): dirnames[:] = [d for d in dirnames if d not in exclude_set] for fname in filenames: suffix = Path(fname).suffix.lower() if suffix in ext_set: counter[suffix] += 1 return counter