MCP & coding agents

Normik is a remote MCP server: agents connect with a URL and a token — nothing to install, nothing to update.

Connecting

Claude Code, one command:

claude mcp add --transport http normik https://api.normik.io/api/mcp \
  --header "Authorization: Bearer $NORMIK_TOKEN"

Or in an MCP config file (.mcp.json):

{ "mcpServers": { "normik": {
    "type": "http",
    "url": "https://api.normik.io/api/mcp",
    "headers": { "Authorization": "Bearer nmk_…" } } } }

The token scopes everything: a workspace token serves that workspace's rules plus the inherited global ones.

The tool surface

Deliberately small — your agent's context window is spent on your code, not our schemas. Three typed tools on the hot path, two meta-tools for the rest:

ToolPurpose
get_playbookCompact rules + a version hash — agents cache while unchanged.
get_ruleFull detail and examples for one rule, on demand.
report_checkReport pass/fail per rule for a working session — powers the fix-rate dashboard. Optionally send agentName and modelId so the dashboard can compare which agents and models drift most on your rules.
list_capabilitiesDiscover the secondary capabilities and their arguments.
use_capabilityInvoke one: list_skills, get_skill, get_gate_result, propose_rule, propose_skill, bootstrap_playbook.

The pre-commit flow

  1. get_playbook — load the rules once, reuse while the version hash is stable.
  2. Write code; before committing, self-check the diff against each applicable rule.
  3. report_check with a stable sessionId (e.g. the branch name), listing pass/fail per rule — plus agentName and modelId when the agent knows them.
  4. Fix failures, re-report — Normik measures which rules break most and how often agents fix them before the commit.

When CI blocks: reading the gate verdict

The CI gate fails the build on error-severity violations. The agent that wrote the code can read that verdict and fix it, without a human pasting logs:

use_capability { "capability": "get_gate_result",
  "arguments": { "repo": "acme/api", "sha": "9f21c3d" } }

Every argument is optional — repo, sha (full or a 7+ character prefix, case-insensitive) and pr narrow the search; with no argument at all you get the most recent analysis in the token's scope, which may well belong to another repo or PR, so the agent is told to check the returned repo/pr/sha first. Branch names are not a filter: the gate records the repo, the PR number and the head sha.

Token scope matters. A workspace-scoped token only sees the analyses of its own workspace plus those recorded without one; an organisation-level token sees the whole organisation. If CI runs under a per-client workspace token and the developer's agent uses a different workspace token, the agent will not see that analysis — give it an organisation-level token. The found: false reason spells this out.

The response is written for an agent, not for a log reader:

  • violations[] — path, line, severity, ruleId, ruleTitle and the reviewer's comment. Call get_rule when a statement needs its full text and examples.
  • suggestion on a violation (may be null) — a short fix written from the diff alone, without the rest of the repo. A hint to check against the real code, not a patch to apply as-is.
  • blocking / blockingCount — whether an error-severity violation is what failed the build. blocking is null, never false, when it cannot be determined.
  • violationCount (what the gate recorded) against violationsReturned, violationsUnreadable and detailComplete. When detailComplete is false the stored detail is partial: the commit must not be read as clean, and the CI log stays the reference.
  • truncated with truncatedNote — whether only part of the diff was analysed. It is null (unknown) for now: the analysis record does not store it, and the partial analysis line in the CI log is the authoritative signal.
  • status: "unavailable" — the gate could not analyse the commit (fail-open: no BYOK key, or a provider incident). Nothing to fix; the merge simply went through unverified.
  • found: false with a reason — no analysis matches, stated explicitly rather than as an empty list.

The full loop: write → block → fix

  1. The agent writes code and self-checks it against get_playbook before committing.
  2. CI runs the gate on the pushed diff; a blocking violation fails the check.
  3. The agent calls get_gate_result and gets the violations, file and line.
  4. It fixes them, re-checks the changes, and calls report_check.
  5. The next CI run passes — and the dashboard records what broke and that it was fixed.

This is the whole point of being present at both moments: Normik is the tool the agent talks to while writing and the one that gates the pull request.

Proposals — agents suggest, humans decide

propose_rule and propose_skill let an agent codify a convention it keeps encountering; bootstrap_playbook derives an initial playbook from repo samples. Everything arrives flagged AI-generated and waits in the review queue (unless your organization disabled validation).Details in Governance.

Skills

list_skills returns names and one-line descriptions; agents load the full markdown of a skill only when relevant. Each retrieval is counted — the dashboard shows which skills actually get used.