# Elek

> Review-only AI code review for GitHub pull requests. Cross-check PRs with model-agnostic reviewers that can comment inline but cannot approve, merge, or close.

- **Type:** MCP server
- **Install:** `agentstack add mcp-selimozten-elek`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [selimozten](https://agentstack.voostack.com/s/selimozten)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [selimozten](https://github.com/selimozten)
- **Source:** https://github.com/selimozten/elek
- **Website:** https://elek.sh

## Install

```sh
agentstack add mcp-selimozten-elek
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Review-only AI for pull requests.
  Cross-check PRs with independent AI reviewers while keeping every model inside a narrow, non-destructive tool surface.

  
  

elek is an open AI code-review engine for GitHub pull requests. It posts
normal review comments and inline threads, but it cannot approve, merge, close,
or mutate your base branch in review mode. That constraint is structural: the
MCP server only exposes review-comment tools, and the starter workflow grants
read-only contents access.

Use it today as a self-hosted GitHub Action with your own model keys. The
hosted GitHub App is the planned zero-config install path for teams that want
branded reviews, centralized settings, and hosted analytics.

It can run one reviewer, a two-lens cross-check, or a four-lens council with any
provider [pi](https://github.com/earendil-works/pi) supports: DeepSeek,
OpenRouter, OpenAI, Anthropic, Google, Bedrock, Vertex, Groq, Mistral,
Together, xAI, and more.

If you want safer AI code review to become boring infrastructure, star the repo
and try it on one real PR.

See it reviewing a real tenant-isolation regression:
[elek-demo#1](https://github.com/selimozten/elek-demo/pull/1).

## One-minute setup

From your repository root:

```bash
npx --package github:selimozten/elek elek-init --provider deepseek
```

Then add one repo secret:

```text
DEEPSEEK_API_KEY
```

Commit the generated `.github/workflows/elek.yml` and `.elek.yml`, open a PR,
and elek will post a live progress comment followed by a structured review with
inline findings on changed lines.

Prefer another provider?

```bash
npx --package github:selimozten/elek elek-init --provider openrouter --model moonshotai/kimi-k2.7-code
npx --package github:selimozten/elek elek-init --provider anthropic --model claude-sonnet-4-6
```

| Path | Status | Use it for |
|---|---|---|
| Hosted GitHub App | Planned primary path | Branded reviews, simple onboarding, hosted analytics, team settings |
| Self-hosted GitHub Action | Available today | BYOK reviews, auditable runs, custom workflow control |
| CLI tools | Available today | Feedback adjudication, saved-run analytics, benchmark evaluation |

## Why elek

| | elek | single-provider review actions | general-purpose CLI actions |
|---|---|---|---|
| **Providers** | 11+ (any pi target) | usually one provider | usually one provider |
| **Per-review cost** | ~$0.005 (deepseek) | often premium-model priced | varies by hosted stack |
| **Inline review threads** | ✓ via MCP | often supported | partial |
| **Iterates on prior findings** | ✓ | often supported | partial |
| **Structural safety** | ✓ no merge/approve/close paths | often broader PR API access | often broader repo access |
| **Modules** | small TypeScript core | larger vendor stack | larger platform stack |
| **Runtime** | Hosted App planned; Action/CLI available | provider CLI/runtime | provider CLI/runtime |

**Bias toward cheap, capable models.** DeepSeek-v4-Pro plus Kimi K2.7 Code through OpenRouter gives you two independent review passes without defaulting to one expensive model. Run them in parallel for cross-validation; reserve premium validators for the highest-risk PRs.

## Hosted App status

The public GitHub App install is planned and not yet open. Normal product
onboarding should become "Install the elek GitHub App"; until that path is
available, use the self-hosted Action below.

## Self-hosted Action

The initializer creates `.github/workflows/elek.yml` and `.elek.yml` for the
Action runtime. If you prefer to wire it manually:

1. Add a provider API key to repo secrets (`Settings → Secrets and variables → Actions`):

   ```
   DEEPSEEK_API_KEY  # or OPENROUTER_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY / etc.
   ```

2. Commit the generated files, or drop this in `.github/workflows/elek.yml` manually:

   ```yaml
   name: elek
   on:
     pull_request: { types: [opened, synchronize, reopened] }
     issue_comment: { types: [created] }
     issues: { types: [opened] }

   permissions:
     contents: read           # blocks merge entirely (read-only)
     pull-requests: write     # post review comments
     issues: write            # post tracking comment

   concurrency:
     group: elek-${{ github.event_name }}-${{ github.event.pull_request.number || github.event.issue.number || github.ref }}
     cancel-in-progress: true

   jobs:
     review:
       if: ${{ github.event_name != 'issue_comment' || !endsWith(github.actor, '[bot]') }}
       runs-on: ubuntu-latest
       timeout-minutes: 15
       steps:
         - uses: actions/checkout@v6.0.3
           with: { fetch-depth: 0 }
         - uses: selimozten/elek@v1
           with:
             deepseek_api_key: ${{ secrets.DEEPSEEK_API_KEY }}
             provider: deepseek
             model: deepseek-v4-pro
             thinking: high
   ```

3. Open a PR. Within ~3 minutes you'll see a tracking comment with a live progress checklist, then the final review (top-level summary + inline threads on changed lines).

Useful initializer variants:

```bash
npx --package github:selimozten/elek elek-init --provider openrouter --model moonshotai/kimi-k2.7-code
npx --package github:selimozten/elek elek-init --strategy crosscheck --max-cost-usd 0.05
npx --package github:selimozten/elek elek-init --no-config
```

The final comment includes an estimated token/cost line by default:

```text
Estimated review cost: $0.0012 (3,420 in / 810 out tokens)
```

For models without built-in price hints, elek still reports token estimates and
returns `$0.0000` until you provide `cost_rates`.

To trigger from a comment, set `trigger_phrase` (default `@pi`) and write `@pi review the auth flow`.

## Modes

The `mode` input controls the model's tool surface:

| `mode` | Tools | MCP | Edits | Use case |
|---|---|---|---|---|
| `review` (default) | `read,grep,find,ls,mcp` | ✓ | ✗ | Repo-scoped read-only code review. Recommended. |
| `review+edit` | `read,grep,find,ls,mcp` | ✓ | ✗ | Review-only until sandboxed mutation tools are available. |
| `agent` | `+ bash` | ✗ | ✓ | Legacy, full power. Trusted workflows only. |

Use `mode` to choose the tool surface. The low-level `tools` input is kept
for compatibility and debugging; review modes still resolve to the safe mode
presets.

**The model can never approve, merge, or close** in any mode — those endpoints aren't plumbed in elek's MCP server. The `permissions:` block in your workflow is the backstop.

## Review Strategies

The `review_strategy` input controls orchestration quality:

| `review_strategy` | Runs | Use case |
|---|---:|---|
| `solo` (resolved when unset) | 1 final reviewer | Fast, cheap default review. |
| `crosscheck` | 2 read-only lenses + orchestrator self-review + final orchestrator | Best default for serious PR review. |
| `council` | 4 read-only lenses + orchestrator self-review + final orchestrator | Larger or high-risk PRs touching auth, billing, migrations, infra, or public APIs. |
| `thermos` | N read-only audit agents + orchestrator self-review + final orchestrator | Highest-signal mode for risky PRs; modeled after Thermos-style independent audit then adjudication. |

Multi-agent strategies currently run only with `mode: review`. If you use
`review+edit` or `agent`, elek runs a solo review and logs a warning.

`crosscheck` runs two independent candidate reviewers:

- **Risk Review** — correctness, security, breaking changes, devex regressions, feature-gate leaks.
- **Design Review** — maintainability, structural simplification, abstraction quality, file-size growth, spaghetti branching, type boundaries.

`council` adds:

- **Test Integrity Review** — missing/weak tests, nondeterminism, meaningless assertions.
- **Operational Review** — rollout/rollback safety, migrations, configuration, observability, retries, partial updates.

`thermos` runs configurable independent audit agents, defaulting to five:

- **Security & Correctness Audit** — concrete bugs, security, auth, data loss, races, and user-visible regressions.
- **Breaking Side-Effects Audit** — cross-module side effects, changed contracts, hidden coupling, and compatibility breaks.
- **DevEx & Config Audit** — local workflow breakage, env/config drift, scripts, generated artifacts, and build/test surprises.
- **Feature Gate & Exposure Audit** — feature leaks, missing guards, internal-only behavior becoming public, and rollout gaps.
- **Tests & Operations Audit** — missing high-signal tests, migrations, observability, timeouts, retries, idempotency, and support burden.

Candidate reviewers are read-only and cannot post. They do not see existing PR
discussion, so they produce fresh independent reports. The final model also
runs its own read-only self-review, then receives every candidate report plus
the visible PR discussion, rejects speculative or duplicate findings, and posts
only high-confidence feedback through elek's narrow review MCP tools.

Every finding is expected to follow elek's review contract: severity,
confidence, evidence, impact, and a concrete fix. Low-confidence findings
should be dropped instead of posted.

```yaml
with:
  provider: together
  model: moonshotai/Kimi-K2.7-Code
  thinking: max
  review_strategy: thermos
  review_agent_count: 5
  review_models: together/moonshotai/Kimi-K2.7-Code,together/deepseek-ai/DeepSeek-V4-Pro,together/Qwen/Qwen3.7-Max
  validator_model: openai/gpt-5.5
  validator_thinking: medium
  max_council_changed_lines: 200000
  max_crosscheck_changed_lines: 200000
```

For expensive models, a good pattern is cheap/open parallel reviewers at high or
max reasoning plus one stronger final orchestrator at medium reasoning.
During initial testing, omit `max_cost_usd` so the full fan-out runs and tune a
budget later from observed review summaries. If the selected multi-lens
strategy already exceeds `max_cost_usd` before output tokens are counted, elek
downgrades to the next cheaper strategy.
Changed-line thresholds do not downgrade the strategy; large PRs keep their
requested review coverage and elek slices prompt diff context by file.

## Cross-Model Review

Run two providers in parallel for free cross-validation. Each model independently iterates on the other's findings:

```yaml
jobs:
  deepseek:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6.0.3
      - uses: selimozten/elek@v1
        with:
          deepseek_api_key: ${{ secrets.DEEPSEEK_API_KEY }}
          provider: deepseek
          model: deepseek-v4-pro

  kimi:
    name: openrouter-kimi-k2.7-code
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6.0.3
      - uses: selimozten/elek@v1
        with:
          openrouter_api_key: ${{ secrets.OPENROUTER_API_KEY }}
          provider: openrouter
          model: moonshotai/kimi-k2.7-code
```

On the second push, each model reads the other's prior findings (kept in the comment thread) and opens its review with a status table — fixed / still present / no longer relevant — before listing new findings.

## How it works

```mermaid
flowchart LR
    A[GitHub event] --> B[run.ts]
    B --> C[fetch diff,comments,prior reviews]
    C --> D[XML-taggedprompt]
    D --> E["pi --mode json"]
    E -->|tool calls| F[MCP server]
    F -->|inline comments| G[/buffer.jsonl/]
    E -->|streaming events| B
    B -->|live updates| H[(trackingcomment)]
    G --> I[post-step]
    I --> J[(inline reviewthreads)]
```

A composite Action installs Node + pi + the MCP adapter, then `tsx` runs the orchestrator. Pi spawns the model, streams events back as JSONL, and elek converts those into a live checklist. The model calls our MCP server to buffer inline comments; a post-step drains the buffer to GitHub's PR review-comments API after pi exits.

Full architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).

## Public roadmap

- **GitHub App primary install** — make the hosted elek App the default way to
  add review-only AI to a repository, with the Action remaining the advanced
  self-hosted runtime.
- **Opt-in telemetry contract** — publish redacted telemetry schemas and client
  redaction tests so teams can choose aggregate or finding-metadata reporting
  without sending raw code, raw diffs, prompts, file paths, branch names,
  commit SHAs, secrets, or author identities.
- **Model-quality analytics** — build on `elek-feedback`, `elek-analytics`,
  and `elek-eval` so teams can compare models by accepted findings, false
  positives, cost, latency, and inline-comment health.

## Inputs

### Trigger / behavior

| Input | Default | Notes |
|---|---|---|
| `trigger_phrase` | `@pi` | Detected in comments, issue body, PR body |
| `prompt` | _(comment text)_ | Explicit prompt; bypasses trigger detection |
| `mode` | `review` | `review` / `review+edit` / `agent`; `review+edit` is currently read-only |
| `config_path` | `.elek.yml` | Repo-local defaults and review policy; use `none`, `off`, or `false` to disable |
| `review_strategy` | _(resolved)_ | `solo` / `crosscheck` / `council` / `thermos` |
| `review_models` | _(primary model)_ | Comma-separated reviewer model specs, e.g. `together/moonshotai/Kimi-K2.7-Code,together/deepseek-ai/DeepSeek-V4-Pro,together/Qwen/Qwen3.7-Max` |
| `review_agent_count` | _(.elek.yml or unset)_ | Parallel reviewer count for `thermos`, 1-8 |
| `validator_model` | _(primary model)_ | Final orchestrator model spec; this model validates reviewer reports and posts findings |
| `validator_thinking` | _(same as `thinking`)_ | Final orchestrator thinking level; use `medium` for frontier orchestrators when reviewers use high/max |
| `severity_threshold` | _(.elek.yml or unset)_ | Prompt-level reviewer threshold: `critical`, `important`, or `minor` |
| `show_cost` | `true` | Show estimated token usage and review cost in comments/logs; outputs are always set |
| `cost_rates` | _(empty)_ | Optional price overrides as `model=inputPerMillion:outputPerMillion` |
| `max_cost_usd` | _(.elek.yml or unset)_ | Soft cost cap; use `0`, `off`, or `none` to disable an inherited cap |
| `max_council_changed_lines` | _(.elek.yml or default)_ | Changed-line warning threshold for `council`/`thermos`; `0` disables |
| `max_crosscheck_changed_lines` | _(.elek.yml or default)_ | Changed-line warning threshold for `crosscheck`; `0` disables |
| `actor_filter` | _(empty)_ | Comma-separated allowlist of usernames; empty allows repository owners, members, and collaborators |
| `allowed_bots` | _(empty)_ | Comma-separated bot logins, or `*` for all |
| `sticky_comment` | `true` | Reuse the same tracking comment across pushes |

### Model

| Input | Default | Examples |
|---|---|---|
| `provider` | `anthropic` | `deepseek`, `openrouter`, `openai`, `anthropic`, `google`, `groq`, `mistral`, `together`, `xai` |
| `model` | _(provider default)_ | `deepseek-v4-pro`, `moonshotai/Kimi-K2.7-Code`, `Qwen/Qwen3.7-Max`, `claude-sonnet-4-6`, `claude-opus-4-8`, `gpt-5.5`, `gemini-3.1-pro-preview` |
| `thinking` | `medium` | Portable pi levels: `off` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max` |
| `system_prompt` | _(pi default)_ | Override pi's system prompt |
| `max_turns` | `20` | Cap conversation turns |
| `run_timeout_seconds` | `600` | Wall-clock timeout for each model run; keep the job timeout higher so elek can update the tracking comment |
| `tools` | _(mode-resolved)_ | Legacy low-level allowlist; review modes use `mode` presets |
| `base_branch` | _(repo default)_ | Override the comparison base |
| `branch_prefix` | `elek/` | Prefix for branches the action creates |

## Outputs

| Output | Notes |
|---|---|
| `conclusion` | `success`, `failure`, or `skipped` |
| `summary` | First 1,000 chars of the final review text |
| `cost_usd` | Aggregate estimated USD cost across all model runs |
| `input_tokens` / `output_tokens` | Aggregate estimated token usage |
| `review_summary_path` | Path to `elek-review-summary.json` on the runner |
| `review_summary_json` | Same summary as a single-line JSON output |

The review summary JSON includ

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [selimozten](https://github.com/selimozten)
- **Source:** [selimozten/elek](https://github.com/selimozten/elek)
- **License:** MIT
- **Homepage:** https://elek.sh

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-selimozten-elek
- Seller: https://agentstack.voostack.com/s/selimozten
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
