Skip to content
All case studies
Payments / Fintech·Senior Full-Stack Developer·2026

Making AI safe for a team: skills, MCP servers, and hard gates

AI assistance that is fast for one careful developer is a liability for a team of five. I built the infrastructure that makes it the other way round - executable workflow skills, four MCP servers, and guardrail hooks that block the destructive command before it runs - packaged as an installable plugin.

43
tools exposed across 4 purpose-built MCP servers
14
executable workflow skills, installable in any repo
9
guardrail rules that block destructive commands before they run

Stack

Claude CodeModel Context ProtocolNode.jsBashPHPStanPsalmDeptracDoctrine DBALJIRAGitHub

In one line

I built the tooling that makes AI assistance safe and repeatable for a whole team - executable skills, four MCP servers, and hooks that block the dangerous command rather than trusting anyone to avoid it - and packaged it as a plugin anyone installs with two commands.

The problem

The migration meant moving business logic out of four legacy codebases into a new stack with strict conventions. That work is a bad fit for a human on a Tuesday afternoon: the logic for one feature is often split across a SOAP service, a JSON-RPC webservice, a BFF layer and an AngularJS UI, and the conventions on the receiving end are unforgiving.

It is a good fit for an AI assistant, which can hold four legacy repositories in view at once and apply a convention consistently across hundreds of files. But that only holds if two problems are solved first, and neither is solved by prompting.

The output has to be trustworthy. An assistant that produces plausible code which quietly violates the architecture is worse than no assistant, because the violation arrives faster than review can catch it.

The blast radius has to be bounded. The moment you give a tool the ability to run commands, you have given it the ability to run git push --force, to drop a table, or to "fix" a failing test by editing vendor/. One careless session can undo a week.

So I built the infrastructure before scaling the AI work out to the team.

Guardrails first

The hooks came before anything else, because everything else is only safe once they exist. A PreToolUse guard runs in every session, and the rules are command-pattern gated so each one fires only when relevant - a guard that interrupts constantly gets disabled, which defeats the point.

guard-bash.sh blocks nine classes of command: force-pushes and hard resets, blanket SKIP_PRECOMMIT, committing pnpm-link artifacts, manual pushes (the sanctioned path is the publish skill), recursive style fixes across src/, database-modifying SQL, and - my favourite - any SELECT without a LIMIT.

guard-files.sh blocks edits to vendor/, and blocks adding vendor/ to .gitignore, which is the move an assistant reaches for when it wants the first block to go away.

The important property is that these are enforced outside the model. They are not instructions the assistant is asked to respect; they are a process that returns a non-zero exit code. No amount of confident reasoning gets around them.

Skills: the workflow as an executable artifact

A skill is a workflow written down in a form the assistant executes rather than improvises. The one that mattered most is migrate-feature: seven phases and a roughly thirty-item checklist spanning three repositories, from legacy analysis through backend implementation, SDK regeneration, middleware routing, frontend work, verification and publication.

Before it existed, every migration was a fresh negotiation about what "done" meant. After it, the fifth migration runs like the first.

Thirteen more cover the rest of the cycle - endpoint and service scaffolding, PHP and Vue review rules, per-repo quality checks, the publish flow, and the JIRA lifecycle. They encode the same conventions the static-analysis rules enforce, which means the assistant is aiming at the target the CI is measuring.

MCP servers: giving the assistant real access, narrowly

Four Model Context Protocol servers, written from scratch in Node, exposing 43 tools. The design principle throughout was to expose the specific capability rather than a general one, because a narrow tool cannot be misused the way a shell can.

  • quality (15 tools) - PHPStan, Psalm, Deptrac, ECS, test runs, changed files, commit, push, PR create/edit/diff/comment/list, JIRA transition.
  • workflow (16 tools) - migration checklists, phased context loading, cross-repository tracking, document validators.
  • database (6 tools) - schema exploration: connections, tables, describe, foreign keys, indexes, and a query tool that is read-only with an automatic row limit.
  • logs (6 tools) - remote API and webserver logs over SSH: list, tail, grep, since, context, errors.

The database server is the clearest illustration. The assistant genuinely needs to inspect schemas - guessing at column names produces confidently wrong code. But it does not need write access, and it does not need to pull a million rows into context. So the tool grants exactly the useful half of the capability, and the dangerous half is not reachable.

The workflow server is the unusual one, because it holds gates. A migration cannot be marked publishable until its checklist items are genuinely satisfied. The assistant cannot skip a step by asserting it was done, because the gate is state held outside the conversation.

The loop that makes it work

The pieces compose into something none of them achieve alone:

  1. The assistant writes code, aiming at conventions encoded in a skill.
  2. The pre-commit hook runs the same PHPStan, Psalm and Deptrac checks a human commit faces.
  3. A check fails. The assistant reads the actual error, fixes it, and retries.
  4. Two or three iterations later, it converges.

This is the whole thesis in one loop. The assistant is not trusted to be correct; it is placed in a system where being incorrect is detected mechanically and immediately, and where the feedback is specific enough to act on. The quality gates I built for human developers turned out to be exactly the infrastructure that makes machine output trustworthy - the same rules, doing double duty.

The generated SDK pipeline closes the same loop across the language boundary: a PHP field change becomes a TypeScript compile error, so an assistant working on the frontend cannot drift from what the backend actually returns.

From personal setup to team platform

For a while this was per-repository configuration, which meant it was really just my setup. Claude Code loads configuration from your user config and the one project you launched in - repositories attached as extra working directories get file access but not their .claude/ config. During full-stack work, where a single ticket touches three repositories, a skill defined in the API repo was simply invisible from the frontend.

I resolved it by packaging everything - skills, hooks, MCP servers - as a user-level plugin with its own on-premise marketplace:

/plugin marketplace add [email protected]:your-org/dev-suite.git
/plugin install dev-suite@dev-suite

Two commands, works in every repository, versioned like any other dependency. That packaging step is what turned it from my tooling into the team's platform - the difference between a colleague admiring a setup and a colleague running it.

What I would tell someone starting this

Build the guardrails first. They are what let you say yes to giving the whole team these tools, rather than keeping them to the one person trusted to be careful.

Expose narrow tools, not broad ones. Read-only with a row limit beats database access plus a warning in the prompt, every time.

Put the gates outside the model. Anything enforced only by instruction is enforced only by luck.

Your existing quality gates are the AI infrastructure. The most useful thing I had already built was the pre-commit toolchain. It is what makes the loop converge - without it there is no signal, and the assistant is just producing confident text.

Let’s build something that lasts

Hiring a senior engineer or architect for a remote team? I work across EU and US time zones - tell me what you're building.

Newsletter

I write about software architecture, PHP, Vue, TypeScript, and developer experience. No spam, unsubscribe anytime.

Copyright © 2026. All rights reserved.