Skills vs Apps vs MCP Servers in Codex Plugins: What's the Difference?
When I first started building AI workflows with Codex, I kept confusing three things: Skills, Apps, and MCP Servers. I’d put workflow logic in MCP configurations, or try to use Apps when I really needed an MCP Server. My plugins were messy and hard to maintain.
After some trial and error, I finally understood: each component has a clear, distinct responsibility. Let me share what I learned.
The Core Problem
Building AI workflows requires answering three questions:
- What should the AI do? (Workflow logic)
- Where does it connect? (External services)
- How does it extend? (Additional capabilities)
I was trying to answer all three with one component. That doesn’t work.
The Three Components
Here’s the mental model that finally clicked for me:
┌─────────────────────────────────────────────────────────────┐│ Codex Plugin Package │├─────────────────┬─────────────────┬───────────────────────┤│ Skills │ Apps │ MCP Servers │├─────────────────┼─────────────────┼───────────────────────┤│ Define WHAT │ Connect WHERE │ Extend HOW ││ │ │ ││ Workflow logic │ Service APIs │ Remote tools ││ Prompts │ Databases │ Shared context ││ Behavior │ Auth handling │ Cross-session data │├─────────────────┼─────────────────┼───────────────────────┤│ SKILL.md │ .app.json │ .mcp.json │└─────────────────┴─────────────────┴───────────────────────┘Skills: Define Behavior
Skills describe what the AI agent should do. They’re workflow descriptions stored in a specific structure.
I initially thought Skills were just prompts. But they’re more than that - they support progressive discovery. Agents learn about skills incrementally as they work through a task.
Let me show you a simple example:
---name: code-reviewdescription: Automated code review workflow for pull requests---
## Workflow
1. Read the changed files from the PR2. Analyze code quality using linting rules3. Check for security vulnerabilities4. Generate review comments with suggestions
## Behavior- Be constructive, not critical- Focus on security and performance- Provide actionable suggestionsThe key insight: Skills are discovered by agents, not hard-coded. This makes them flexible and reusable.
Apps: Connect Services
Apps handle external connections. When I need to talk to GitHub, Jira, or a database, I use an App configuration.
Here’s where I went wrong initially: I tried to put API logic inside my Skills. That’s not the right place. Apps are specifically for integration:
{ "github": { "connector": "github-api", "auth": "oauth", "capabilities": ["read-repos", "create-prs", "write-issues"] }, "jira": { "connector": "jira-cloud", "auth": "api-key", "capabilities": ["read-issues", "create-issues"] }}The App handles:
- Authentication (OAuth, API keys)
- Connection management
- Capability scoping
I don’t have to worry about tokens expiring or rate limits in my workflow logic. The App abstraction handles that.
MCP Servers: Extend Capabilities
MCP Servers are the most powerful component. They provide remote tool access and shared context.
This is where I got confused most often. I’d try to use Apps when I really needed MCP Servers. The distinction:
- Apps: Connect to existing services with known APIs
- MCP Servers: Provide custom tools and shared state
{ "mcpServers": { "database": { "command": "postgres-mcp-server", "args": ["--connection-string", "${DB_URL}"], "env": { "MAX_CONNECTIONS": "10" } }, "shared-context": { "command": "context-server", "args": ["--storage-path", "/data/context"] } }}MCP Servers shine when you need:
- Custom tools that don’t exist as services
- Shared context across multiple workflow sessions
- Stateful operations that persist between runs
A Real Example: Putting It Together
Let me show you how these work together in a real plugin I built.
Scenario: I wanted to create a plugin that reviews pull requests and posts comments.
Step 1 - Define the Skill (what)
---name: pr-reviewdescription: Review pull requests and post feedback---
## Workflow1. Fetch PR changes2. Analyze code quality3. Check for security issues4. Post review commentsStep 2 - Configure the App (where)
{ "github": { "connector": "github-api", "auth": "oauth", "capabilities": ["read-prs", "write-reviews"] }}Step 3 - Add MCP Server (how)
{ "mcpServers": { "security-scanner": { "command": "security-mcp-server", "args": ["--rules", "owasp-top-10"] } }}Now my Skill can:
- Use the GitHub App to fetch PRs and post comments
- Use the security-scanner MCP Server for vulnerability detection
- Define the workflow logic in the SKILL.md
Each component stays focused. Each can evolve independently.
Common Mistakes I Made
Mistake 1: Putting Workflow Logic in MCP Config
{ "mcpServers": { "review-workflow": { "steps": ["fetch", "analyze", "post"], "prompt": "Review this code..." } }}This belongs in a Skill, not an MCP Server. MCP Servers are for tools, not workflows.
Mistake 2: Using Apps for Custom Tools
I tried to configure a custom code analyzer as an App. But Apps are for existing services with defined APIs. Custom tools should be MCP Servers.
Mistake 3: Overcomplicating Skills
I once wrote a 500-line Skill that handled everything. Bad idea. Skills should describe workflows, not implement them. Keep Skills focused and readable.
When to Use Each Component
Need to define a workflow? → Skill (SKILL.md)Need to connect to GitHub/API? → App (.app.json)Need custom tools or shared state? → MCP Server (.mcp.json)All three components are optional in a plugin. You can have:
- A plugin with only Skills (pure workflow descriptions)
- A plugin with only Apps (just connectors)
- A plugin with only MCP Servers (just tools)
- Any combination
This flexibility is powerful. I’ve built plugins ranging from single-file Skills to full packages with all three components.
Why This Separation Matters
Understanding these distinctions helped me:
- Organize code better: Each file has a clear purpose
- Debug faster: I know where to look for problems
- Reuse components: My GitHub App works across multiple Skills
- Scale workflows: Adding new capabilities doesn’t require touching existing logic
The architecture cleanly separates concerns. That’s the point.
Key Takeaways
- Skills = Workflow descriptions (SKILL.md)
- Apps = Service connectors (.app.json)
- MCP Servers = Tool providers (.mcp.json)
Choose based on what you’re solving:
- Defining behavior → Skill
- Connecting services → App
- Extending capabilities → MCP Server
Don’t mix responsibilities. Each component has a job. Let it do that job well.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments