> User Manual

Everything you need to know about installing, configuring, and using Bernard.

1. Getting Started

Installation

Bernard requires Node.js 20.9.0 or later. Install it globally from npm:

$ npm install -g bernard-agent

After installation, the bernard command is available globally in your terminal.

First-Time Setup

On first launch, Bernard runs an interactive setup wizard that walks you through selecting a provider and entering your API key. You can also configure it manually:

# Store an API key
$ bernard add-key anthropic sk-ant-...

# Verify it's configured
$ bernard providers

All configuration is stored in ~/.bernard/:

Basic Usage

Launch the REPL by running bernard with no arguments. Type natural-language requests and Bernard will use its tools to help you:

$ bernard
bernard> what git branch am I on?
  ▶ shell: git branch --show-current
  You're on the main branch.

Type /help to see available slash commands, or /exit (or Ctrl+C) to quit.

CLI Flags

Flag Description Example
-p, --provider Override the LLM provider bernard -p openai
-m, --model Override the model name bernard -m gpt-4o
-r, --resume Resume the previous conversation bernard -r
--alert <id> Open with a cron alert context bernard --alert abc123
-V, --version Show version number bernard -V

Resuming Conversations

Use the -r flag to pick up where you left off. Bernard saves conversation history to disk between sessions and replays it on resume. A session boundary marker is injected so the agent knows prior tasks are considered complete.

$ bernard -r
# Previous conversation is restored

2. Configuration

Environment Variables

Variable Description Default
BERNARD_PROVIDER Default LLM provider anthropic
BERNARD_MODEL Default model name Provider-specific (first in list)
BERNARD_MAX_TOKENS Max tokens per AI response 4096
BERNARD_SHELL_TIMEOUT Shell command timeout (ms) 30000
BERNARD_TOKEN_WINDOW Context window size for compression (0 = auto-detect) 0
BERNARD_RAG_ENABLED Enable/disable RAG memory true
ANTHROPIC_API_KEY Anthropic API key
OPENAI_API_KEY OpenAI API key
XAI_API_KEY xAI API key

.env File Loading

Bernard loads environment variables from .env files in this priority order:

  1. Current working directory./.env (checked first)
  2. Home config~/.bernard/.env (fallback)

API keys stored via bernard add-key take precedence over .env values.

API Key Management

# Add a key
$ bernard add-key anthropic sk-ant-...

# Remove a key
$ bernard remove-key anthropic

# Check key status for all providers
$ bernard providers

Keys are stored in ~/.bernard/keys.json with file permissions set to 0600 (owner read/write only).

Options Management

Configurable options can be viewed and changed from the CLI or within the REPL (/options):

Option Env Var Default Description
max-tokens BERNARD_MAX_TOKENS 4096 Maximum tokens per AI response
shell-timeout BERNARD_SHELL_TIMEOUT 30000 Shell command timeout in milliseconds
token-window BERNARD_TOKEN_WINDOW 0 Context window size for compression (0 = auto-detect from model)
# List current option values
$ bernard list-options

# Reset a single option to default
$ bernard reset-option max-tokens

# Reset all options to defaults
$ bernard reset-options

Themes v0.3.0+

Bernard comes with six built-in color themes. Switch at any time using the /theme REPL command. Your choice persists across sessions.

Theme Description
bernard Default orange accent theme
ocean Cyan/blue palette
forest Green nature palette
synthwave Purple/pink retro palette
high-contrast Accessibility — maximized contrast
colorblind Accessibility — IBM color-blind safe palette

3. Providers

Bernard uses the Vercel AI SDK for unified access to multiple LLM providers. All tools, memory, and capabilities work identically regardless of which provider you choose.

Anthropic

Default provider. Set ANTHROPIC_API_KEY or run bernard add-key anthropic <key>.

Available Models

OpenAI

Set OPENAI_API_KEY or run bernard add-key openai <key>.

Available Models

xAI

Set XAI_API_KEY or run bernard add-key xai <key>.

Available Models

Switching Providers

There are three ways to switch your provider and model:

  1. CLI flagsbernard -p openai -m gpt-4o
  2. REPL commands/provider and /model for interactive selection
  3. Environment variablesBERNARD_PROVIDER and BERNARD_MODEL

Changes made via /provider and /model are saved to preferences and persist across sessions.

4. REPL Commands

Type slash commands in the REPL to control Bernard. Tab-completion is supported, and live hints appear as you type.

Command Description
/help Show all available commands
/clear Clear conversation history, scratch notes, and the terminal screen
/compact Compress conversation history in-place
/task Run an isolated task with structured JSON output (no history, 5-step budget)
/memory List all persistent memory keys
/scratch List session scratch note keys
/mcp Show MCP server connection status and available tools
/cron Show cron jobs, daemon status, and unacknowledged alerts
/rag Show RAG memory stats, domain breakdown, and recent facts
/facts Show RAG facts currently in the context window
/provider Interactively switch LLM provider
/model Interactively switch model for the current provider
/theme Interactively switch color theme
/options View and set options (max-tokens, shell-timeout, token-window)
/update Check for and install updates
/routines List all saved routines
/create-routine Create a routine with guided AI assistance
/create-task Create a task routine (task- prefixed) with guided AI assistance
/specialists List all saved specialists
/candidates Review auto-detected specialist suggestions
/{routine-id} Execute a saved routine (with optional arguments)
/{specialist-id} Execute a saved specialist (with a task description)
/exit Quit Bernard (also: exit, quit, or Ctrl+C)
Tip
To send a message that starts with / without triggering a slash command, escape it with a backslash: \/not-a-command
Keyboard Shortcut
Press Escape while the agent is running to interrupt the current turn and return to the prompt.

5. Tools & Capabilities

Bernard has access to a set of built-in tools that it uses autonomously based on your requests. You don't call tools directly — Bernard decides when to use them.

Shell

Executes shell commands in your current working directory. Output is captured and returned to the AI. Commands have a configurable timeout (default: 30 seconds) and a 10 MB output buffer.

Dangerous Command Detection

Bernard detects potentially dangerous commands and asks for confirmation before executing them. The following patterns trigger the safety check:

Warning
These checks are pattern-based and not exhaustive. Always review commands that Bernard proposes, especially when working with important data.

Memory

Persistent, disk-backed storage at ~/.bernard/memory/. Survives across sessions. The agent can list, read, write, and delete memory entries by key.

Use this for things like project conventions, server addresses, or personal preferences.

bernard> remember that this project uses pnpm
  ▶ memory: write "project-conventions"
  Saved to persistent memory.

Scratch

Session-only scratch notes for tracking complex task progress, intermediate findings, and working plans. Scratch notes survive context compression within a session but are discarded when the session ends. Same actions as memory: list, read, write, delete.

Web Read

Fetches a web page by URL and converts it to markdown. Useful for reading documentation, articles, Stack Overflow answers, or any public URL. Supports an optional CSS selector to extract specific content.

Sub-Agents

Bernard can delegate tasks to independent sub-agents that run in parallel. Each sub-agent gets its own AI context with access to the base tools (shell, memory, web, cron, MCP tools, etc.) but not the agent tool itself (no recursive sub-agents), and no conversation history.

bernard> check disk usage and count lines of code in parallel
  ▶ agent: "Check disk usage"
  ▶ agent: "Count lines of code"
  [sub:1] ▶ shell: df -h /
  [sub:2] ▶ shell: find . -name "*.ts" | xargs wc -l
  Disk: 42G used of 256G (16%). Code: 2,847 lines across 23 files.

Tasks v0.6.0+

Tasks are isolated, focused executions that return structured JSON output. Unlike sub-agents (which return free-form text), tasks always produce a {status, output, details?} response — making them ideal for machine-readable results, routine chaining, and conditional branching.

bernard> /task List all TypeScript files in src
  ┌─ task — List all TypeScript files in src
  ▶ shell: find src -name "*.ts" -type f
  └─ task success: Found 23 .ts files
Routine chaining
When the agent executes a routine, it can call the task tool for isolated sub-steps and use the structured JSON result to decide next steps — enabling conditional branching and output chaining within routines.

Date/Time

The datetime tool returns the current date and time information. The time_range tool calculates the duration between two military/24-hour times, and the time_range_total tool calculates the total duration across multiple military time ranges.

Wait

Pauses execution for a specified number of seconds. Useful when a task requires waiting within the current turn (e.g., server restart, build propagation).

6. Routines v0.5.0+

Routines are named, persistent multi-step workflows that Bernard can execute on demand. Use them to capture repeatable procedures — deploy scripts, release checklists, onboarding flows, code review steps — as structured instructions that Bernard follows with full tool access.

Creating Routines

There are two ways to create a routine:

Natural language

Ask Bernard to save a routine directly. The agent will use the routine tool to create it:

bernard> save a routine called "deploy-staging" that builds, pushes the docker image, and updates k8s
  ▶ routine: create { id: "deploy-staging", name: "Deploy to Staging", ... }
  ✓ Routine "Deploy to Staging" (/deploy-staging) created.

Guided creation

Use the /create-routine command for a guided, interactive experience. Bernard will ask about your workflow, clarify ambiguities, and draft a well-structured routine using prompt-engineering best practices before saving:

bernard> /create-routine
  What workflow would you like to save as a routine?
  … (interactive Q&A to build the routine)

Task routines

Use /create-task to create a routine whose ID follows a task- prefix convention. Bernard will generate an ID prefixed with task-, letting you organize quick, focused procedures under a consistent /task-{name} namespace:

bernard> /create-task
  What task would you like to save?
  … (interactive Q&A — Bernard will generate an ID prefixed with task-)

bernard> /task-run-tests
  (Bernard follows the saved task procedure)

Invoking Routines

Type /{routine-id} to execute a saved routine. Bernard follows the stored procedure with full access to all tools:

bernard> /deploy-staging
  (Bernard follows the saved deploy steps)

bernard> /deploy-staging to production instead
  (Bernard follows the routine with "to production instead" as additional context)

Routine names appear in the live autocomplete hints when you type /.

Managing Routines

The agent has a routine tool for full lifecycle management. You can also use /routines in the REPL for a quick list.

Action How
List routines /routines or ask Bernard to list them
View a routine Ask Bernard: “show the deploy-staging routine”
Update a routine Ask Bernard: “update deploy-staging to add a rollback step”
Delete a routine Ask Bernard: “delete the deploy-staging routine”
Create (guided) /create-routine
Create task (guided) /create-task (auto-prefixes ID with task-)

Storage: one JSON file per routine in ~/.local/share/bernard/routines/. Maximum 100 routines. IDs must be lowercase kebab-case (1–60 characters).

7. Specialists v0.6.0+

Specialists are reusable expert profiles — persistent personas with custom system prompts and behavioral guidelines that shape how a sub-agent approaches work. Unlike routines (which define what steps to follow), specialists define how to work.

Creating Specialists

Ask Bernard to create a specialist. The agent will use the specialist tool with an ID, name, description, system prompt, and optional guidelines:

bernard> create a specialist called "code-reviewer" that reviews code for correctness, style, and security
  ▶ specialist: create { id: "code-reviewer", name: "Code Reviewer", … }
  ✓ Specialist "Code Reviewer" (code-reviewer) created.

Each specialist has a system prompt (the persona and behavioral instructions) and optional guidelines (short behavioral rules appended as bullet points).

Invoking Specialists

Type /{specialist-id} followed by a task description to run a specialist. Bernard delegates the task to a sub-agent that uses the specialist’s system prompt and guidelines as its persona:

bernard> /code-reviewer review the changes in src/agent.ts
┌─ spec:1 [Code Reviewer] — review the changes in src/agent.ts
  ▶ shell: git diff src/agent.ts
└─ spec:1 done

Each specialist run gets its own generateText loop with a 10-step budget and no conversation history. Specialists share the concurrency pool with sub-agents and tasks (4 slots max).

Auto-Dispatch v0.7.0+

Bernard automatically detects when your message matches a saved specialist’s domain using lightweight keyword matching against specialist names and descriptions. For strong matches (score ≥ 0.8), Bernard delegates to the specialist immediately without asking. For partial matches (score 0.4–0.8), Bernard confirms with you before dispatching. This means you don’t need to remember specialist names — just describe what you need and Bernard will route to the right expert.

Managing Specialists

The agent has a specialist tool for full lifecycle management. You can also use /specialists in the REPL for a quick list.

Action How
List specialists /specialists or ask Bernard to list them
View a specialist Ask Bernard: “show the code-reviewer specialist”
Update a specialist Ask Bernard: “update code-reviewer to also check for accessibility”
Delete a specialist Ask Bernard: “delete the code-reviewer specialist”

Storage: one JSON file per specialist in ~/.local/share/bernard/specialists/. Maximum 50 specialists. IDs must be lowercase kebab-case (1–60 characters).

Specialist Suggestions v0.6.0+

Bernard automatically detects recurring delegation patterns in your conversations and suggests new specialists. Detection runs in the background when you exit a session or use /clear --save.

When candidates are detected, you’ll see a notification at the start of your next session:

  2 specialist suggestion(s) pending. Use /candidates to review.

Use /candidates to see pending suggestions with their name, description, confidence score, and reasoning. You can then accept or reject candidates conversationally (e.g., “accept the code-review candidate”), and Bernard will create the specialist for you.

Lifecycle
Candidates are auto-dismissed after 30 days if not reviewed. Up to 10 pending candidates are stored at a time. Storage: one JSON file per candidate in ~/.local/share/bernard/specialist-candidates/.

8. Cron Jobs

Bernard can schedule recurring tasks that run in the background on a timer. Cron jobs execute an AI prompt through the agent on each run, with access to all tools.

Creating Jobs

Ask Bernard to create a cron job with natural language, or the agent will use the cron_create tool with a name, cron expression, and prompt:

bernard> every hour, check if the API is healthy
  ▶ cron_create: "api-health-check"
  Schedule: 0 * * * * (every hour)
  ✓ Created cron job — runs every hour.

The cron daemon starts automatically when the first job is created.

Managing Jobs

The agent has tools for full cron job lifecycle management:

Tool Description
cron_create Create a new scheduled job
cron_list List all jobs with status
cron_get Get full details of a job including prompt and last result
cron_run Manually trigger a job immediately
cron_update Update a job's name, schedule, or prompt
cron_enable Enable a disabled job
cron_disable Disable a job without deleting it
cron_delete Permanently delete a job
cron_status Check daemon status and job counts
cron_bounce Restart the cron daemon

Daemon Management

The cron daemon is a background process that ticks and executes jobs on schedule. It starts automatically when enabled jobs exist and stops automatically when none remain.

Alerts & Notifications

Cron jobs can generate alerts (e.g., when a monitored API goes down). Alerts are stored locally and can trigger desktop notifications.

Use the --alert <id> flag to open a Bernard session with alert context pre-loaded, so you can review and act on the alert immediately.

$ bernard --alert abc123
  Alert from cron job: api-health-check
  Message: API returned 503
  Time: 2025-01-15T10:00:00Z

Logs

Cron job execution logs are stored locally. The agent has the following tools to inspect and manage past runs:

CLI Commands

Cron jobs can also be managed from the command line without entering the REPL:

Command Description
bernard cron-list List all cron jobs with status
bernard cron-run <id> Manually run a job immediately
bernard cron-delete <ids...> Delete specific jobs by ID
bernard cron-delete-all Delete all cron jobs
bernard cron-stop [ids...] Stop the daemon (no args) or disable specific jobs
bernard cron-bounce [ids...] Restart the daemon (no args) or bounce specific jobs

9. MCP (Model Context Protocol)

Bernard supports the Model Context Protocol for connecting to external tool servers. MCP servers extend Bernard with additional capabilities like file system access, database queries, API integrations, and more.

Configuration

MCP servers are configured in ~/.bernard/mcp.json. The file uses a mcpServers object where each key is the server name:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"],
      "env": {}
    },
    "remote-api": {
      "url": "https://api.example.com/mcp",
      "type": "sse",
      "headers": {
        "Authorization": "Bearer token..."
      }
    }
  }
}

Stdio Servers

Stdio-based MCP servers are spawned as child processes. Specify the command, optional args array, and optional env object:

Field Required Description
command Yes Executable to run (e.g., npx, python, node)
args No Array of command arguments
env No Environment variables to pass (merged with process env)

URL-Based Servers

URL-based servers connect over HTTP using SSE or HTTP transport:

Field Required Description
url Yes Server URL
type No Transport type: sse (default) or http
headers No HTTP headers to send with requests

You can also add URL-based servers from within a session using the mcp_add_url tool.

Commands

Command / Tool Description
/mcp REPL: Show connected servers and their tools
bernard mcp-list CLI: List configured MCP servers
bernard remove-mcp <key> CLI: Remove a configured MCP server
mcp_config Agent tool: List, add, remove, or inspect MCP servers
mcp_add_url Agent tool: Add a URL-based MCP server
Note
MCP server changes take effect after restarting Bernard. The agent will remind you to restart when adding or removing servers.

10. RAG Memory

Bernard automatically builds a long-term knowledge base from your conversations using local embeddings and retrieval-augmented generation (RAG). No data leaves your machine.

How It Works

  1. Extraction — When a session ends (and the conversation has 4 or more messages), a background worker extracts durable facts from the conversation. Each domain has a specialized extraction prompt that filters for relevant facts.
  2. Embedding — Facts are embedded locally using fastembed — no API calls required. Embeddings and facts are stored in ~/.bernard/rag/memories.json.
  3. Retrieval — On each new message, Bernard searches the RAG store using cosine similarity. The top results (up to 3 per domain, 9 total) are injected into the system prompt as recalled context.
  4. Deduplication — Near-duplicate facts (similarity > 0.92) are automatically skipped to prevent bloat.

Domains v0.3.0+

Facts are categorized into four domains, each with a specialized extraction prompt:

Domain Description Examples
tool-usage Tool Usage Patterns Command sequences, error resolutions, build/deploy workflows, git patterns
user-preferences User Preferences Communication style, workflow conventions, naming preferences, "always/never" rules
general General Knowledge Project architecture, environment info, team context, API endpoints, decisions
conversations Conversation Summaries v0.6.0+ What was discussed, approaches taken, tools/specialists/routines used, outcomes

Managing Facts

Use the CLI or REPL to browse and manage stored facts:

# List all stored facts
$ bernard facts

# Search facts by query
$ bernard facts "deployment workflow"

# Search using a file's contents as query
$ bernard facts ./src/deploy.ts

# Delete ALL facts (requires exact confirmation phrase)
$ bernard clear-facts

Both commands show facts grouped by domain and offer an interactive prompt to select and delete facts by number (e.g., 1,3,5-8).

The clear-facts command deletes all stored facts. It displays a per-domain breakdown and requires you to type the exact phrase yes, delete all facts before proceeding.

Within the REPL:

Auto-Expiration v0.4.0+

RAG memories have a configurable TTL (default: 90 days). Facts that are never accessed decay over time and are eventually pruned. Actively recalled facts have their lastAccessed timestamp refreshed, keeping them alive.

11. Auto-Updates v0.3.0+

Bernard can check for new versions on npm and install them for you. Update checks are cached for 24 hours.

# Check for updates interactively
$ bernard update

# Or from within the REPL
bernard> /update

# Enable automatic update checks on startup
$ bernard auto-update on

# Disable automatic update checks
$ bernard auto-update off

When auto-update is enabled, Bernard checks for new versions each time you start a session and notifies you if one is available.