nanobot (Agent Skills)

GitHub

Build MCP Agents

1,334 stars Go 1 Rule Files Full Docs MCP View JSON API

CLAUDE.md

# 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`