A grumpy senior code reviewer for Claude Code and Codex. He reviews your changes, tells you what's wrong, and never suggests fixes.
More at askmarko.xyz.
**Verdict:** bad
Three concurrency bugs and a log line leaking PII.
1. `src/worker.ts:42` — retry loop has no backoff; an upstream outage will hammer the service.
2. `src/worker.ts:89` — `sessionId` is compared with `==` to a request string; type confusion on integer IDs.
3. `src/auth.ts:14` — full email logged at info; move to debug or redact.
4. `src/queue.ts:110` — inner `flush()` is not awaited; writes can be dropped on shutdown.
- Reviews your current
git diff, branch diff, or recent edits. - Returns a one-word verdict:
catastrophe/bad/mediocre/ok. - Lists concrete,
file:line-anchored gripes that a coding agent can act on directly. - Never suggests fixes. Never softens. Never pads. "ok" is the ceiling and it is rare.
The point is signal-to-noise. A review that ends "LGTM, ship it" contains no information. Marko's does.
One command, installs for both tools:
curl -fsSL https://raw.githubusercontent.com/julianmemberstack/marko/main/install.sh | bashFlags:
# Just one tool
curl -fsSL https://raw.githubusercontent.com/julianmemberstack/marko/main/install.sh | bash -s -- --claude-only
curl -fsSL https://raw.githubusercontent.com/julianmemberstack/marko/main/install.sh | bash -s -- --codex-onlyOr manually:
- Claude Code: copy
SKILL.mdto~/.claude/skills/marko/SKILL.md - Codex: copy
codex/marko.mdto~/.codex/prompts/marko.md
Address him by name. Natural language triggers the skill:
marko?what do you think marko?hey marko, take a lookmarko thoughts on this branch?
He picks what to review in this order: uncommitted git diff → branch diff → recently edited files → asks you.
You will need to restart your Claude Code session once after install so the new skill is picked up.
Type /marko in a session. Same behavior, different entry point — Codex doesn't have skill auto-triggering, so it's an explicit slash command.
Want Marko watching while you work? In Claude Code:
/loop 10m marko?
Or wire a Stop hook in ~/.claude/settings.json so he chimes in after every turn.
Marko is a prompt, not a tool. The repo contains two files:
SKILL.md— the Claude Code skill. Skills are markdown with YAML frontmatter that Claude Code loads at session start. Thedescriptionfield is what Claude consults to decide when to invoke the skill, which is why Marko triggers on being addressed by name.codex/marko.md— the Codex custom prompt. Plain markdown injected into the conversation when you type/marko.
The two files contain the same instructions with minor framing differences (third-person "Marko does X" vs. second-person "you do X") so each tool's invocation model reads naturally.
A few deliberate choices that make Marko actually useful instead of just funny:
- No praise inflation. "ok" means the code is actually good. This is the point of the whole exercise — a verdict is only information if it distinguishes good from bad.
- No suggested fixes. Forces each complaint to stand on its own. Vague critique gets exposed when you can't hide it behind a proposed solution. Also keeps the output short.
file:lineanchors on every gripe. The output is designed to be consumed by another agent (Claude Code, Codex) that then fixes the issues. Vague complaints are useless for that; concrete ones are actionable.- Few words. A reviewer who writes three paragraphs per gripe is not reviewing, they are performing.
- No caricature. The "grumpy senior engineer" persona exists to strip out flattery and verbosity. No accent, no stereotypes, no theatre.
rm -rf ~/.claude/skills/marko ~/.codex/prompts/marko.mdMIT. See LICENSE.