Skip to content

Latest commit

Β 

History

343 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Kevin

Agent Kevin 🍌

Your personal AI assistant, as a Claude Code plugin. One markdown folder, one plugin, a brain that learns who you are session after session.

LicenseΒ  Claude Code pluginΒ  macOS testedΒ  Made by AgentLayer


πŸ€– What is Kevin?

Kevin is a portable, file-based personal AI assistant that runs inside Claude Code. Everything that makes Kevin Kevin, personality, memory, knowledge, projects, tasks, lives in your own directory as plain markdown. Any AI can read it. You can browse it in Obsidian or Finder. If you ever want to leave Claude Code, you take the folder and go.

This isn't a chat wrapper. It's an operating system for personal AI:

  • A 51-tool MCP server for tasks, knowledge compilation, reports, worktrees, database queries, GitHub review, search, page-speed, Playwright, and Google Search Console.
  • A 32-skill library covering onboarding, project lifecycle, daily/weekly/monthly cadences, trip planning, worktree setup, API-request drafting, and read-only SEO auditing.
  • A knowledge pipeline that turns every conversation into structured, queryable memory.
  • A skill-pack system for opt-in capabilities (SEO, Browser) and an install-on-demand bridge to community skill libraries via skills.sh.
  • Bundled behaviour is disable-model-invocation: true β€” Kevin only acts when you ask, never spontaneously. The exceptions are six helper skills Kevin can run on its own when you ask: dashboard (refresh the mission-control page), where-am-i (session radar), find-session (locate a past session by what it worked on and hand back its resume command), standup (your last 24h as did / next / blocked), api-collections (draft API requests for you to fire in your API client β€” authoring only, never sends), and roadmap (wizard-built roadmap surfaces β€” always interviews before writing); none mutates knowledge or task state.

Kevin is named after the loyal minion. Helpful, enthusiastic, a little nerdy.


⚑ Quick start

πŸ“¦ Prerequisites β€” what to install first

Kevin runs on a small, bun-first toolchain (no Node.js). Install these once:

Tool Why you need it Get it
Claude Code The host Kevin plugs into docs.claude.com
Bun β‰₯ 1.1 Runtime for the MCP server, hooks, and the kevin CLI bun.sh
Git Cloning, the plugin marketplace, and Kevin's git-activity awareness git-scm.com
Python 3 (optional, recommended) Kevin is TypeScript-first, but some tooling and integrations still reach for Python python.org
Obsidian (optional) Browse the knowledge graph; opens dashboard links rendered, not raw obsidian.md

bun and git are hard requirements β€” /agent-kevin:init checks for them up front and stops with an install pointer if either is missing. Chromium (for the Playwright tools) is not a manual step β€” bun install downloads it into the plugin via a postinstall hook.

On Windows? Kevin runs on native Windows through Git Bash β€” the shell Claude Code already uses for its Bash tool, which supplies the POSIX environment Kevin's hooks, MCP server, and per-skill bash permission patterns expect. Install the bun + git toolchain (above) for Windows, then run Claude Code + /agent-kevin:init as usual. WSL2 is also fully supported if you prefer a full Linux userland: install WSL2 (wsl --install in an admin PowerShell, then reboot), put the toolchain inside the distro, and launch Claude Code from there. Either works β€” native is lighter; WSL2 is closer to a Linux production target. Native Windows has a few rough edges to know about (MSYS path-mangling on colon-paths, no OS sandbox, and a couple of pack-gated skills that assume tools Git Bash lacks like jq); see Platform support.

Option A: Install via /plugin (recommended once published)

First, cd to wherever you want Kevin's brain to live and launch Claude Code:

mkdir -p ~/Documents/Agents/Kevin && cd ~/Documents/Agents/Kevin
claude

Inside the session, register the marketplace and install the plugin:

/plugin marketplace add github:AgentLayer1/agentlayer-claude-marketplace
/plugin install agent-kevin@agentlayer
/exit

Then enter claude again and run /agent-kevin:init to scaffold your home (see Onboarding below).

Option B: Local development install

The plugin ships its own embedded marketplace (.claude-plugin/marketplace.json), so a local clone of agent-kevin is itself a marketplace you can register.

# Clone the plugin
git clone https://github.com/AgentLayer1/agent-kevin ~/Developer/agent-kevin

# One-time MCP-server deps install (~150MB, pulls chromium for Playwright)
cd ~/Developer/agent-kevin/mcp-server && bun install

# cd to wherever you want Kevin's brain to live and launch Claude Code
mkdir -p ~/Documents/Agents/Kevin && cd ~/Documents/Agents/Kevin
claude

Inside the session, register the local marketplace and install:

/plugin marketplace add ~/Developer/agent-kevin
/plugin install agent-kevin@agentdev-kevin
/exit

Then claude again and /agent-kevin:init as above.

Already have a CLAUDE.md in the directory? Kevin writes its operating manual to CLAUDE.local.md instead and leaves yours alone. Both files load at session start.

Updating an installed plugin

Plugin updates are not automatic for third-party marketplaces β€” Kevin ships an explicit version in plugin.json, so you pull new releases on your own. Inside a session:

/plugin marketplace update agentlayer    # refresh the catalog
/plugin update agent-kevin@agentlayer     # pull the new version
/reload-plugins                           # activate without restarting

(Local dev install? Swap agentlayer for agentdev-kevin.)

Prefer hands-off? Turn on auto-update via /plugin β†’ Marketplaces tab β†’ select the marketplace β†’ Enable auto-update. Each launch then refreshes the catalog and pulls any new version automatically.

⚠️ Auto-update is a global toggle per marketplace, not per plugin β€” enabling it updates every plugin installed from that marketplace at startup, not just Kevin. Leave it off if you want to control exactly when each plugin changes.

Then apply the home-side changes: /agent-kevin:upgrade

/plugin update refreshes the plugin code only β€” it never touches your home's scaffolded files (CLAUDE.md, SOUL.md, settings, rules) or runs bun install. After pulling a new version, run /agent-kevin:upgrade to reconcile your home:

/agent-kevin:upgrade

See How upgrades & releases work for the full process.


πŸ’‘ Why you'll want one

graph LR
    A[Sessions] -->|capture| B[Knowledge]
    B -->|informs| C[Projects]
    C -->|generate| D[Results]
    D -->|feed back into| A
Loading

The flywheel. Every session makes Kevin smarter. Every project generates knowledge. Every piece of knowledge makes the next session better.

  • 🧠 Memory that compounds. The SessionEnd and PreCompact hooks copy your conversation to knowledge/raw/sessions/. The knowledge-compile skill distils those raw logs into structured wiki articles (user profile facets, cross-cutting concepts, active memory). On your next launch, the compiled knowledge loads as @-imports before you've typed a word. This loop is the entire evolution story.
  • πŸ“‹ Project lifecycles, not just chats. Spin up projects with /agent-kevin:create-project, track tasks with status / priority / dependencies, archive cleanly when they're done. Markdown files. Obsidian-friendly. Git-friendly.
  • πŸŒ… Daily, weekly, monthly cadences. Morning briefings, evening wraps, weekly goals, monthly reviews. Built-in skills, run on demand.
  • πŸ” SEO that audits itself. Plug GSC + PageSpeed + SerpAPI, run /agent-kevin:google-search-audit, get a ranked-by-impact diagnostic report.
  • 🌐 Web at your fingertips. Bundled Playwright + chromium for screenshots, styled PDFs (markdown + mermaid rendered), URL β†’ clean Markdown (handles SPAs), scripted page recordings. Optional Perplexity for live web research.
  • 🏠 Multiple homes, multiple personas. One personal Kevin, one work Kevin, one SEO Kevin. Same plugin, different brains.
  • βœ… Subscription-billed, not API-billed (see Claude Code Billing).

πŸ›°οΈ The Agent OS Dashboard

Kevin Agent OS dashboard

There's a lot going on inside an agent β€” and even more going on in your life around it. The Agent OS dashboard shows both: your life through Kevin's eyes. Every /agent-kevin:sync regenerates <HOME>/dashboard.html β€” a dark mission-control page you open like any file (no server, no service). A left sidebar carries Kevin's wordmark, the page nav, your avatar, and the system-health badge; the pages are operator-first:

  • Today β€” a time-aware greeting and stat strip, with sub-tabs: the plan (focus, next 7 days, waiting-on), your weekly/monthly/yearly goals, a "today so far" activity trail (sessions, tasks touched, commands run, output produced), and a News tab of headlines harvested from recent briefings.
  • Tasks β€” the agenda grouped by due horizon (overdue β†’ today β†’ this week β†’ this month β†’ later) and a needs-attention view (blocked with reasons, going stale).
  • Projects β€” color-coded project cards with description, done/total progress, and last-updated; click one to expand its tasks grouped by status, plus a 🧭 link to the project's own roadmap when it keeps one.
  • Sessions β€” your real working sessions (command runs filtered out) from the last 30 days, grouped by day with longer summaries, subtle turn counts, and the working directory only when it isn't the agent home.
  • Brain β€” active memory threads and recent decisions, the Memory tab (daily memory with summaries, learnings, pending), concept articles, the compile pipeline, and the last lint run.
  • Reports β€” everything Kevin has produced, grouped by day, skill chips color-coded, every title clickable.
  • Capabilities β€” a cheatsheet of starter recipes, every skill as a tile (with an auto badge when the model may self-invoke it), every MCP tool, the full kevin CLI command reference, and hook wiring. The "what can I ask Kevin?" page.
  • Profile β€” the operator page: your avatar, timezone, and the compiled profile rendered section by section (web links open in new tabs).
  • Persona β€” Kevin's page: avatar, vibe, bio, core role, and soul traits rendered from IDENTITY.md and SOUL.md.
  • System β€” sub-tabs for context assembly, settings (per-scope layers with their allow/deny/env contributions), and a scrollable log tail.

A Surfaces group appears in the sidebar for the standalone pages Kevin builds alongside the dashboard, discovered by convention and never configured: <HOME>/roadmap.html (your north star) leads, followed by any projects/<slug>/roadmap.html or projects/<slug>/dashboard.html.

Pages and sub-tabs deep-link by hash (dashboard.html#work/projects), text filters narrow tasks/sessions/skills/tools/reports live, every project carries a stable color across its badges, and the pulsing health badge jumps you to whatever needs attention. Markdown links (tasks, reports, concepts, memory) open through a configurable opener app so they land rendered and editable rather than downloading as raw text β€” obsidian://open?path={path}&paneType=tab by default (the paneType=tab opens notes in a new Obsidian tab so the dashboard stays put); set the MARKDOWN_URL env var in .claude/settings.local.json to point elsewhere, e.g.:

{ "env": { "MARKDOWN_URL": "markedit://open?path={path}" } }

How to refresh it: every /agent-kevin:sync does it automatically; /agent-kevin:dashboard rebuilds and opens it; kevin dashboard does the same from a terminal; the dashboard MCP tool is the programmatic hook. Every refresh also rebuilds projects/TASKS.md (and vice versa) β€” the two derived views always regenerate together. It's a snapshot, not a live app β€” the generated timestamp is in the footer. The file is fully self-contained and makes zero external requests: no CDN, no webfonts, no analytics. It renders identically offline, nothing on it leaves your machine, and regenerating it never mutates state.

⚠️ Privacy note: dashboard.html sits at your HOME root and reflects your tasks, knowledge stats, and (redacted) settings. If you ever publish that repo β€” e.g. enable GitHub Pages on it β€” this page publishes too. Keep agent homes private.


🎬 Onboarding

> /agent-kevin:init

❓ What should this agent be called? (default: Kevin β€” plus emoji + avatar if you rename)
❓ Its character (SOUL): accept default, or refine?
❓ Its role (IDENTITY): general / coding / research / planning / custom?
❓ Your name and home timezone?
❓ Paste any URLs about you (blog, LinkedIn, GitHub, etc.) so Kevin seeds your profile
❓ Paste a path or URL for your avatar (optional, gets linked to knowledge/user/profile.md)
❓ Should knowledge/ and projects/ live somewhere else? (e.g. ~/Documents/Agents/Kevin-Knowledge)
❓ Communication style and any hard preferences?
❓ Configure skill packs (SEO, Browser, third-party libraries)?
❓ Confirm + scaffold

Total time: β‰ˆ 5 minutes. Each question's answer becomes the default for later steps β€” the name first of all, since every file the wizard writes is phrased in it. See Naming your agent if you want something other than Kevin, now or later. The wizard writes:

  • CLAUDE.md (operating manual + identity @-imports), or CLAUDE.local.md if a CLAUDE.md already exists
  • SOUL.md, IDENTITY.md, USER.md (Kevin's character / role / your headline)
  • knowledge/ and projects/ directory trees, optionally at custom locations
  • .claude/settings.json (marketplace registration + pre-granted permissions for the always-on core MCP tools: ping, compile_*, task_*, knowledge_lint, links_rewrite, memory_prune, report_write. SEO + Browser pack tools land here only when you activate the matching pack via configure-skills)
  • .claude/settings.local.json (gitignored; init writes an empty {} β€” Kevin has no universal-infra env keys. The one non-secret pack key, GSC_SITE_URL, is planted here by configure-skills; every secret credential (PERPLEXITY_API_KEY, SERPAPI_KEY, OPENPAGERANK_API_KEY, GITHUB_TOKEN, AGENT_DB_*) goes in the deny-gated .kevin/secrets/.env instead. Either way you fill the values in your editor, never via chat)

If you chose custom AGENT_KNOWLEDGE or AGENT_PROJECTS paths outside the home directory, the wizard appends the required permissions.allow entries and (where supported) sandbox.filesystem.allowWrite entries to <HOME>/.claude/settings.json so Claude Code can read/write there without prompting you on every operation.

Exit and relaunch

The plugin registration in .claude/settings.json only takes effect on a fresh session. After init:

/exit
cd ~/Documents/Agents/Kevin && claude

Watch for a marketplace trust prompt on first relaunch. Accept it. If you miss it, recover with /plugin marketplace add ... + /plugin install agent-kevin@agentlayer.

That cd is the convention, not just this once. Always launch from the agent home and reach your code from inside the session β€” it's what loads the plugin, and it's what keeps multiple agents apart. See The one convention.


πŸ’Ό What a session looks like

$ cd ~/Documents/Agents/Kevin && claude

  🧠 Knowledge: ~/Documents/Agents/Kevin/knowledge
  πŸ“ Projects:  ~/Documents/Agents/Kevin/projects
  πŸ“š Context  Β· 4.2KB
    βœ“ session tail   1.6KB  (YYYY-MM-DD.md)
    βœ“ today reports  0.2KB  (1 briefing)
    βœ“ git activity   0.3KB  (15 commits in the last week)

> /context
Context loaded from <HOME>/CLAUDE.md and its @-imports:

  CLAUDE.md                                operating manual + @-imports
  └─ @SOUL.md                              Kevin's character
  └─ @IDENTITY.md                          Kevin's role
  └─ @USER.md                              your headline + links to deeper user facets
  └─ @knowledge/index.md                   master catalog
  └─ @knowledge/memory/index.md            active threads Β· decisions Β· learnings
  └─ @projects/TASKS.md                    cross-project task dashboard

Read on demand (not auto-loaded β€” Kevin pulls them when relevant):
  Β· knowledge/user/{profile,skills,preferences,career,interests}.md
  Β· knowledge/concepts/<slug>.md
  Β· projects/<slug>/README.md + tasks

Dynamic (per-session, injected by SessionStart hook):
  Β· today's date (YYYY-MM-DD, <your-timezone>)
  Β· last session tail (yesterday's conversation)
  Β· today's reports (briefings, plans, audits written earlier today)
  Β· recent git activity in knowledge/

Plugin: agent-kevin@agentlayer Β· 52 MCP tools loaded

> /agent-kevin:morning-briefing
[Kevin reads your active threads, in-flight tasks, anything overdue, and surfaces what
 deserves your attention today, using yesterday's session tail as continuity context]

> Create a project called "new-blog". I want to relaunch under a different domain.
[Kevin runs /agent-kevin:create-project, scaffolds projects/new-blog/, registers the
 prefix, asks you for the one-line vision, opens for your first task]

> Audit the site I have in Search Console.
[Kevin runs /agent-kevin:google-search-audit, pulls 28 days of GSC, PSI on the top 5
 pages, applies 4 rules, ranks findings by impact, writes the report to
 projects/<slug>/audits/YYYY-MM-DD.md, threads matching findings into open tasks]

> /exit
[SessionEnd hook captures the conversation to knowledge/raw/sessions/YYYY-MM-DD.md,
 redacting any secret values from .kevin/secrets/.env before persisting.
 Next time you run /agent-kevin:knowledge-compile, this session feeds into Kevin's
 long-term memory.]

The header banner (🧠 Knowledge / πŸ“ Projects / πŸ“š Context) is what the SessionStart hook injects on every launch β€” quick proof your brain is wired up. The /context slash command (built into Claude Code) shows the full @-imports cascade: identity stack, knowledge index, memory index, task dashboard, plus the dynamic per-session additions. User facets and concept articles aren't auto-loaded β€” Kevin reads them on demand via the links in USER.md and knowledge/index.md. That keeps the static lane lean while keeping the deeper material one read away.


🧠 How the knowledge pipeline works (the central evolution loop)

Kevin's long-term memory follows Andrej Karpathy's LLM Wiki pattern. Raw conversations are source code, an LLM is the compiler, the compiled wiki is your queryable second brain.

graph LR
    HOOK[SessionEnd hook] --> SES[raw/sessions/]
    PRE[PreCompact hook] --> SES
    SES --> C[knowledge-compile]
    FB[raw/user/feedback.md] --> C
    INBOX[raw/inbox/] --> C
    C --> USER[user/]
    C --> CON[concepts/]
    C --> MEM[memory/]
    USER -.-> NEXT[next session]
    CON -.-> NEXT
    MEM -.-> NEXT
Loading

The capture is automatic. Every time you exit a session, or Claude Code auto-compacts mid-session, a hook calls bin/kevin session-capture which reads your transcript and appends it to today's session log under knowledge/raw/sessions/YYYY-MM-DD.md. The hook redacts secret values before writing (exact-match against .kevin/secrets/.env values, plus any in .claude/settings.local.json, plus prefix heuristics for sk-…, pplx-…, AIza…, sk-ant-…, gh[pous]_…). The CLI is harness-agnostic β€” adding Codex (or any future host) is a one-file format adapter inside mcp-server/src/knowledge/session-capture.ts, not a new hook script.

Capture anything else manually. A thought, a meeting note, a clipped article, a file, a URL, a correction rule β€” anything you want compiled into the wiki goes in via the capture verb. Same destination, same compile pipeline; you just initiate it instead of a hook.

In a conversation (the common case). Drop a URL, paste a snippet, or hand Kevin a file path β€” he'll route to the capture MCP tool automatically. The tool is exposed as mcp__plugin_agent-kevin_kevin__capture, and natural-language prompts work fine:

you  > capture this for the inbox: https://thenewstack.io/hidden-agentic-technical-debt/
kevin > [calls capture(url=…)] β†’ wrote inbox β†’ knowledge/raw/inbox/2026-05-29-1430-hidden-agentic-technical-debt.md

you  > save as feedback: when refactoring, don't touch adjacent code I didn't ask about
kevin > [calls capture(text=…, kind=feedback)] β†’ appended to knowledge/raw/user/feedback.md

you  > here's my standup notes β€” capture with title "Standup 2026-05-28": <paste>
kevin > [calls capture(text=…, title=…)] β†’ wrote inbox

you  > pull in ~/notes/board-meeting.md
kevin > [calls capture(file=…)] β†’ wrote inbox

URL fetches run through Mozilla Readability + Turndown, which extracts the article body (drops nav/footer/sidebar/modal noise) and converts it to clean Markdown β€” no HTML soup in the inbox.

From the CLI β€” same surface, useful for clipboards, scripts, and one-shots from a terminal:

# Inline thought β†’ raw/inbox/<ts>-<slug>.md
kevin capture "remember to follow up with tracy on constitution lodgement"

# Local file β†’ raw/inbox/ with an explicit title (overrides the auto-slug)
kevin capture --file=~/notes/board-meeting.md --title="Board meeting 2026-05-28"

# URL β†’ fetch, extract article body, convert to Markdown, store with provenance
kevin capture --url=https://docs.anthropic.com/en/docs/claude-code/overview

# Stdin pipe β†’ useful for clipboard / scripted captures
pbpaste | kevin capture --stdin --title="Clipped article"

# Correction / rule / preference β†’ raw/user/feedback.md (compiled into memory/index.md β†’ Learnings)
kevin capture --kind=feedback "don't propose git push for local-only repos"

# Optional metadata β€” label is stored in frontmatter (inbox) or in the feedback header
kevin capture --file=~/spec.md --label="design-spec"
Flag Behaviour
(positional) or --text=... Inline text. Default input source.
--file=PATH Read a local file (≀ 512 KB) and capture its contents.
--url=URL Fetch over HTTP(S) (≀ 5 MB raw). HTML responses run through Mozilla Readability (extracts the article body, drops nav / footer / sidebar / modals) β†’ Turndown (HTML β†’ Markdown). On extraction failure, falls back to a regex strip of <script>/<style>/<head>/<nav>/<header>/<footer>/<aside>/<form>/<svg>/<iframe>/comments. Sanitized body must fit ≀ 512 KB. Provenance recorded as source: url:<url> in frontmatter.
--stdin Read from stdin. Auto-enabled when stdin is a pipe.
--kind=inbox (default) Write to knowledge/raw/inbox/<YYYY-MM-DD-HHMM>-<slug>.md. Compiled into concepts / user facets next compile.
--kind=feedback Append to knowledge/raw/user/feedback.md. Operator-meta β€” corrections, preferences, rules. Compiled into memory/index.md β†’ ## Learnings.
--title=X Sets the filename slug + frontmatter title (inbox only). Without it, the slug comes from the first heading / first line.
--label=X Stored in frontmatter (inbox) or in the feedback entry header. Free-form tag.

Local-only, secret-redacted (same heuristics as session capture), atomic write, content-hash deduped (re-capturing identical input short-circuits to the existing file). The same surface is exposed as mcp__plugin_agent-kevin_kevin__capture for use inside Claude Code sessions β€” same options, same defaults.

The compile is on-demand. When you run /agent-kevin:knowledge-compile, Kevin picks up any session logs whose hash has changed since last compile, plus any inputs you've captured into knowledge/raw/inbox/ (via kevin capture, the MCP capture tool, or a direct file drop), plus any new feedback in knowledge/raw/user/feedback.md. The MCP server returns a synthesis prompt; you, in your TUI session, synthesize; the MCP server confirms the write. Idempotent, hash-tracked, interruptible.

Output Lifecycle What lives there
knowledge/user/ Permanent, evolves with you profile, skills, preferences, career, interests, the durable facets refined every compile
knowledge/concepts/ Permanent, cross-cutting patterns and strategies spanning multiple projects. Specs distill into concepts here
knowledge/memory/ Hot context (index.md loads every session) active threads, recent decisions, learnings from feedback. Daily entries auto-prune after 14 days

Why this stays cheap. The compile MCP tool returns a synthesis prompt, Claude Code (you, in your TUI turn) runs the synthesis using your subscription, the result is written back via another MCP call. No internal LLM-as-a-service, no API billing.


πŸ”„ Sync: end-to-end maintenance in one pass

/agent-kevin:sync runs the whole maintenance chain β€” compile β†’ lint β†’ prune β†’ links β†’ flywheel β†’ scan β†’ dashboards β†’ closing interview β€” when you want every derived view brought current at once. Heavier than quick-pulse, lighter than running each skill manually.

flowchart TD
    SES[/raw/sessions/<br/>YYYY-MM-DD.md/] -.pending.-> C1
    INB[/raw/inbox/<br/>captured items/] -.pending.-> C1
    FB[/raw/user/<br/>feedback.md/] -.pending.-> C1

    START([/agent-kevin:sync]) --> C1[1\. Compile pending raw inputs]
    C1 --> C2[2\. Lint + auto-fix]
    C2 --> C3[3\. Prune transient memory]
    C3 --> C4[4\. Rewrite stale wikilinks]
    C4 --> C5[5\. Flywheel: advance Β· **archive** Β· **persist**]
    C5 --> C6[6\. Scan for overdue/stale]
    C6 --> C7[7\. Read dust-settled state + refresh dashboards]
    C7 --> OUT([πŸ”„ Status block])
    OUT --> GATE{Anything<br/>actionable?}
    GATE -->|clean bill| DONE([done])
    GATE -->|yes| ASK[8\. Closing interview:<br/>pick next move Β· **act now or queue**]

    C1 -.synthesis in your TUI turn.-> WIKI[(knowledge/<br/>user Β· concepts Β· memory)]
    C2 -.errors + warnings.-> LINT[/.kevin/lint.md/]
    C5 -.advance Β· update Β· close.-> TASKMUT[(task frontmatter<br/>+ threads)]
    C5 -.unconditional sweep.-> ARCHIVE[(projects/&lt;slug&gt;/<br/>tasks/archive/)]
    C5 -.unconditional snapshot.-> FLYREP[/reports/briefings/<br/>flywheel/&lt;slug&gt;.md/]
    C7 -.one call, both views.-> TASKS[/projects/TASKS.md<br/>+ dashboard.html/]
    ASK -.act now.-> TASKMUT
Loading

The dependency order is the point: compile feeds the wiki state that lint operates on; lint's auto-fix touches the same articles the dashboard's task-link rewriter needs to be clean. Flywheel runs after the wiki is clean (so it reads a current memory index) and before scan + dashboard refresh (so both views reflect post-flywheel task state). Running steps out of order makes you re-reconcile.

The run closes with a gated interview: only when sync actually surfaced something to act on (an overdue/stale item, a due cadence skill, a pending upgrade, or a concrete next move) does it end with a single AskUserQuestion β€” pick what to tackle next, then act on it this session or queue it as a task. On a clean bill there's no interview; the status block is the end.

Two sub-steps of flywheel run every sync, unconditionally: the archive sweep (moves done/cancelled task files into tasks/archive/ so the active dir stays scannable) and the snapshot persist (report_write to reports/briefings/flywheel/ so the next morning brief can pick up the cross-session trail). Advance Β· update Β· close Β· concepts Β· decisions fire only when there's real work to do.

The status block reads from the dust-settled artifacts (projects/TASKS.md, .kevin/lint.md, knowledge/memory/index.md) β€” not from per-tool return values β€” so the summary reflects what's actually on disk after every mutation has landed. See skills/sync/SKILL.md for the protocol.


🌐 Browser web tools

Four MCP tools (the browser_* family) backed by a bundled chromium (installed once via bun install's playwright postinstall, ~150MB). All four output to <HOME>/reports/captures/<timestamp>-<name>.<ext>. The Browser pack must be active (/agent-kevin:configure-skills β†’ tick Browser pack) for the permissions to be pre-granted; without it the first call confirms.

Tool Output Use it for
browser_screenshot PNG Visual snapshot of any URL or local HTML / MD file; optional fullPage for the whole scrolling page
browser_pdf PDF (A4) Render markdown (with mermaid diagrams) or HTML to print-styled PDF
browser_markdown Markdown Convert any URL β€” including SPAs / Next.js / React sites β€” to clean LLM-friendly Markdown. Loads in chromium so client-rendered sections hydrate; pipes through Mozilla Readability + Turndown
browser_record WebM video Drive a page through scripted steps (navigate / scroll / wait) and capture the run

All four take the same input β€” a URL, a file:// URL, or an absolute/relative path. screenshot and pdf will also render local Markdown files (loading them through marked + a styled CSS so mermaid renders). markdown does the reverse β€” fetches a hydrated page and converts back to Markdown.

In a conversation (the common case) β€” just ask:

you  > screenshot https://acme.com and call it acme-landing
kevin > [calls browser_screenshot(input=…, name=acme-landing)] β†’ reports/captures/<ts>-acme-landing.png

you  > render ~/Documents/business-plan.md to PDF
kevin > [calls browser_pdf(input=…)] β†’ reports/captures/<ts>-pdf.pdf  (mermaid diagrams come through)

you  > convert https://basem.emara.io to markdown β€” make sure the JS-rendered sections come through
kevin > [calls browser_markdown(input=…, waitUntil=networkidle)] β†’ reports/captures/<ts>-markdown.md

you  > record a 15-second tour of agentlayer.one β€” scroll halfway, wait 2s, scroll to the bottom
kevin > [calls browser_record(input=…, steps=[{kind:scroll,pixels:600},{kind:wait,ms:2000},{kind:scroll,pixels:9999}])] β†’ reports/captures/<ts>-record.webm

🌱 Self-evolution: Kevin gets better the more you use him

graph LR
    CAP["Reactions + corrections<br/>in chat"]
    FB["knowledge/raw/user/<br/>feedback.md"]
    SYN["compile: feedback<br/>synthesis"]
    LN["knowledge/memory/<br/>index.md ## Learnings"]
    NEXT["next session"]
    REV["self-review skill"]
    EDIT["edits to SOUL,<br/>CLAUDE.md, skills"]
    PLANS["plans to<br/>reports/plans/"]

    CAP --> FB
    FB --> SYN
    SYN --> LN
    LN -.->|loaded every session| NEXT
    FB --> REV
    REV --> EDIT
    REV --> PLANS
Loading

Every time you correct Kevin mid-conversation ("don't do that", "actually, that's wrong"), the SessionEnd hook captures the correction into knowledge/raw/user/feedback.md, append-only, durable. The next knowledge-compile run synthesises all feedback into a ## Learnings block in knowledge/memory/index.md, which loads as static memory at the start of every future session. Kevin sees his own past misses while he works and self-corrects in real time.

When you have ten minutes, run /agent-kevin:self-review. It's not a quick pass over the synth β€” Kevin casts a wide signal net across eight sources: the ## Learnings synth, the full feedback.md, the last 7 days of session logs and task threads, git history (to find prior-fix commits), concept articles, in-flight plans, and installed skills. Grep is for both correction and confirmation phrases β€” wins matter too, they validate non-obvious choices.

Each theme gets classified as missing, buried, present-but-violated, or present-and-working β€” the whole point is catching rules that landed but didn't stick. Themes rank by severity Γ— instance count Γ— cycle count; anything with fewer than two independent signals or present-and-working gets dropped. If nothing clears the bar, Kevin says so and stops.

Proposals come in three tracks:

  • Track A β€” prompt/skill edits. Applied synchronously in-session, you pick which to accept. Surface choice is deliberate: identity β†’ SOUL, procedural β†’ CLAUDE.md, skill-specific β†’ that skill's body.
  • Track B β€” code-change plans. Written to <HOME>/reports/plans/ via the report_write MCP tool, never auto-applied. You implement them in a separate session.
  • Track C β€” skill install or create. Only when the signal is a recurring multi-step procedure. Requires explicit in-session approval.

Kevin also sweeps <HOME>/reports/plans/ for aging proposals (>14 days, no follow-through) and proposes re-surface / downgrade / close on each one. A quality gate runs before any proposal lands β€” every target file actually read (not paraphrased), specific evidence (timestamps, quotes, file:line), coverage audit done, and for any pre-existing rule: violations counted after it was introduced.

Three stages, loosely coupled. Capture is automatic. Compile is on-demand. Review is manual. No ceremony.


🧰 Use cases

1. Personal home base

Track your projects, plan your weeks, capture decisions, remember context across sessions. Spin up cd ~/Documents/Agents/Kevin && claude whenever you want, ask Kevin what you were working on last Tuesday, get a coherent answer because the session tail loaded itself.

2. SEO + content workflow for one site

Configure GSC + PageSpeed + SerpAPI keys once. Run /agent-kevin:google-search-audit weekly (or wire it to cron). Get a markdown report ranked by impact, findings threaded into existing tasks. Pair with optional third-party SEO libraries for content drafting + EEAT scoring.

3. Several agents, one plugin install

Different homes for different roles, each its own brain with its own name, persona, and skill packs.

~/Documents/Agents/Kevin/     # personal projects, journals, life ops
~/Documents/Agents/Scout/     # client work, professional persona
~/Documents/Agents/Sage/      # SEO-focused, only the SEO pack configured

The plugin code lives once on disk; each home is independent. Switch by cd-ing into the one you want and launching claude, and the right brain loads automatically β€” the home is resolved from where you launched, so nothing needs configuring to keep them apart.

Give each one its own identity with /agent-kevin:rename-agent. They'll still share the /agent-kevin: command namespace, which is plumbing you never see once each IDENTITY.md carries its own name.

The single rule: no KEVIN_* variable in ~/.claude/settings.json or your shell rc. It's machine-wide and outranks the walk-up, so one value captures every session for one brain and the rest become unreachable. Anything per-home goes in that home's .claude/settings.local.json.

Each home can even bill against its own Claude account β€” see Running homes on different Claude accounts.

4. Augmenting an existing project

You already have a project with its own CLAUDE.md. You want Kevin's memory + task system layered on top, without overwriting your existing instructions.

cd ~/Developer/my-existing-project
claude
/agent-kevin:init

Init detects the pre-existing CLAUDE.md and writes Kevin's operating manual to CLAUDE.local.md instead. Both files load at session start (Claude Code natively merges them). Your project context and Kevin's identity coexist.

5. Team-shared agent in a shared repo

Drop Kevin into a team repo, commit the <HOME>/{CLAUDE.md, SOUL.md, IDENTITY.md, .claude/settings.json, knowledge/} files, gitignore settings.local.json. Every teammate gets the same agent identity. Each accepts the trust prompt once on first launch.

6. Seed a teammate's agent from yours

You've shaped your agent β€” renamed it, grown project knowledge, wired up custom skills and MCP servers β€” and a teammate wants to start from that instead of a blank scaffold, while their memory, sessions, and credentials stay entirely their own.

/agent-kevin:seed-export          # you: interview + review gate β†’ a zip in reports/seeds/
# send the zip; on their machine:
/agent-kevin:init                 # their own scaffold (any name β€” the seed brings identity if you exported it)
/agent-kevin:seed-import ~/Downloads/2026-08-27-scout-seed.zip

The bundle is a plain zip with a manifest: identity files, selected concepts, project READMEs/roadmaps, custom skills, MCP server entries, and permission grants β€” plus the credential key names the setup needs. Values never travel; the import ends with a fill-these-in-your-editor checklist. Everything imported becomes the recipient's own (fork semantics β€” no sync, no link back to your agent; for that, this is the wrong tool). Unlike use case 5's shared repo, each teammate's agent diverges freely after the handoff.


πŸ—οΈ Architecture

The brain is portable markdown on your disk. Claude Code is the runtime. The plugin is the glue. Obsidian is how a human reads the brain. Terminal-driven scripts read and write the brain directly via bin/kevin when you don't want a session.

graph LR
    YOU["You"]
    CC["Claude Code"]
    PLUGIN["agent-kevin plugin<br/>MCP server Β· skills Β· hooks"]
    BRAIN["Brain<br/>your markdown home"]
    OBS["Obsidian"]
    TERM["Terminal"]
    EXT["External services<br/>GSC Β· PageSpeed Β· SerpAPI<br/>OpenPageRank Β· Perplexity Β· Playwright"]

    YOU <-->|chat| CC
    CC <-->|plugin loaded| PLUGIN
    PLUGIN -->|reads + writes| BRAIN
    PLUGIN -.->|hooks capture sessions| BRAIN
    PLUGIN -->|dispatch with your keys| EXT
    TERM -->|bin/kevin CLI| BRAIN
    BRAIN -->|browse| OBS
Loading
Layer What Where
You The decision maker wherever you are
Claude Code The AI runtime that reads the brain and acts on it your terminal
Plugin Skill bodies, MCP server, hooks agent-kevin/ (one repo, multiple homes)
Brain Personality, knowledge, projects, everything that makes Kevin yours <HOME>/ (portable markdown)
Obsidian Human-facing browser for the brain β€” clickable wiki-links, daily notes, graph view <HOME>/ opened as an Obsidian vault
Terminal Bypass route for scripted task ops and headless compile runs shell bin/kevin invocations
External services Optional tools the MCP server dispatches to with your API keys GSC, PageSpeed, SerpAPI, OpenPageRank, Perplexity, in-process Chromium

🧱 What you get

Core skills (25+), always loaded

Skill What it does
init First-run onboarding
configure-skills Configure skill packs, install third-party libraries
rename-agent Change the agent's display name across an existing home β€” persona fields, avatar, and prose β€” without forking the plugin (/rename-agent, and it asks before running)
knowledge-compile Synthesise raw sessions/feedback/inbox items into the wiki
create-project / archive-project Project lifecycle
flywheel Cross-project work session, framed by the north-star roadmap (and each project's own), whose milestone statuses it keeps honest
sync End-to-end maintenance: compile β†’ lint+fix β†’ prune β†’ flywheel β†’ scan β†’ dashboards β†’ closing interview in one pass
morning-briefing / evening-briefing Daily orient + wrap
standup Your standup update in three parts β€” what you did in the last 24h (merged PRs, hand-run prod actions, investigations with no commit), what you're picking up next, and what's blocked with named owners. Glanceable while presenting; flags older work a skipped run may have left unsaid; /agent-kevin:standup 48 to widen (auto-invocable)
weekly-goals / monthly-goals / yearly-goals Goal-setting cadences β€” weeks, monthly themes, and the year planned quarter by quarter
quick-pulse 60-second status check
self-review Process feedback into skill refinements
dashboard Refresh + open the Agent OS mission-control page (auto-invocable)
where-am-i Radar over recent Claude Code sessions β€” what you were working on, where you left off (auto-invocable)
find-session Locate a past session by what it worked on β€” a branch, a PR, a bug β€” content search over all transcript history, ranked by did-the-work signals, ending in its resume command (auto-invocable)
api-collections Draft API requests as file-based collections in <HOME>/reports/api/<adapter>/ (or a named location) β€” you visualize and fire them in your API client (Bruno adapter shipped, curl fallback); Kevin authors, never sends
setup-worktree Create a sibling git worktree on a new branch and bootstrap it (copy local files, install, build)
seed-export / seed-import Hand your agent to a teammate as a seed bundle β€” a zip carrying the persona (name, SOUL, avatar), selected knowledge concepts, project docs/roadmaps, custom skills, MCP registrations, and pack activations (credential key names only, never values). Export runs an interview + per-file review gate; import dry-runs the plan, confirms conflicts, then overlays the bundle onto a fresh home with fork semantics (auto-invocable)
upgrade / release Consumer applies a new plugin version to the home; maintainer cuts one (CHANGELOG + tag)
itinerary Wizard-style trip planner β†’ interviews you, researches flights/routes/prices, renders an interactive, print-ready HTML itinerary into a trips project
roadmap Wizard-style roadmap builder β†’ interviews for the frame (shape, horizons, lanes, palette), mines the task board / READMEs / git history for milestones, renders a themable timeline-and-lanes HTML surface (auto-invocable)
plan-spec Deep-dive spec writer β€” Socratic interview β†’ standalone, plan-compatible spec saved to the plans directory (/plan-spec)
simple-simplify Review a script/app/area/change and simplify it: elegance, dead-code removal, no over-engineering (/simple-simplify)
humanizer Strip the tells of AI-generated prose β€” inflated symbolism, rule-of-three, em-dash overuse, AI vocabulary β€” to make writing read as human

Custom-skill authoring isn't a Kevin skill, because Claude Code already ships a native skill-creator plugin that does exactly that. Use it for your own skills.

SEO pack (6), pre-loaded, configured via /agent-kevin:configure-skills

serpapi Β· open-page-rank Β· google-search-console Β· google-page-speed Β· wordpress-rest Β· google-search-audit

Four need API keys (SerpAPI, OpenPageRank, Google OAuth + GSC_SITE_URL for the last two). wordpress-rest uses curl with a host-scoped permission grant derived from GSC_SITE_URL. google-search-audit is a composite read-only audit using everything above. Account signup steps and costs: External accounts & costs.

Browser pack, configured on demand

  • Perplexity, live web search with citations (mcp__plugin_agent-kevin_kevin__web_search). Built into the kevin MCP server β€” direct call to the Perplexity Search API, no extra subprocess. Activate the tool via /agent-kevin:configure-skills (grants the permission + ensures the .kevin/secrets/.env store exists for a PERPLEXITY_API_KEY line), then fill the key value in your editor β€” configure-skills never asks for it in chat, since pasted secrets touch the transcript and the Anthropic API. Way better answers than vanilla web-search and dirt-cheap on pay-as-you-go: $5 of credit lasts most personal users several days to several weeks depending on query volume. Get a key at perplexity.ai/settings/api.
  • Browser tools, four web tools backed by a bundled Playwright + chromium (drops in via the one-time bun install). See Browser web tools below for the full set, or here's the short of it:
    • browser_screenshot β€” PNG of any URL or local HTML/MD file
    • browser_pdf β€” styled PDF (markdown + mermaid rendered)
    • browser_markdown β€” JS-rendered page β†’ clean Markdown via Readability
    • browser_record β€” scripted page interactions β†’ WebM video

Third-party skill libraries

Installed on demand via skills.sh. Pure-prompt content/marketing skill libraries are not bundled. They install via Vercel Labs' skills CLI into <HOME>/.claude/skills/ as symlinks into the skills.sh cache, so upstream updates propagate without re-running install. Currently offered:

  • aaron-he-zhu/seo-geo-claude-skills (Apache-2.0): 20-skill SEO + GEO library including content-quality-auditor (80-item CORE-EEAT audit), seo-content-writer, content-refresher, domain-authority-auditor.
  • coreyhaines31/marketingskills: 23 marketing playbooks (CRO, SEO, copy, analytics, experiments, pricing, launches, ads, social).

Install: /agent-kevin:configure-skills β†’ tick "Third-party libraries".

MCP tools (55)

Group Tools
Tasks (7) task_query, task_get, task_create, task_update, task_close, task_thread, task_scan
Knowledge (7) capture, memory_prune, links_rewrite, knowledge_lint, compile_status, compile_next, compile_write
Reports (1) report_write
Dashboard (1) dashboard
Worktree (3) setup_worktree, list_worktrees, remove_worktree
Upgrade (1) run_upgrade
Seed (3) seed_scan, seed_export, seed_import
Database (4) database_list, database_schema, database_query, database_fork
GitHub (11) github_pr_list, github_pr_view, github_pr_comments, github_pr_diff, github_pr_checks, github_run_list, github_run_view, github_run_log, github_issue_list, github_issue_view, github_fast_forward
Dispatch (17) serpapi_search, open_page_rank, google_auth, gsc_query, gsc_inspect, gsc_sites, page_speed_psi, page_speed_audit, browser_screenshot, browser_pdf, browser_markdown, browser_record, browser_flows, web_search, curl_run, video_frames, ping

Always-on core (ping, capture, compile_*, task_*, knowledge_lint, memory_prune, links_rewrite, report_write, dashboard, setup_worktree, run_upgrade, seed_scan, seed_export) is pre-granted via permissions.allow at init. Pack-gated tools (SEO: serpapi_search, open_page_rank, gsc_*, page_speed_*, google_auth; Browser: web_search, browser_*; Database: database_*; GitHub: github_pr_*, github_run_*, github_issue_*, github_fast_forward) only land in permissions.allow when you activate the matching pack via /agent-kevin:configure-skills. remove_worktree is deliberately never pre-granted β€” it deletes a worktree, so every call surfaces a confirm prompt. seed_import sits in the baseline ask list for the same reason: it overwrites identity files and merges permissions/MCP registrations from a foreign bundle, so it always confirms. This keeps settings.json an accurate audit trail β€” it advertises only the packs you actually opted into.

Hooks

  • SessionStart: pre-init shows the setup banner. Post-init injects today's date, last session tail, today's reports (any briefings or plans written earlier today), and recent git activity (≀10KB total).
  • SessionEnd + PreCompact: capture transcript turns to knowledge/raw/sessions/YYYY-MM-DD.md with API key redaction. This is what makes the flywheel work. Without these hooks, Kevin would have no source material to compile into long-term memory.

All three ship with the plugin, so Claude Code runs them only for sessions started where the plugin is enabled β€” its own home. A session can therefore only ever be captured by the agent whose home it launched in, which is what keeps two agents on one machine from writing into each other's memory. Don't add capture hooks to ~/.claude/settings.json; see the launch convention.


πŸ—‚οΈ How it's laid out

The plugin (this repo)

agent-kevin/
β”œβ”€β”€ .claude-plugin/
β”‚   └── plugin.json          # plugin manifest
β”œβ”€β”€ assets/                  # Kevin's avatar, AgentLayer logo
β”œβ”€β”€ bin/
β”‚   └── kevin                # standalone CLI for shell-driven task ops
β”œβ”€β”€ hooks/
β”‚   └── hooks.json           # SessionStart + SessionEnd + PreCompact
β”œβ”€β”€ mcp-server/              # the kevin MCP server (Bun)
β”‚   β”œβ”€β”€ src/
β”‚   └── package.json
β”œβ”€β”€ skills/                  # 30+ skills (core + SEO + Browser) auto-load with plugin
β”‚                            #   (per-version upgrade migrations live in skills/upgrade/scripts/<v>.ts)
β”œβ”€β”€ templates/               # init copies these into <HOME>
β”‚   β”œβ”€β”€ CLAUDE.md            # β†’ <HOME>/CLAUDE.md (or CLAUDE.local.md on collision)
β”‚   β”œβ”€β”€ IDENTITY.md          # Kevin's role (includes Kevin's avatar)
β”‚   β”œβ”€β”€ SOUL.md              # Kevin's character
β”‚   β”œβ”€β”€ USER.md              # YOUR headline + links to knowledge/user/
β”‚   β”œβ”€β”€ rules/              # path-scoped coding rules, auto-applied by file glob
β”‚   └── knowledge/          # seed wiki (index.md, memory scaffold)
β”œβ”€β”€ .mcp.json                # declares the `kevin` MCP server
β”œβ”€β”€ CHANGELOG.md             # release contract (### Upgrade blocks drive /upgrade)
β”œβ”€β”€ LICENSE                  # Apache 2.0
└── NOTICE                   # Apache 2.0 attribution

Your agent home (after init)

<HOME>/
β”œβ”€β”€ .claude/
β”‚   β”œβ”€β”€ assets/              # Kevin's avatar (kept out of the home root)
β”‚   β”œβ”€β”€ skills/              # third-party skill libraries installed via skills.sh (lazy)
β”‚   β”œβ”€β”€ settings.json        # enabledPlugins + pre-granted permissions
β”‚   └── settings.local.json  # non-secret env (GSC_SITE_URL, AGENT_CODE_PATH), gitignored
β”œβ”€β”€ .kevin/                  # plugin runtime state (hidden)
β”‚   β”œβ”€β”€ secrets/             # deny-gated credential store β€” gitignored, Kevin can't read it
β”‚   β”‚   β”œβ”€β”€ .env             # API keys + AGENT_DB_<NAME> connection strings
β”‚   β”‚   └── google/          # Google OAuth client JSON + cached tokens
β”‚   β”œβ”€β”€ updates/             # per-upgrade file backups (<from>-to-<to>/)
β”‚   β”œβ”€β”€ logs/
β”‚   β”œβ”€β”€ version.json         # template baseline (drives upgrade tracking)
β”‚   └── knowledge.json       # compile state
β”œβ”€β”€ knowledge/               # (or AGENT_KNOWLEDGE elsewhere)
β”‚   β”œβ”€β”€ concepts/            # cross-cutting articles
β”‚   β”œβ”€β”€ memory/              # hot context (threads, decisions, learnings)
β”‚   β”œβ”€β”€ raw/                 # unprocessed inputs to compile
β”‚   β”‚   β”œβ”€β”€ archive/         # compiled inbox items land here after compile
β”‚   β”‚   β”œβ”€β”€ sessions/        # auto-captured conversations (the source of evolution)
β”‚   β”‚   β”œβ”€β”€ inbox/           # drop any input here (or use `kevin capture`) for distillation
β”‚   β”‚   └── user/
β”‚   β”‚       └── feedback.md  # corrections log (append-only)
β”‚   β”œβ”€β”€ user/                # evolving long-form knowledge about you (incl. profile.md with your avatar)
β”‚   └── index.md             # master catalog
β”œβ”€β”€ projects/                # (or AGENT_PROJECTS elsewhere)
β”‚   β”œβ”€β”€ <slug>/
β”‚   β”‚   β”œβ”€β”€ tasks/
β”‚   β”‚   β”‚   └── <id>-<slug>.md
β”‚   β”‚   └── README.md
β”‚   └── TASKS.md
β”œβ”€β”€ reports/                 # transient skill outputs (briefings, plans)
β”‚   β”œβ”€β”€ index.md             # auto-maintained "newest first" log (today's entries injected into SessionStart)
β”‚   β”œβ”€β”€ briefings/           # morning/evening briefings, weekly/monthly goals, self-review summaries
β”‚   β”œβ”€β”€ captures/            # browser-tool artifacts (screenshots, pdfs, recordings) β€” gitignored, regenerable
β”‚   └── plans/               # self-review code-change proposals (Track B) + native plan-mode saves (plansDirectory)
β”œβ”€β”€ .mcp.json                # only present if the user adds their own MCP servers β€” Kevin's bundled `kevin` server lives in the plugin's own .mcp.json
β”œβ”€β”€ CLAUDE.md                # operating manual + @-imports for identity stack
β”‚                            # (or CLAUDE.local.md if CLAUDE.md pre-existed)
β”œβ”€β”€ IDENTITY.md              # Kevin's role + evolving self-description
β”œβ”€β”€ SOUL.md                  # Kevin's character
└── USER.md                  # YOUR headline + links to knowledge/user/

Open <HOME>/ in Obsidian to browse with working wiki-links. .claude/ and .kevin/ are hidden by default.


πŸ’» Outside Claude Code: bin/kevin CLI

For terminal-driven task ops, cron jobs, scripted compile prep:

export PATH="$HOME/Developer/agentlayer-claude-marketplace/agent-kevin/bin:$PATH"

kevin help     # full command reference

kevin help prints groups, commands, flags, env vars, and examples. The major groups:

Group What it does
kevin task <subcmd> Query, get, create, update, close, thread, scan tasks
kevin dashboard Rebuild both dashboards: projects/TASKS.md + the Agent OS page at <HOME>/dashboard.html
kevin knowledge lint [--fix] Structural wiki health check (broken links, orphans, missing backlinks, sparse, invalid frontmatter); --fix auto-rewrites links + inserts backlinks
kevin compile <subcmd> status (queue), next (peek), write <id> (mark complete). Synthesis itself runs in Claude Code via /agent-kevin:knowledge-compile
kevin prune Delete memory/YYYY-MM-DD*.md older than the retention window (14 days)
kevin seed <subcmd> scan (what this home could seed a teammate with), export (build a bundle zip from explicit paths β€” no review gate here, you are the gate), import <zip> [--dry-run] [--overwrite] (overlay a bundle onto this home)
kevin links Rewrite bare task IDs + shorthand into [[wikilinks]] across the wiki
kevin ping Print resolved paths + timezone (sanity check)

Common examples:

kevin task query --status=active
kevin task create --project=blog-dev --title="Draft launch post" --description="..." --priority=P1
kevin task dashboard                  # rebuild projects/TASKS.md from frontmatter
kevin knowledge lint --fix            # check wiki + auto-fix broken links + backlinks
kevin compile status                  # what's pending compile

Note: bin/kevin invokes the MCP server logic locally without going through Claude Code. The compile pipeline returns prompts (not synthesized output), so full evolution still needs a TUI session β€” see /agent-kevin:knowledge-compile for the orchestration loop, or /agent-kevin:sync to run compile β†’ lint β†’ dashboard β†’ briefing in one pass.


βš™οΈ Configuration

Two spellings per knob. The table below lists each var under its shared, agent-neutral AGENT_* name β€” the spelling init and configure-skills write. Every one also accepts a per-agent override under this agent's prefix β€” KEVIN_*, derived from the plugin manifest name (agent-kevin β†’ KEVIN_); a fork named agent-scout reads SCOUT_* with zero code change β€” and the prefixed spelling always wins, so existing KEVIN_* configs work unchanged. Set these per home, in <HOME>/.claude/settings.local.json, under the neutral AGENT_* names. The file's location is what scopes the value to that agent, which is why the portable spelling is the right one there. The prefixed form exists for the case where you genuinely want one value to reach a specific agent from anywhere, and on a machine running more than one home that case is essentially "never" β€” ~/.claude/settings.json is machine-wide, so a KEVIN_HOME there captures every session for one brain and makes the others unreachable. See the launch convention.

Env var Purpose Default
KEVIN_HOME Path to your agent home. Normally leave this unset β€” the home is found by walking up from the launch directory for .kevin/, which is correct for sessions and required for running more than one home. Useful as a one-off prefix when running bin/kevin from a plain terminal outside the home. Never put it in ~/.claude/settings.json. resolved from the launch dir via the .kevin/ walk-up
AGENT_TIMEZONE IANA timezone for date formatting system timezone
AGENT_HOME_TIMEZONE Home-base IANA timezone; when it differs from the live timezone, session context flags the operator as traveling unset
AGENT_KNOWLEDGE Override knowledge dir $KEVIN_HOME/knowledge
AGENT_PROJECTS Override projects dir $KEVIN_HOME/projects
AGENT_REPORTS Override reports dir $KEVIN_HOME/reports
AGENT_CODE_PATH Absolute path to your primary codebase. Lets Kevin ground code-related tasks against it and surface its git activity in session context. Optional β€” asked in chat at init (not a secret), or set later. none
AGENT_GIT_REPOS Comma-separated extra git repo paths (~-expanded) surfaced in the SessionStart context block alongside the knowledge repo. Init derives it from AGENT_CODE_PATH; append more later. derived from AGENT_CODE_PATH
AGENT_LOG_LEVEL Log level: debug Β· info Β· warn Β· error. Falls back to LOG_LEVEL. info
AGENT_LOG_FILE Override log file path. Set to off to disable file output. $KEVIN_HOME/.kevin/logs/app.log
AGENT_RUNTIME_DIR Rename the runtime data-dir folder (a bare folder name, not a path β€” validated). Machine-wide by design; the per-agent spelling also works. .kevin

How the home is found. In order: an explicit KEVIN_HOME / AGENT_HOME; then the nearest ancestor of cwd carrying .kevin/; then the same walk from the launch directory (CLAUDE_PROJECT_DIR, which Claude Code exports to hooks and MCP servers and which doesn't move when the shell does); then cwd as a last resort. Launch from the home and steps two and three cover you for the whole session, including after you cd into a repo.

The marker is the data dir, never SOUL.md. Every agent's home has a SOUL.md, so testing for it answers "some agent lives here" rather than "this agent lives here" β€” and since resolution falls back to cwd, the weaker test would let one agent read and write inside another's brain. Guards use the same predicate the walk does, so if the resolved directory isn't this agent's home, the CLI refuses and hooks skip instead of writing somewhere wrong.

AGENT_KNOWLEDGE and AGENT_PROJECTS let you put those directories anywhere (e.g. a cloud-synced folder β€” iCloud Drive on macOS, OneDrive on WSL2 β€” an external drive, or a separate git repo). The init wizard offers this during scaffold and, if the chosen path is outside the agent home, automatically appends permissions.allow (and sandbox.filesystem.allowWrite where supported) entries to <HOME>/.claude/settings.json so Claude Code can read/write there without prompting. If you set these env vars after init, edit settings.json yourself.

Two homes for env keys, split by sensitivity. Secret credentials (SERPAPI_KEY, OPENPAGERANK_API_KEY, PERPLEXITY_API_KEY, GITHUB_TOKEN, AGENT_DB_*, plus the Google OAuth files) live in <HOME>/.kevin/secrets/.env (and .kevin/secrets/google/) β€” a deny-gated store Kevin's own tools can't read, gitignored. Non-secret config (GSC_SITE_URL, AGENT_CODE_PATH, AGENT_GIT_REPOS) lives in <HOME>/.claude/settings.local.json env block, also gitignored. The rule: init owns universal-infra env keys; configure-skills owns pack-gated keys. Kevin's only universal-infra keys are the optional AGENT_CODE_PATH / AGENT_GIT_REPOS pair β€” init writes them only if you give a codebase path at Step 4b (otherwise /init writes an empty {}). Every pack key configure-skills plants as an empty placeholder when you activate the matching pack β€” the secret ones into secrets/.env, GSC_SITE_URL into settings.local.json. You fill the values in your editor β€” neither flow asks for them in chat, since secrets must not enter the session transcript or the Anthropic API. (The codebase path isn't a secret, so init does ask for it in plain chat.)

Running homes on different Claude accounts

Claude Code's /login is a single slot per OS user (last login wins), so on its own it can't keep two homes on two subscriptions. CLAUDE_CODE_OAUTH_TOKEN can: it sits above the /login slot in Claude Code's credential precedence, and each session resolves its own settings.local.json env block at launch. Give each home its own token and two homes authenticate against two different subscriptions at the same time.

Mint one token per account with claude setup-token (requires Pro/Max/Team/Enterprise; the token is subscription-backed, inference-only, and valid for a year):

# 1. In any session: /login as account A
claude setup-token          # runs an OAuth flow, prints a token for account A
# 2. Put the token in home A's env block (see below)
# 3. /login as account B, run setup-token again, put that one in home B
// <HOME>/.claude/settings.local.json  (gitignored)
{
  "env": {
    "CLAUDE_CODE_OAUTH_TOKEN": "sk-ant-oat01-..."
  }
}

This is the one credential that lives in settings.local.json rather than the secrets store: Claude Code itself consumes it at launch, before Kevin's tools exist, so the deny-gated .kevin/secrets/.env can't carry it. The file is gitignored either way.

The gotchas, learned the hard way:

  • Switch /login between mints. setup-token issues a token for whatever account you're currently logged into; running it twice without switching yields two tokens for the same subscription.
  • The env block is read at launch, not hot-reloaded. Adding the token to an open session does nothing; restart claude.
  • Launch from the home root. settings.local.json resolves from the launch directory β€” the same convention everything else here relies on.
  • Nothing higher-precedence may shadow it. An ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN in your shell rc or ~/.claude/settings.json silently outranks the token machine-wide.
  • Verify with /status + /usage, not the shell. /status shows the auth method (CLAUDE_CODE_OAUTH_TOKEN vs the /login fallback) but not the account; the definitive test is independent /usage meters β€” heavy work in one home should move only that account's usage. echo $CLAUDE_CODE_OAUTH_TOKEN in a session reads empty even when auth is live, since Claude Code doesn't export credentials into subprocesses.

One caveat: setup-token is documented for CI/headless use, and the docs don't address running two subscription accounts concurrently on one OS user. If per-client cost attribution is what you're actually after, a Console API key (ANTHROPIC_API_KEY) from a separate Console organization per client is the cleaner instrument: itemized per-token spend you can invoice, with no ToS ambiguity.

Database connections (database_* tools)

The database_list, database_schema, and database_query MCP tools run read-only Postgres queries against any databases you wire up: no external account, just a connection string. Connections are discovered by env-var convention. Every AGENT_DB_<NAME> entry in <HOME>/.kevin/secrets/.env (since v0.3.0 connection strings, like all credentials, live in the deny-gated secrets store β€” not settings.local.json) becomes a connection named <name> (lowercased). Add or remove connections by editing that file, with no code change:

# <HOME>/.kevin/secrets/.env
AGENT_DB_APP=postgres://user:pass@localhost:5432/app_dev
AGENT_DB_ANALYTICS=postgres://user:pass@host:5432/analytics

That yields connections app and analytics. The easiest way to set this up is the Database pack: run /agent-kevin:configure-skills (or tick it during /agent-kevin:init Step 8), which grants the database_* tool permissions and ensures .kevin/secrets/.env exists for the AGENT_DB_<NAME> lines you add. You then fill the connection string in your editor, never in chat (it carries a password, and the secrets file is deny-gated so Kevin can't read it). Re-run the pack any time to add more connections. You can also just add the env lines by hand: the tools discover any AGENT_DB_<NAME> key regardless of how it got there. database_list only ever reports host/port/database, never the credentials.

Every query runs inside a BEGIN READ ONLY transaction with a statement timeout and is then rolled back, so Postgres itself rejects any write: the read tools are read-only by construction. For tighter control (row or column limits), point the connection string at a SELECT-only database role.

The pack also grants one write tool, database_fork: it clones a database into a private copy via CREATE DATABASE <fork> TEMPLATE <source> (pure SQL β€” no pg_dump/pg_restore, no dump file, cross-platform), so you can run risky or destructive schema changes against a scratch copy instead of a shared/live DB. It refuses remote hosts (local servers only), defaults to the first connection and its database, names the fork after the current git branch, and can repoint an env file at the fork; drop: true tears it back down. This is what the setup-worktree skill uses to give a worktree its own database on demand.

GitHub pack (github_* tools)

Eleven read-only GitHub tools. Ten let Kevin review pull requests and issues and diagnose failing CI without leaving the session: github_pr_list, github_pr_view, github_pr_comments (inline review threads with resolved/outdated state β€” the review surface github_pr_view can't see), github_pr_diff, github_pr_checks, github_run_list, github_run_view, github_run_log, github_issue_list, and github_issue_view; the eleventh, github_fast_forward, fast-forwards your local checkouts' default branches during /agent-kevin:sync (one authenticated git fetch, strictly forward-only). github_run_log defaults to the failed steps only (gh run view --log-failed) β€” the right altitude for "why is this build red" without dumping a megabyte of green log. Diffs and logs are truncated to a character budget you can override per call.

They wrap the gh CLI (brew install gh), shelled out from inside the MCP server. That matters: under the Claude Code sandbox gh dies during TLS setup (its macOS build verifies certs through the keychain, which the seatbelt blocks), but the MCP server runs outside that sandbox, so the same gh works. There are no write subcommands β€” commenting, creating PRs, merging, and re-running workflows stay a deliberate human-in-terminal activity.

Auth is a fine-grained, read-only personal access token in <HOME>/.kevin/secrets/.env as GITHUB_TOKEN (gh honors it and skips the keychain). The easiest setup is the GitHub pack: /agent-kevin:configure-skills β†’ tick GitHub (or tick it at /agent-kevin:init Step 8). It grants the eleven tool permissions, ensures .kevin/secrets/.env exists, and walks you through minting the PAT β€” resource owner set to the repos' owner, repository permissions all read-only (Pull requests Β· Issues Β· Metadata Β· Actions Β· Contents). You paste the value into your editor, never into chat. The read-only token is a second wall behind the read-only tool surface.

One gotcha worth calling out: grant Actions: Read (which GitHub describes as "Workflows, workflow runs and artifacts") β€” that's what lets Kevin see CI run status and logs. Do not grant the separate Workflows permission: despite the name it's write access to the .github/workflows/*.yml files, which Kevin never touches. Contents: Read is required: git fetch (behind github_fast_forward) and github_pr_diff both authenticate against it, and it grants no push ability. There is no Checks permission for fine-grained PATs β€” check runs are a GitHub App capability, so github_pr_checks 403s wherever CI reports as check runs; read build state from the run tools under Actions: Read instead.

When a call omits repo, Kevin resolves owner/repo from the origin remote of your AGENT_CODE_PATH, then the first AGENT_GIT_REPOS entry β€” the same codebase pair init configures. An explicit repo="owner/repo" always wins, so you can point any call at another repo the token can see.


πŸ”Ό How upgrades & releases work

Two halves of one machine: maintainers release (describe what changed and what a home needs), consumers upgrade (apply it). The contract between them is CHANGELOG.md.

graph LR
    A["/agent-kevin:release<br/>(maintainer)"] -->|CHANGELOG + tag| B["/plugin update<br/>(pull code)"]
    B -->|/agent-kevin:upgrade| C["your home<br/>reconciled"]
Loading

Why two steps at all? A plugin update replaces files in the plugin directory. Your home (CLAUDE.md, SOUL.md, .claude/settings.json, knowledge/, …) was copied out of templates/ once, at /init, and has been yours to edit ever since. A code update can't safely overwrite it. So the home is reconciled separately, on your terms.

How "you're behind" is detected β€” locally, no network. Your home records which template version it's on in .kevin/version.json (git-tracked, so it survives a clone). Compared against the installed plugin.json version, that yields three states, surfaced on the SessionStart banner and the dashboard's sidebar badge:

State Meaning Signal
current baseline == installed (nothing)
pending baseline < installed β€” migrations await amber badge "upgrade available Β· N"
onboard no version.json yet (home predates tracking) "enable update tracking"

The consumer flow β€” /agent-kevin:upgrade

  1. Scope. Reads the ### Upgrade blocks for every release between your baseline and the installed version (pending), or all of them on a first run (onboard). Handles being many versions behind in one pass.
  2. Coalesce. Merges the actions (latest wins) β€” the target is the current template state, not a replay of every intermediate edit.
  3. Back up. Snapshots every file it will touch into .kevin/updates/<from>-to-<to>/ before writing a byte.
  4. Apply. Auto-applies functionality-critical changes; asks before anything you may have personalized:
    • deps β†’ runs bun install in the MCP server
    • settings β†’ merges missing permissions.allow entries (never removes yours)
    • file β†’ copies new rule/concept files (only if absent)
    • template/<file> β†’ section-aware merge of CLAUDE.md / SOUL.md / etc.: adds new sections, updates changed ones, and preserves any sections you added (your personal blocks are never touched or deleted)
  5. Stamp. Writes the new baseline to .kevin/version.json.
  6. Sync. Finishes with /agent-kevin:sync so the dashboard, briefing, and knowledge reflect the new state (or tells you to reload first if MCP code/deps changed).

Safety guarantees: always backs up first Β· never overwrites a file wholesale Β· never deletes a section it doesn't recognize Β· only auto-applies what the release marked mandatory/additive Β· idempotent (re-running when current is a no-op).

The maintainer flow β€” /agent-kevin:release

  1. Diffs everything since the last v* tag and groups it into Added / Changed / Fixed.
  2. Detects what consumers need by inspecting the diff (dependency changes, touched templates/, new skills/tools needing permissions) and writes them as a machine- actionable ### Upgrade block.
  3. Bumps .claude-plugin/plugin.json (SemVer), prepends the CHANGELOG.md entry, and stages a commit + vX.Y.Z tag for your approval β€” it never commits or pushes on its own.

The Upgrade-block format

Each release carries an ### Upgrade section; every actionable line is a backticked tag plus a note. This is the exact text /agent-kevin:upgrade parses:

- `<kind>: <severity>` β€” <note>
kind severity what the upgrade does
deps required runs bun install
settings mandatory adds the named permission/hook/env entries
file additive copies a new file if absent
template/<f> mandatory section-merges, applied automatically
template/<f> optional section-merges, asks first with a diff
manual β€” a step only you can do; surfaced, never silent

A code-only release writes a single line: None β€” code-only, no bun install or HOME changes.


πŸ”‘ External accounts & costs

Kevin's core needs zero external accounts: tasks, knowledge compile, dashboard, session capture, and all four Playwright web tools (bundled chromium) run entirely on your machine against your Claude Code subscription. External accounts only enter the picture when you activate the SEO, Browser, or GitHub packs via /agent-kevin:configure-skills. Everything below is optional; skip this section if you don't need web search, SEO tooling, or PR/CI access.

Account What it unlocks Pack Credential Cost
Perplexity web_search: live web research with citations Browser PERPLEXITY_API_KEY Pay-as-you-go, $5 per 1,000 requests. A $5 credit lasts most personal users days to weeks.
GitHub github_pr_* / github_issue_* / github_run_*: read-only PR + issue review + CI diagnosis (needs the gh CLI). Also github_fast_forward, which keeps any local checkouts current during /agent-kevin:sync GitHub GITHUB_TOKEN (fine-grained, read-only PAT incl. Contents: Read) Free
Google Cloud gsc_* (Search Console data) + page_speed_* (Lighthouse audits) SEO OAuth client JSON at <HOME>/.kevin/secrets/google/google-oauth-client.json Free. PSI quota is 25k requests/day per project.
Google Search Console The site data behind gsc_query, gsc_inspect, and the audit skill SEO Your site verified under the same Google account Free
SerpAPI serpapi_search: live Google SERP positions for rank tracking SEO SERPAPI_KEY Free tier: 250 searches/month. Paid from $25/month (1,000 searches).
OpenPageRank open_page_rank: domain-authority proxy (0–10) for competitor tracking SEO OPENPAGERANK_API_KEY Free (1,000 requests/day; DomCop pledges to keep it free)

No account needed for the rest of the SEO pack: wordpress-rest reads the public /wp-json/wp/v2/ API of whatever site GSC_SITE_URL points at, and google-search-audit is a composite over the tools above. The knowledge pipeline never bills an API key either (see Claude Code Billing).

Bottom line: a typical personal setup runs at $0/month on free tiers. Heavy Perplexity use or serious rank tracking adds roughly $5 to $30/month.

Setting each one up

For every keyed service the flow is the same: /agent-kevin:configure-skills activates the pack and ensures the placeholder exists (secret keys β†’ .kevin/secrets/.env; the non-secret GSC_SITE_URL β†’ settings.local.json); you paste the value in your editor, never in chat.

Perplexity (web search): create an account at perplexity.ai, go to Settings β†’ API, load a small credit block ($5 is plenty to start), and generate a key. Note the API bills separately from a Perplexity Pro chat subscription (Pro only includes $5/month of API credit).

Google Search Console + PageSpeed (one free Google Cloud project covers both):

  1. console.cloud.google.com β†’ create a project (any name).
  2. APIs & Services β†’ Library β†’ enable Search Console API and PageSpeed Insights API.
  3. APIs & Services β†’ Credentials β†’ Create credentials β†’ OAuth client ID β†’ application type Desktop app. (First time, Google forces you through the consent-screen setup: choose External, add your own email as a test user.)
  4. Download the client JSON and save it as <HOME>/.kevin/secrets/google/google-oauth-client.json.
  5. Verify your site in Search Console under the same Google account, and set GSC_SITE_URL in settings.local.json (e.g. https://example.com/ or sc-domain:example.com).
  6. Run the google_auth MCP tool once (or bun run dispatch google-search-console auth from the plugin dir). A browser consent flow mints tokens that are cached and shared across all google-* tools; you won't be asked again.

SerpAPI (rank tracking): sign up at serpapi.com, copy the key from the dashboard. The free 250 searches/month comfortably covers a weekly audit of a small site; upgrade only if you track many keywords across devices and locales.

OpenPageRank (domain authority): sign up at domcop.com/openpagerank, generate the free key.


πŸ“ The one convention: launch from the agent home

Always start sessions from your agent home, then reach code from inside the session:

cd ~/Documents/Agents/Kevin && claude

Everything follows from this. The plugin is enabled in <HOME>/.claude/settings.json, so Claude Code loads it only for sessions started there. That single fact gives you the identity stack, the skills, the MCP tools, and session capture, and it's also what keeps multiple agents apart without any configuration.

Reaching your code. You don't cd to a repo to launch. You launch from the home and add the repos you work in to permissions.additionalDirectories in <HOME>/.claude/settings.local.json:

{
  "permissions": {
    "additionalDirectories": [
      "/Users/you/Developer/Acme",
      "/Users/you/Developer/side-project"
    ]
  }
}

Now Read, Edit, Grep and Bash all work against those trees while the session stays anchored to the brain. Set AGENT_CODE_PATH to your primary one and its git activity shows up in every session's context.

The session can wander, the anchor can't. Once running, cd anywhere you like. Claude Code exports CLAUDE_PROJECT_DIR (the launch directory, which never moves) to hooks and MCP servers, so capture still lands in the right brain even when the shell has roamed three repos deep.

What you give up

A session started outside a home isn't captured, and says nothing about it. No plugin loads, so there are no hooks to run. That's the trade for the isolation, and the failure is silent: the conversation simply never reaches your knowledge base. If you use a terminal multiplexer that opens workspaces at repo paths, check how it launches.

Earlier versions of this README recommended user-level hooks in ~/.claude/settings.json to capture every session machine-wide, with a KEVIN_HOME env var to route them. Don't. That variable is machine-wide and outranks launch-directory resolution, so it hands every session on the box to one brain and makes a second agent unreachable. The hooks it fed needed a self-defer mode, an enabled-plugin probe, and repeatable --exclude flags just to avoid writing into a sibling agent's memory. All of it is gone; plugin hooks are the only supported path.

Don't put any KEVIN_* variable in ~/.claude/settings.json. One value, every home. Per-home config belongs in <HOME>/.claude/settings.local.json under the neutral AGENT_* names, where its location scopes it.

Running the CLI outside a session

bin/kevin resolves its home from the current directory, and a plain terminal has no CLAUDE_PROJECT_DIR to fall back on. Run it from inside the home, or point it at one:

KEVIN_HOME=~/Documents/Agents/Kevin kevin task query --status=active

Anywhere else it refuses and tells you what it resolved, rather than scaffolding a knowledge/ tree into whatever repo you were standing in.


🏷️ Naming your agent

The plugin is agent-kevin, but your agent doesn't have to be called Kevin. Two separate things:

Lives in Changeable
Display name β€” what it calls itself, what the dashboard shows IDENTITY.md β†’ - **Name:** freely, any time
Namespace β€” /agent-kevin: commands, KEVIN_* vars, .kevin/, MCP tool names the plugin manifest only by forking

/agent-kevin:init asks for a name, an emoji and an avatar up front. Everything downstream reads the answer: the templates are written in that name, the session banner and TASKS.md header render it, and the knowledge-compile prompts refer to it, so your compiled memory speaks about the agent you actually named.

Already have a home? /agent-kevin:rename-agent does the migration. It only runs when you type that command β€” it never fires on its own β€” and it asks for permission even then, because it rewrites files across the whole brain in one pass. It: rewrites the persona fields, swaps the avatar, sweeps the prose across SOUL.md / CLAUDE.md / USER.md / knowledge / projects, and leaves the plumbing alone. It won't touch your home directory path, so ~/Documents/Agents/Kevin in a settings file or a wiki page survives intact.

Renaming survives updates. /agent-kevin:upgrade resolves {{AGENT_NAME}} in the shipped templates from your IDENTITY.md before diffing, so template changes arrive phrased in your agent's name instead of proposing "Kevin" back on every release. The persona block is never reconciled at all.

Forking is a different decision. Change name in .claude-plugin/plugin.json and the env prefix follows automatically (agent-scout reads SCOUT_*), giving you your own slash-command namespace. The price is merging from upstream on every release, forever. If you only want the agent to feel like yours, rename it and skip the fork.


πŸ” Privacy

  • All data stays local. Your agent home is markdown on your disk. No cloud sync unless you choose to commit it to git.
  • Secrets live in the deny-gated .kevin/secrets/.env (API keys, DB connection strings, Google OAuth), non-secret config in .claude/settings.local.json, runtime state in .kevin/ β€” all gitignored by default. The plugin's .gitignore includes them, and Kevin's own tools are blocked from reading .kevin/secrets/.
  • Transcripts are redacted before persisting. The session-capture hook exact-matches every value in .kevin/secrets/.env (plus any in settings.local.json) and runs prefix heuristics for common key formats.
  • Anthropic training opt-out + telemetry disable is recommended on your Claude Code install. See docs.claude.com.
  • The folder is the product. If anything goes wrong, the markdown + git history is the complete backup.

πŸ–₯️ Platform support

Built and tested on macOS. The plugin also runs on Linux (one caveat: chromium auto-install via playwright is sometimes flaky in headless sandboxes β€” on a fresh distro run playwright install-deps chromium once) and on Windows, both native and via WSL2.

  • Native Windows works through Git Bash β€” the shell Claude Code uses for its Bash tool β€” which supplies the POSIX environment the hooks, MCP server, and per-skill bash patterns (e.g. Bash(git log *)) assume. Requirements: bun and git on PATH. Rough edges to know about: MSYS path-mangling can bite commands that pass colon-paths or unix-style absolute paths (MSYS_NO_PATHCONV=1 is the escape hatch); the OS sandbox is unavailable (Windows has no equivalent, so the sandbox block is omitted); and a few pack-gated skills assume tools Git Bash doesn't ship (e.g. serpapi pipes through jq). The core loop β€” tasks, compile, memory, briefings, worktrees, dashboard β€” runs natively.
  • WSL2 is the closest-to-Linux-production option: run everything from inside the distro, where Kevin shares the same POSIX path as Linux.

If you run Kevin on Linux, native Windows, or WSL2 and hit a platform-specific snag, please open a PR with install notes or a fix.


πŸ’³ Claude Code Billing

/agent-kevin:knowledge-compile is the showcase of how this plugin handles billing. Other personal-AI setups call the LLM internally, which bills against a metered API key. This plugin doesn't. The MCP server returns a synthesis prompt; you, in your interactive Claude Code session, do the synthesis; the MCP server confirms the write. The thinking happens inside your TUI turn, so it draws from your Claude Code subscription pool (Max / Pro / Teams), not a per-token API bucket.

Verify it yourself:

  1. Open Anthropic Console β†’ Usage. Note current API cost.
  2. Run /agent-kevin:knowledge-compile inside Claude Code.
  3. Refresh Usage. API cost should not change. Subscription usage should increment.

If it does change, open an issue β€” that assumption was wrong.

A note on what Kevin used to be

Kevin started life as a much more ambitious thing: a standalone Bun daemon running a Telegram bot for the whole family, a cron-style heartbeat scheduler that woke Kevin up at 7am to send morning briefings, evening wraps that arrived while you were cooking dinner, the homeschool planner that produced actual printable HTMLs for the kids before the school week, autonomous knowledge compiles every six hours. The brain was the same markdown folder you see here. The body was a long-running process talking to the Claude Agent SDK on your behalf, calling out from your phone, the office, the car.

Then Anthropic closed off the Claude Agent SDK from subscription billing. Headless SDK calls became pay-per-token-API only. The whole point of Kevin was that he ran on your Max/Pro subscription bucket, not a metered API; the cost ceiling was a flat monthly bill, not "what did Kevin do while you were sleeping." Without subscription-backed SDK, the daemon model couldn't survive.

So Kevin had to die a little bit inside, and Kevin had to be reborn as a Claude Code plugin. The brain is intact. The skills got ported. The MCP server runs locally, returning prompts that you, in your TUI session, synthesize using your subscription. That's why everything in this plugin is structured to make Claude Code do the LLM work, not the plugin itself. No API charges, ever.

What that means in practice:

  • βœ… You drive every session. Kevin is reactive, not proactive. You type claude, Kevin loads, you ask.
  • ❌ No proactive messaging. No "morning briefing at 7am" delivered to your phone. You run /agent-kevin:morning-briefing when you sit down.
  • ❌ No Telegram bridge. No texting Kevin from the airport.
  • ❌ No cron daemon. External schedulers (launchd, cron, GitHub Actions) can invoke Kevin via claude --print, but they pay-per-token-API. Inside-CC manual runs stay subscription-billed.
  • βœ… Everything else. Memory compounding, the wiki pipeline, projects, tasks, audits, briefings on demand. All here.

If Anthropic ever reopens the Agent SDK to subscription billing, we'll happily revive the daemon. Until then, this plugin is the maximum amount of Kevin that fits inside the rules.

❓ Common questions

Q: Do I need to be a developer to use this? A: You need to clone a git repo, run bun install, and launch Claude Code. After that, the entire experience is conversational. /agent-kevin:init walks you through everything.

Q: I finished /init and relaunched, but no SessionStart banner appears. A: The marketplace trust prompt was missed. Recover inside Claude Code with /plugin marketplace add github:AgentLayer1/agentlayer-claude-marketplace followed by /plugin install agent-kevin@agentlayer, then /exit and relaunch.

Q: I already had a CLAUDE.md in this directory before installing Kevin. Did it get overwritten? A: No. Init detects pre-existing CLAUDE.md and writes Kevin's operating manual to CLAUDE.local.md instead. Both files load at session start.

Q: How do I update the plugin? A: /plugin marketplace update agentlayer from inside Claude Code. Or if you cloned locally, git pull the marketplace repo. Your <HOME>/ data is untouched.

Q: How do I uninstall? A: /plugin uninstall agent-kevin@agentlayer. Your <HOME>/ data stays. To purge everything: rm -rf <HOME>/.

Q: Will Kevin ever message me first? A: No. See Claude Code Billing. Inside Claude Code, you initiate every session. External schedulers can pipe prompts into claude --print but those go through pay-per-token API.

Q: Subscription billing, does it really avoid API costs? A: For the LLM synthesis steps yes. The MCP server is pure I/O, returning prompts; your interactive Claude Code session does the thinking using your subscription quota. To verify: note Anthropic Console β†’ Usage before running /agent-kevin:knowledge-compile, refresh after. API cost should not change; subscription usage should increment.


πŸ› οΈ Agentic Coding Tips

macOS-only. Kevin runs anywhere Claude Code does, but the tooling below is what I (the author) actually use day to day on a Mac. Linux/Windows users: most have equivalents, but the specifics here assume macOS.

Running agents well is less about the model and more about the rig around it: a fast terminal, sane keybindings, isolated worktrees, and a place to read the markdown brain. Here's the setup that makes driving Kevin (and a swarm of other agents) genuinely pleasant.

1. Terminal: Ghostty

Ghostty is a GPU-accelerated, native-Mac terminal. It's fast (120fps, zero input lag even with agents streaming walls of output), it's native AppKit (no Electron tax), and the config is a single readable file. After bouncing through iTerm2 and the rest, this is the one that stuck. The 25MB scrollback alone is worth it when an agent dumps a long trace and you need to scroll back through all of it.

πŸ“„ My Ghostty config β€” ~/.config/ghostty/config (a starting point, not gospel)
# Typography
font-family = JetBrainsMonoNerdFont
font-size = 14
font-thicken = true
adjust-cell-height = 2

# Theme and Colors β€” Catppuccin with automatic light/dark switching
theme = light:Catppuccin Latte,dark:Catppuccin Mocha

# Window and Appearance
background-opacity = 0.9
background-blur-radius = 20
macos-titlebar-style = transparent
window-padding-x = 10
window-padding-y = 8
window-save-state = never
quit-after-last-window-closed = true
window-theme = auto

# Cursor
cursor-opacity = 0.8

# Mouse
mouse-hide-while-typing = true

# Security
clipboard-paste-protection = true
clipboard-paste-bracketed-safe = true

# Shell Integration
shell-integration = detect

# Keybindings β€” tabs
keybind = cmd+t=new_tab
keybind = cmd+shift+left=previous_tab
keybind = cmd+shift+right=next_tab
keybind = cmd+w=close_surface

# Splits
keybind = cmd+d=new_split:right
keybind = cmd+shift+d=new_split:down
keybind = cmd+alt+left=goto_split:left
keybind = cmd+alt+right=goto_split:right
keybind = cmd+alt+up=goto_split:top
keybind = cmd+alt+down=goto_split:bottom

# Font size
keybind = cmd+plus=increase_font_size:1
keybind = cmd+minus=decrease_font_size:1
keybind = cmd+zero=reset_font_size

# Splits management
keybind = cmd+shift+e=equalize_splits
keybind = cmd+shift+f=toggle_split_zoom

# Reload config (Cmd+Shift+,)
keybind = cmd+shift+comma=reload_config

# Performance β€” generous scrollback (25MB)
scrollback-limit = 25000000

# Command finished notifications
notify-on-command-finish = unfocused
notify-on-command-finish-action = no-bell,notify
notify-on-command-finish-after = 30s

# Working directory inheritance
window-inherit-working-directory = false
tab-inherit-working-directory = true
split-inherit-working-directory = true

2. Essential keybindings

These are readline (emacs-style) bindings that work in the Claude Code prompt and your shell. Internalize them and you stop reaching for arrow keys:

Keys Does
Cmd + ← / Cmd + β†’ Jump to start / end of line
Ctrl + A / Ctrl + E Start / end of line (readline equivalent)
Ctrl + W Delete the word before the cursor
Ctrl + K Kill from cursor to end of line
Ctrl + U Clear the whole line
Option + ← / Option + β†’ Move one word at a time

Ctrl + W and Ctrl + K are the two that pay for themselves daily β€” chopping a half-typed prompt back a word at a time beats holding backspace.

3. cmux: orchestrate many agents at once

cmux is a native-Mac terminal built on Ghostty (it renders via libghostty and reads your existing Ghostty config, so the look and keybindings above carry straight over). It's purpose-built for the parallel-agent era: instead of one terminal with one Claude session, you get workspaces in a vertical sidebar, each showing its git branch, PR status, working directory, and the latest agent notification.

Why it's great for driving Kevin and friends:

  • One workspace per agent task. Kick off Kevin in one, a coding agent in another, a long research run in a third. Split panes within a workspace for the editor + logs + agent.
  • Notifications that tell you who's waiting. When an agent finishes or needs input, its pane gets a ring and the sidebar tab lights up, so you know which of your six running agents wants attention without staring.
  • Organize like a file system. Group related workspaces into folders, color-code by project (Kevin home = one color, each repo = another), and the sidebar becomes a live map of everything in flight.
  • Session restore. It saves and restores workspace layouts, directories, and scrollback, so closing the lid doesn't lose your swarm.

cmux is open source (AGPL-3.0, by Manaflow AI). It pairs naturally with worktrees (next tip) β€” one workspace per worktree, one agent per workspace.

4. Turn on CLAUDE_CODE_NO_FLICKER

Add this to your user-level ~/.claude/settings.json env block:

{ "env": { "CLAUDE_CODE_NO_FLICKER": "1" } }

It's an alias for Claude Code's fullscreen renderer, and it fixes more than the name suggests:

  • Click-to-position in the prompt. This is the big one. Fullscreen mode enables mouse tracking, so you can click anywhere in your prompt text to move the cursor instead of arrow-keying across a long instruction. Without it, clicks fall through to the terminal and the prompt cursor never moves.
  • No flicker. It draws on the alternate screen buffer (like vim/htop) and virtualizes rendering, so the input box stays pinned to the bottom and streaming output doesn't make the screen jump.
  • Flat memory in long sessions. Only visible messages render, so a marathon session doesn't bloat.

5. Git worktrees: parallel agents, one repo, zero collisions

A git worktree checks out a second (third, fourth) working copy of the same repo into a separate folder, each on its own branch, all sharing one .git. This is the unlock for running multiple agents on the same codebase without them stepping on each other's files:

# From inside the repo β€” spin up an isolated copy on a new branch
git worktree add ../myrepo-feature-x -b feature-x
git worktree add ../myrepo-bugfix   -b bugfix-y

git worktree list      # see them all
git worktree remove ../myrepo-feature-x   # clean up when merged

Point one cmux workspace (and one agent) at each worktree. Agent A refactors on feature-x while Agent B fixes a bug on bugfix-y, no merge conflicts mid-flight, no "wait, why did my file just change" surprises. When a branch lands, remove the worktree and the folder's gone. (Claude Code's own background agents use the same trick under the hood.)

Two conventions make this painless (and Kevin follows both):

  • Worktrees are siblings of the main repo, never nested inside it. The main checkout lives at, say, ~/Developer/Acme/tech/acme, so a worktree lands one level up alongside it: ~/Developer/Acme/tech/acme-my-feature. From the main checkout, the ../ keeps it at the same level: git worktree add ../acme-my-feature -b feat/my-feature. A nested worktree would sit under a tracked path and pollute the parent's working tree.
  • A fresh worktree needs its gitignored local files before it can run. A new checkout has no .env*, no .claude/settings.local.json, no installed deps or built packages. You need to copy the machine-local config over from the main checkout, install, and build before the branch is workable.

You can just ask Kevin to do all of this. The bundled setup-worktree skill (/agent-kevin:setup-worktree, like every Kevin skill it only acts when you ask) first pins down which repo you mean (it asks when the HOME sits above several repos), creates the worktree as a sibling on a new branch, then bootstraps it: it copies the gitignored local files (.env*, .claude/settings.local.json, .cursor, .cmux) from the main checkout, detects the package manager (bun / pnpm / yarn / npm), installs, and runs the repo's build script. Say "make a worktree for the billing refactor" and you get a ready-to-code checkout. Under the hood the skill calls the bundled setup_worktree MCP tool, which runs outside the Bash sandbox so git worktree add can make the writes the seatbelt blocks (the main repo's .git/config and checked-out config like .vscode/settings.json / .mcp.json). The same logic is on the CLI for a real terminal: kevin worktree <repoPath> --branch=....

πŸ’‘ Managing worktrees from the CLI gets tedious. Tower has an excellent worktree GUI to create, switch, and prune them visually. See tip #10.

6. Editor: VS Code, not Cursor

If your terminal (cmux) is now the primary place agents do work, Cursor is overkill. Cursor's whole pitch is an AI layer baked into the editor, but when Claude Code and other agents live in the terminal driving the actual changes, you're paying for a second AI surface you don't use. Drop back to plain VS Code for reading diffs, quick manual edits, and extensions. The editor becomes a viewer/tweaker; the terminal is the cockpit.

7. Obsidian: read the brain as a graph

Kevin's entire memory is markdown with [[wikilinks]], and so is almost everything an agent touches: tasks, project READMEs, plans, reports, knowledge articles. Working with agents is working in markdown all day. Open <HOME>/ as an Obsidian vault and that whole tree comes alive β€” it's a far nicer reader/editor for the projects, tasks, and notes than a code editor:

  • A real markdown workspace. Browse and edit projects/, knowledge/, reports, and daily memory with proper rendering, outline, search, and tags. This is where you live when you're reading what Kevin (and your other agents) wrote.
  • Graph view turns the knowledge base into a visual map β€” concepts, projects, memory, and user facets as linked nodes. You can see what's densely connected and what's orphaned.
  • Working wikilinks + backlinks for navigating between concepts, tasks, and daily memory the way Kevin wrote them.
  • HTML-viewer plugins (e.g. an "HTML Reader" community plugin) let you open the generated Agent OS dashboard (<HOME>/dashboard.html) rendered, right inside Obsidian, next to the notes it summarizes. Combined with the MARKDOWN_URL setting (obsidian://open?path={path}), dashboard links open notes rendered in a new tab.

8. MarkEdit: native markdown + styled PDF export

MarkEdit is a free, open-source, native-Mac markdown editor (think "TextEdit for Markdown"). It's fast, distraction-free, and deeply Mac-integrated: Quick Open, system Quick Look, and a live preview so you see rendered output beside the source. The markedit-preview extension adds the live HTML preview pane.

The payoff is a clean Markdown β†’ HTML β†’ PDF export pipeline for anything you want to look polished (a business plan, a one-pager, a report Kevin generated). I run mine through a custom panda-doc stylesheet β€” a CSS theme that styles the exported HTML (typography, spacing, headings, code blocks) so the resulting PDF looks designed, not dumped. Drop your own stylesheet in, export to HTML, then print/render to PDF (Kevin's browser_pdf tool can also do the HTML β†’ PDF step with your CSS applied).

9. Folder structure: brains in Documents, code in Developer

The mental model that keeps multi-agent setups sane: agent brains are standalone vaults under ~/Documents/Agents/; all code lives flat in a separate ~/Developer/ tree. Never nest one inside the other.

~/Documents/Agents/              # every agent brain lives here
β”œβ”€β”€ Kevin/                       #   the personal agent β€” knowledge + projects, no code
β”‚   β”œβ”€β”€ knowledge/  projects/  reports/
β”‚   β”œβ”€β”€ SOUL.md / IDENTITY.md / USER.md
β”‚   └── .git  β†’  gitdir pointer (internals live in the code tree, see below)
└── Acme/                        #   a forked company agent (fictitious "Acme"), same shape

~/Developer/Acme/                # that company's code root β€” flat, no brain
β”œβ”€β”€ repo-one/                    #   main checkout
β”œβ”€β”€ repo-one-my-feature/         #   worktrees as siblings (tip #5)
└── agent-acme-data.git          #   the brain's git internals, out of the vault

Why the split earns its keep: the brain opens cleanly as an Obsidian vault (no thousands of source files to index or exclude), you can run many brains against one code tree, and ~/Documents syncing (iCloud) never drags repos with it. The brain's git internals live outside the vault via git init --separate-git-dir β€” the vault keeps a one-line .git pointer file, so version control works normally while sync tools only ever see markdown. Wake an agent with cd ~/Documents/Agents/<Name> && claude; point a coding session at a repo with cd ~/Developer/<Org>/<repo>. One agent per role/company, each with its own brain, and the brain you launched in is the one you get: the home is resolved from the launch directory, which doesn't roam even when the session cds into a repo.

Two homes can run off the same plugin install (a work agent and a personal one, both agent-kevin) β€” they stay isolated by location, and each one's IDENTITY.md gives it its own name via /agent-kevin:rename-agent. The one rule: don't pin KEVIN_HOME (or any KEVIN_*) in user-level settings or your shell rc when you run more than one home. It's machine-wide, it beats launch-directory resolution outright, and it hands every session to a single brain. Per-home config goes in <HOME>/.claude/settings.local.json under the neutral AGENT_* names.

10. Tower for git review

VS Code's built-in git is fine for staging a quick commit, but for reviewing history, diffs, and branch topology it's cramped. Tower gives you a proper visual overview: a clear commit graph, side-by-side diffs that are actually readable, interactive rebase/stage-by-hunk, fast branch navigation, and (per tip #5) a first-class worktree manager. When you're reviewing what three agents did across three worktrees before merging, a real git client earns its keep.


⚠️ Known limitations

  1. CC must open in <HOME> for static identity to load. Outside, you only get the dynamic lane.
  2. Sandbox can block .claude/skills/ writes during /agent-kevin:configure-skills. Pre-create the dir from a normal terminal if it hits the wall.
  3. Playwright + macOS sandbox. Browser launch can fail inside CC's sandboxed subprocesses (XPC walls). Workaround: install playwright manually in a normal terminal so chromium caches.
  4. No live GUI. The Agent OS dashboard at <HOME>/dashboard.html is a static snapshot regenerated on sync (or kevin dashboard), not a served app β€” between syncs it can drift from task frontmatter.
  5. Single-user. Multi-user / team-isolation isn't built in. Workaround: separate homes per user.
  6. No proactive Kevin. See Claude Code Billing. External schedulers can run Kevin via claude --print, but those calls bill against API quota, not your subscription.

🀝 Contributing

Pull requests welcome. Particularly interested in:

  • New skill packs that ship as opt-in via configure-skills
  • New MCP dispatch tools that fit the read-mostly + key-gated model
  • Linux / Windows platform notes
  • Documentation improvements, more use-case examples
  • Translations / regional compliance hints

Open an issue first for architectural changes. Kevin's contract with <HOME>/ markdown is intentional and worth preserving.


πŸ“œ License

Licensed under the Apache License, Version 2.0.

agent-kevin is Β© AgentLayer Β· agentlayer.one. See NOTICE for the attribution stanza.

Third-party skill libraries installable via /agent-kevin:configure-skills are not bundled with this plugin. They install via skills.sh into <HOME>/.claude/skills/, each carrying its own LICENSE. Review each library's terms before relying commercially.


AgentLayer

Built by AgentLayer Β· agentic infrastructure for AI-native operations

Kevin is named after the loyal minion. Helpful, enthusiastic, a little nerdy.

About

Portable, file-based personal AI assistant.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages