Your personal AI assistant, as a Claude Code plugin. One markdown folder, one plugin, a brain that learns who you are session after session.
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), androadmap(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.
π¦ 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.
First, cd to wherever you want Kevin's brain to live and launch Claude Code:
mkdir -p ~/Documents/Agents/Kevin && cd ~/Documents/Agents/Kevin
claudeInside 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).
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
claudeInside 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.mdin the directory? Kevin writes its operating manual toCLAUDE.local.mdinstead and leaves yours alone. Both files load at session start.
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.
/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.
graph LR
A[Sessions] -->|capture| B[Knowledge]
B -->|informs| C[Projects]
C -->|generate| D[Results]
D -->|feed back into| A
The flywheel. Every session makes Kevin smarter. Every project generates knowledge. Every piece of knowledge makes the next session better.
- π§ Memory that compounds. The
SessionEndandPreCompacthooks copy your conversation toknowledge/raw/sessions/. Theknowledge-compileskill 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).
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
autobadge when the model may self-invoke it), every MCP tool, the fullkevinCLI 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.htmlsits 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.
> /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), orCLAUDE.local.mdif a CLAUDE.md already existsSOUL.md,IDENTITY.md,USER.md(Kevin's character / role / your headline)knowledge/andprojects/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 viaconfigure-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 byconfigure-skills; every secret credential (PERPLEXITY_API_KEY,SERPAPI_KEY,OPENPAGERANK_API_KEY,GITHUB_TOKEN,AGENT_DB_*) goes in the deny-gated.kevin/secrets/.envinstead. 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.
The plugin registration in .claude/settings.json only takes effect on a fresh session. After init:
/exit
cd ~/Documents/Agents/Kevin && claudeWatch 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.
$ 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.
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
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.
/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/<slug>/<br/>tasks/archive/)]
C5 -.unconditional snapshot.-> FLYREP[/reports/briefings/<br/>flywheel/<slug>.md/]
C7 -.one call, both views.-> TASKS[/projects/TASKS.md<br/>+ dashboard.html/]
ASK -.act now.-> TASKMUT
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.
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
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
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 thereport_writeMCP 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.
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.
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.
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 configuredThe 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.
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:initInit 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.
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.
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.zipThe 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.
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
| 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 |
| 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-creatorplugin that does exactly that. Use it for your own 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.
- Perplexity, live web search with citations (
mcp__plugin_agent-kevin_kevin__web_search). Built into thekevinMCP 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/.envstore exists for aPERPLEXITY_API_KEYline), then fill the key value in your editor βconfigure-skillsnever 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 filebrowser_pdfβ styled PDF (markdown + mermaid rendered)browser_markdownβ JS-rendered page β clean Markdown via Readabilitybrowser_recordβ scripted page interactions β WebM video
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 includingcontent-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".
| 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.
- 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.mdwith 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.
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
<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.
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 referencekevin 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 compileNote: 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.
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.)
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 BThis 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
/loginbetween mints.setup-tokenissues a token for whatever account you're currently logged into; running it twice without switching yields two tokens for the same subscription. - The
envblock is read at launch, not hot-reloaded. Adding the token to an open session does nothing; restartclaude. - Launch from the home root.
settings.local.jsonresolves from the launch directory β the same convention everything else here relies on. - Nothing higher-precedence may shadow it. An
ANTHROPIC_API_KEYorANTHROPIC_AUTH_TOKENin your shell rc or~/.claude/settings.jsonsilently outranks the token machine-wide. - Verify with
/status+/usage, not the shell./statusshows the auth method (CLAUDE_CODE_OAUTH_TOKENvs the/loginfallback) but not the account; the definitive test is independent/usagemeters β heavy work in one home should move only that account's usage.echo $CLAUDE_CODE_OAUTH_TOKENin 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.
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/analyticsThat 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.
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.
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"]
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" |
- Scope. Reads the
### Upgradeblocks 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. - Coalesce. Merges the actions (latest wins) β the target is the current template state, not a replay of every intermediate edit.
- Back up. Snapshots every file it will touch into
.kevin/updates/<from>-to-<to>/before writing a byte. - Apply. Auto-applies functionality-critical changes; asks before anything you
may have personalized:
depsβ runsbun installin the MCP serversettingsβ merges missingpermissions.allowentries (never removes yours)fileβ copies new rule/concept files (only if absent)template/<file>β section-aware merge ofCLAUDE.md/SOUL.md/ etc.: adds new sections, updates changed ones, and preserves any sections you added (your personal blocks are never touched or deleted)
- Stamp. Writes the new baseline to
.kevin/version.json. - Sync. Finishes with
/agent-kevin:syncso 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).
- Diffs everything since the last
v*tag and groups it into Added / Changed / Fixed. - Detects what consumers need by inspecting the diff (dependency changes, touched
templates/, new skills/tools needing permissions) and writes them as a machine- actionable### Upgradeblock. - Bumps
.claude-plugin/plugin.json(SemVer), prepends theCHANGELOG.mdentry, and stages a commit +vX.Y.Ztag for your approval β it never commits or pushes on its own.
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.
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.
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):
- console.cloud.google.com β create a project (any name).
- APIs & Services β Library β enable Search Console API and PageSpeed Insights API.
- 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.)
- Download the client JSON and save it as
<HOME>/.kevin/secrets/google/google-oauth-client.json. - Verify your site in Search Console under the same Google account, and set
GSC_SITE_URLinsettings.local.json(e.g.https://example.com/orsc-domain:example.com). - Run the
google_authMCP tool once (orbun run dispatch google-search-console authfrom the plugin dir). A browser consent flow mints tokens that are cached and shared across allgoogle-*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.
Always start sessions from your agent home, then reach code from inside the session:
cd ~/Documents/Agents/Kevin && claudeEverything 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.
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.
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=activeAnywhere else it refuses and tells you what it resolved, rather than scaffolding a knowledge/ tree into whatever repo you were standing in.
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.
- 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.gitignoreincludes 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 insettings.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.
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
bashpatterns (e.g.Bash(git log *)) assume. Requirements:bunandgitonPATH. Rough edges to know about: MSYS path-mangling can bite commands that pass colon-paths or unix-style absolute paths (MSYS_NO_PATHCONV=1is 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.serpapipipes throughjq). 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.
/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:
- Open Anthropic Console β Usage. Note current API cost.
- Run
/agent-kevin:knowledge-compileinside Claude Code. - Refresh Usage. API cost should not change. Subscription usage should increment.
If it does change, open an issue β that assumption was wrong.
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-briefingwhen 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.
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.
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.
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 = trueThese 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.
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.
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.
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 mergedPoint 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.
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.
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 theMARKDOWN_URLsetting (obsidian://open?path={path}), dashboard links open notes rendered in a new tab.
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).
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.
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.
- CC must open in
<HOME>for static identity to load. Outside, you only get the dynamic lane. - Sandbox can block
.claude/skills/writes during/agent-kevin:configure-skills. Pre-create the dir from a normal terminal if it hits the wall. - 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.
- No live GUI. The Agent OS dashboard at
<HOME>/dashboard.htmlis a static snapshot regenerated on sync (orkevin dashboard), not a served app β between syncs it can drift from task frontmatter. - Single-user. Multi-user / team-isolation isn't built in. Workaround: separate homes per user.
- 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.
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.
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.
Built by AgentLayer Β· agentic infrastructure for AI-native operations
Kevin is named after the loyal minion. Helpful, enthusiastic, a little nerdy.
