# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Nanobot is a standalone MCP (Model Context Protocol) host that enables building agents with MCP and MCP-UI. Unlike built-in MCP hosts in applications like VSCode, Claude, or ChatGPT, Nanobot is designed to be an open-source, deployable solution that combines MCP servers with LLMs to create agent experiences through external interfaces such as Obot. The project is written in Go. **Technology Stack:** - Go 1.26.0 with GORM (SQLite, MySQL, PostgreSQL) and goja (JavaScript runtime for hooks) ## Build and Development Commands ### Backend (Go) ```bash # Build the nanobot binary make # Run nanobot with a configuration file ./bin/nanobot run ./nanobot.yaml # Run Go tests go test ./... # Run a specific test go test ./pkg/agents -run TestName # Format Go code gofmt -w . ``` ## Architecture Overview ### Backend Architecture **Core Components:** - **Runtime (`pkg/runtime/`)** - Main orchestration layer that initializes the system. Creates and wires together the LLM client, tool service, agents, and sampling components. Manages the overall execution environment. - **Agents (`pkg/agents/`)** - Agent execution engine that handles tool mapping, request population, and agent interactions. Responsible for running agents backed by LLMs with access to tools. - **Tools Service (`pkg/tools/`)** - Central registry for tools and agents. Handles tool discovery, mapping, and execution delegation. Manages MCP server connections. - **MCP Layer (`pkg/mcp/`)** - MCP protocol implementation including sessions, clients, servers, and wire protocols. Handles both stdio and HTTP transports. Key types: - `Session` - Manages MCP session lifecycle and message routing - `Client` - MCP client implementation for connecting to servers - `Wire` - Protocol transport abstraction (stdio/HTTP) - **LLM Integration (`pkg/llm/`)** - Abstraction over different LLM providers (OpenAI, Anthropic). Routes requests to appropriate providers based on model names. Handles both completion and response APIs. - **Session Management (`pkg/session/`, `pkg/sessiondata/`)** - Manages user sessions, conversation state, and session-scoped data. Handles agent context, tool mappings, and resource mappings within sessions. Supports parent-child session relationships and database-backed OAuth token storage. - **Server Layer (`pkg/server/`)** - HTTP server handling MCP protocol over HTTP. Routes requests for initialize, tools/list, tools/call, prompts/*, resources/*, etc. Manages session creation and request routing. - **Built-in MCP Servers (`pkg/servers/`)** - Nanobot includes several built-in MCP servers: - `agent/` - Exposes individual agents as MCP servers with chat capabilities - `capabilities/` - Session initialization and capability management (workspace setup) - `meta/` - Metadata and introspection tools (list_chats, update_chat, list_agents) - `resources/` - Database-backed resource management (create_resource, delete_resource) with automatic mimetype detection - `workspace/` - Workspace and session management (create/update/delete workspaces, session reading) - **Configuration (`pkg/config/`)** - YAML-based configuration loading and validation. Supports profiles, extends (inheritance), and environment variables. See `pkg/config/schema.yaml` for the complete schema. **Key Architectural Patterns:** - **Tool Mappings** - Tools from MCP servers are mapped to agent-accessible tools. The `BuildToolMappings` method creates this mapping by resolving tool references from agents and MCP servers. - **Hooks** - Lifecycle hooks for agents and MCP servers (config, request, response). Hooks are TypeScript/JavaScript functions that can modify configuration and messages. See `hooks.ts` for type definitions. - **Sandboxing** - MCP servers can run in Docker containers for isolation. The `pkg/mcp/sandbox/` handles containerization and port mapping. Nanobot does not bundle a frontend. External UIs communicate through MCP endpoints, `/api/events`, and the browser proxy routes. ## Configuration Configuration is YAML-based. Key top-level sections: - `agents` - Define agents with their models, tools, instructions, and behaviors - `mcp-servers` - MCP server configurations (command, URL, Docker image, etc.) - `prompts` - Template definitions - `publish` - Defines what to expose when Nanobot itself acts as an MCP server - `env` - Environment variable definitions with descriptions and defaults - `auth` - Authentication configuration (OAuth, remote headers) - `profiles` - Configuration profiles for different environments - `extends` - Inherit from other configuration files Example minimal configuration: ```yaml agents: myagent: name: My Agent model: gpt-4 mcpServers: my-mcp-server mcpServers: my-mcp-server: url: https://example.com/mcp ``` ## Important Go Packages - `pkg/types/` - Core type definitions shared across the system (Config, Agent, Message, ToolCall, etc.) - `pkg/complete/` - Utility package for handling option completion and merging - `pkg/expr/` - Expression evaluation for dynamic values in configurations - `pkg/schema/` - JSON Schema validation and manipulation - `pkg/supervise/` - Process supervision for running MCP server subprocesses - `pkg/sampling/` - Handles MCP sampling requests (LLM-in-the-loop) - `pkg/envvar/` - Environment variable handling with descriptions and defaults - `pkg/cmd/` - CLI command handling (routes from `main.go`) ## Entry Points and Special Modes **Main Entry Point:** `main.go` routes commands to `pkg/cmd` **Special `_exec` Mode:** Nanobot can act as a daemon wrapper for MCP server subprocesses. When invoked with `_exec` as the first argument, it handles stdio piping and process lifecycle management for MCP servers. This enables Nanobot to supervise and manage MCP server processes. ## Testing Go tests follow standard Go conventions: - Test files are named `*_test.go` - Run all tests: `go test ./...` - Run specific package tests: `go test ./pkg/agents` - Run specific test: `go test ./pkg/agents -run TestName` ## Common Patterns ### Adding a New Agent Hook 1. Define TypeScript types in `hooks.ts` (root level) 2. Update corresponding Go types in `pkg/types/hooks.go` 3. Implement hook handling in `pkg/agents/` or relevant package 4. Hook execution is managed through `pkg/mcp/hooks.go` ### Adding a New Tool 1. Tools come from MCP servers (external or built-in servers in `pkg/servers/`) 2. Tool resolution happens in `pkg/tools/service.go` ### Working with Sessions - Sessions are scoped to MCP connections - Use `mcp.SessionFromContext(ctx)` to get current session - Session state includes tool mappings, current agent, and custom attributes - Parent sessions can be accessed via `Session.Parent` - Root session can be accessed via `session.Root()` ## MCP Protocol Notes Nanobot supports both MCP standard and MCP-UI extensions: - Standard MCP: tools, prompts, resources, sampling - MCP-UI: Elicitations (user input prompts), progress notifications, structured UI elements When implementing MCP features, refer to: - MCP types in `pkg/mcp/types.go` - Message handling in `pkg/mcp/message.go` - Protocol reference at `https://modelcontextprotocol.io` ## Code Style - Go: Follow standard Go conventions, use `gofmt`