The Agent Architecture: Skills, Plugins, and MCP

Lauren Milligan April 16, 2026 7 min read

In the previous post, I described the agency: a team of specialized AI agents that coordinate to deliver client work. This post is about what's underneath — the infrastructure that makes it possible.

Three concepts do most of the heavy lifting: MCP servers that give agents access to external tools, Skills that define each agent's behavior, and a plugin system that packages everything into something reusable. If you're building your own agent workflows, this is the scaffolding you need to understand.

MCP: The USB Port for AI

Model Context Protocol is an open standard for giving AI models access to external tools and data. If you've ever plugged a printer into a USB port and had it just work, that's the idea. MCP is the interface layer between an AI model and the systems it needs to interact with.

An MCP server is a small process — usually Node.js or Python — that exposes a set of tools. Each tool has a name, a description, and a schema that defines what inputs it accepts. The AI model sees the tool list, decides which one to call, and the MCP server executes it against the real system.

Here's what that looks like in practice. My Klaviyo MCP server exposes tools like create_email_template, get_campaigns, get_flows, and get_segments. When the Klaviyo Expert agent needs to audit a client's account, it calls get_flows to pull the flow list, get_campaigns to check campaign history, and get_segments to review audience structure. It's reading real data from a real account, not hallucinating a summary.

The Cloudflare MCP server exposes 16 tools: zone management, DNS record CRUD, Pages deployment, Workers deployment, R2 storage, and SSL configuration. When the Developer agent deploys a site, it calls cf_pages_create to set up the project, cf_pages_deploy to push the build, and cf_dns_create to add the CNAME record. Real infrastructure, configured by the agent, verified by me.

The pattern is the same every time: a lightweight server, a clean tool interface, and a real system on the other end. I currently run MCP servers for Klaviyo, Gmail, Cloudflare, Namecheap, a Google Sheets CRM, a nanny management system, and a rental property manager. Each one gives an agent the ability to do things, not just talk about them.

Skills: The Agent's Operating Manual

An MCP server gives an agent tools. A skill tells it how to use them.

A Claude Code skill is a Markdown file — typically called SKILL.md — that defines everything an agent needs to know about its role. It's the contract between me and the model. When I invoke the Designer agent, Claude reads the Designer's skill file and becomes that agent: it knows its workflows, its data paths, its tools, its constraints, and its voice.

A skill file typically includes:

The skill file is what turns a general-purpose language model into a specialist. Without it, Claude is smart but directionless. With it, Claude is a Designer who knows that Instagram Reels are 1080x1920 and that brand onboarding requires a color audit before anything else.

The Plugin Structure

Skills and references need packaging. That's what the plugin system provides.

A Claude Code plugin is a directory with a specific structure. Here's what a typical agent plugin looks like:

  my-agent/
  |
  +-- .claude-plugin/
  |   +-- plugin.json          # Plugin metadata (name, version, description)
  |
  +-- skills/
  |   +-- my-agent/
  |       +-- SKILL.md         # The agent's operating manual
  |       +-- references/
  |       |   +-- platform-specs.md
  |       |   +-- domain-guide.md
  |       |   +-- api-reference.md
  |       +-- templates/
  |           +-- creative-brief.md
  |           +-- delivery-package.md
  |
  +-- data/                    # Runtime data (JSON, documents)
  +-- memory/                  # Persistent notes across sessions

The plugin.json file is simple. It declares the plugin's name, version, and a human-readable description. Claude Code uses this to register the plugin and make it available as a slash command.

The skills/ directory is where the real substance lives. Each skill has its SKILL.md, a references/ folder with domain knowledge the agent can read on demand, and a templates/ folder with reusable document structures. When the Designer needs to produce a creative brief, it doesn't start from scratch. It reads the brief template and fills it in with the client's specifics.

The data/ directory holds runtime state — JSON files with project tracking, client records, or financial data. The memory/ directory holds persistent notes that carry context across conversation sessions. Together, they give each agent a working memory that survives restarts.

The Local Marketplace

Here's where it gets elegant.

All of my agent plugins live as regular project directories in my codebase. The Designer source code is in projects/designer/. The Developer is in projects/web-developer/. They're just folders with Markdown files and JSON.

To make them available as Claude Code plugins, I use a local marketplace — a directory that contains symlinks to each plugin's project folder. The marketplace is registered in Claude Code's settings, and each symlink is registered in a manifest file.

  local-plugins/
  |
  +-- .claude-plugin/
  |   +-- marketplace.json     # Manifest listing all available plugins
  |
  +-- plugins/
      +-- designer    -->  /projects/designer/       (symlink)
      +-- developer   -->  /projects/web-developer/  (symlink)
      +-- copywriter  -->  /projects/copywriter/     (symlink)
      +-- onboarding  -->  /projects/onboarding/     (symlink)

The beauty of symlinks is that changes to the source take effect immediately. I edit the Designer's SKILL.md, and the next conversation with the Designer uses the updated instructions. No rebuild. No reinstall. No deploy pipeline. The marketplace is just a directory of pointers.

Installing a plugin is one command: claude plugins install designer@local-plugins. After that, I can invoke it with /designer from any conversation.

The Shared Data Model

Agents are only as useful as the data they share. The most important architectural decision I made was establishing a shared client directory that every agent reads from and writes to.

When a new client comes in, the Onboarding Assistant creates a folder at projects/clients/{client-name}/. It writes contact.md with the client's info and assets-access.md with their credentials and platform access. That's the foundation.

The Designer picks up from there and adds brand-guidelines.md — colors, typography, logo usage, photography direction. The Copywriter adds brand-voice.md — tone attributes, vocabulary preferences, sample phrases. The Developer reads both of those when building the site.

There's also a shared feedback-log.md where both the Designer and Copywriter record client feedback tagged with their agent name. And a creative-direction.md that evolves across projects as we learn what the client responds to.

The pattern is simple: each agent owns certain files but can read everything. Ownership prevents conflicts. Read access enables coordination. No agent works in a vacuum.

How Agents Trigger Each Other

This is less about technology and more about workflow design.

Agents don't call each other directly. There's no API between the Designer and the Developer. Instead, I orchestrate. The GM scopes a project and I invoke the Designer. The Designer produces specs and I invoke the Developer. At each handoff, I review the output before the next agent picks it up.

This is intentional. Full autonomy between agents sounds cool, but it's a debugging nightmare. When something goes wrong — and it does — I need to know exactly where in the chain the issue started. Human-in-the-loop at every handoff gives me that visibility.

The handoffs themselves are clean because of the shared data model. The Developer doesn't need me to explain what the Designer produced. It reads the design specs from the client directory. The Copywriter doesn't need a brief emailed to it. The brief is in the shared folder, written by the GM, following a template the Copywriter knows how to parse.

Over time, I expect some of these handoffs to become automatic. The GM finishes scoping and the Designer starts immediately. The Designer finishes specs and the Developer begins without waiting. But for now, I'm the scheduler, and that's the right call. Trust is built incrementally.

The Stack, Summarized

If you're thinking about building something similar, here's the minimum viable architecture:

That's it. No orchestration framework. No vector database. No fine-tuning. Just Markdown files, JSON data, MCP servers, and a directory structure that every agent understands.

The infrastructure is simple on purpose. The complexity lives in the skill definitions and the domain knowledge. That's where it should live — close to the work, easy to read, easy to change.

Build the scaffolding. Then fill it with everything you know.