> 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/:
keys.json— Stored API keys (file permissions set to 0600)preferences.json— Provider, model, theme, and option choices.env— Fallback environment variable file
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_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:
-
Current working directory —
./.env(checked first) - 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 |
# 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
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
claude-sonnet-4-5-20250929(default)claude-opus-4-6claude-haiku-4-5-20251001claude-opus-4-20250514claude-sonnet-4-20250514
OpenAI
Set OPENAI_API_KEY or run bernard add-key openai <key>.
Available Models
gpt-5.2(default)gpt-5.2-chat-latesto3o3-minigpt-4o-minigpt-4.1gpt-4.1-minigpt-4.1-nano
xAI
Set XAI_API_KEY or run bernard add-key xai <key>.
Available Models
grok-4-fast-non-reasoning(default)grok-4-fast-reasoninggrok-4-1-fast-non-reasoninggrok-4-1-fast-reasoninggrok-4-0709grok-code-fast-1grok-3grok-3-mini
Switching Providers
There are three ways to switch your provider and model:
-
CLI flags —
bernard -p openai -m gpt-4o -
REPL commands —
/providerand/modelfor interactive selection -
Environment variables —
BERNARD_PROVIDERandBERNARD_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 |
/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) |
/update |
Check for and install updates |
/routines |
List all saved routines |
/create-routine |
Create a routine with guided AI assistance |
/{routine-id} |
Execute a saved routine (with optional arguments) |
/exit |
Quit Bernard (also: exit, quit, or Ctrl+C) |
/ without triggering a slash command,
escape it with a backslash: \/not-a-command
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:
rmwith-ror-fflagssudomkfs,dd- Writing to
/dev/sd* chmod 777,chown -Rreboot,shutdownsystemctl stop/disable/maskkill -9,pkill,killall
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.
- Strips navigation, footer, scripts, and other non-content elements
- HTML limit: 1 MB, output limit: 20,000 characters
- Fetch timeout: 15 seconds
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.
- Up to 4 concurrent sub-agents
- Each sub-agent gets up to 10 tool steps
- Task descriptions must be self-contained — sub-agents have no prior context
- Sub-agents can access RAG memory and persistent memory for context
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.
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).
- Minimum: 0.1 seconds
- Maximum: 300 seconds (5 minutes)
6. Routines
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)
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 |
Storage: one JSON file per routine in
~/.local/share/bernard/routines/. Maximum 100 routines. IDs must be lowercase
kebab-case (1–60 characters).
7. 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.
- The daemon runs independently of the REPL — jobs continue after you exit Bernard
- Use
/cronin the REPL to check daemon status -
If the daemon misbehaves, restart it with the
cron_bouncetool orbernard cron-bounce
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:
cron_logs_list— List recent execution runs for a specific jobcron_logs_get— Retrieve a specific log entry by ID-
cron_logs_summary— Aggregate statistics across jobs (run counts, success/error rates) -
cron_logs_cleanup— Rotate and delete old log entries to reclaim space
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 |
8. 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 |
9. 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
- 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.
-
Embedding — Facts are embedded locally using
fastembed
— no API calls required. Embeddings and facts are stored in
~/.bernard/rag/memories.json. - 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.
- Deduplication — Near-duplicate facts (similarity > 0.92) are automatically skipped to prevent bloat.
Domains
Facts are categorized into three 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 |
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:
-
/rag— Show total count, per-domain breakdown, and 10 most recent facts -
/facts— Show facts currently in the context window with similarity scores
Auto-Expiration
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.
- Max memories: 5,000
- Default TTL: 90 days
- Decay half-life: 90 days (used for capacity-based pruning when memory count exceeds the cap)
- Similarity threshold: 0.35 (minimum for retrieval)
- Disable RAG entirely by setting
BERNARD_RAG_ENABLED=false
10. Auto-Updates
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.