---
description: Add a custom MCP skill to a Zibby workflow
argument-hint: <workflow-name> <skill-purpose-or-mcp-server-name>
---

# /zibby-add-skill

The user wants to add a custom skill (MCP tool bundle) to a workflow.

**Arguments:** $ARGUMENTS

## Steps

1. **Identify the MCP server** the skill wraps:
   - If the user named one (e.g. "slack", "linear", "filesystem"), find
     the official MCP server. Standard ones live at
     `@modelcontextprotocol/server-<name>`.
   - If unsure, ask: "Which MCP server should this skill wrap, or
     should it be a JS-only middleware?"

2. **Find the workflow** under your project's workflows path —
   `agents/<name>/` by default, or whatever `paths.agents` is
   set to in `.zibby.config.mjs`. (Legacy projects may still use
   `.zibby/workflows/`.) Create a `skills/` subfolder if it doesn't
   exist.

3. **Write `skills/<id>.mjs`:**

   ```js
   import { registerSkill } from '@zibby/core';

   registerSkill({
     id: 'slack',                       // referenced by node `skills: ['slack']`
     serverName: 'slack-mcp',
     command: 'npx',
     args: ['-y', '@modelcontextprotocol/server-slack'],
     // Convention: 'mcp__<short-server-name>__*' matches every tool the
     // MCP server exposes. Use the short name from the npm package
     // (e.g. server-filesystem → 'mcp__filesystem__*').
     allowedTools: ['mcp__slack__*'],
     envKeys: ['SLACK_BOT_TOKEN'],      // optional — env required to run
     description: 'Read channels, post messages, search history',   // optional
   });
   ```

   **MCP-server-specific args:** some servers need extra positional
   arguments. `@modelcontextprotocol/server-filesystem` requires the
   allowed paths as args, e.g.
   `args: ['-y', '@modelcontextprotocol/server-filesystem', process.cwd()]`.
   Check the server's npm page for required args.

4. **Import the skill file from `graph.mjs`** at the TOP, before
   `new WorkflowGraph()`:

   ```js
   import './skills/slack.mjs';        // side-effect: registers the skill
   import { WorkflowAgent, WorkflowGraph } from '@zibby/core';
   // ...
   ```

5. **Opt nodes into the skill:**

   ```js
   graph.addNode('post_summary', {
     ...postSummaryNode,
     skills: ['slack'],                // ← agent gets slack tools here
   });
   ```

6. **Document the env requirement.** Add to the workflow's README or
   tell the user which env var they need to set:
   - Locally: `export SLACK_BOT_TOKEN=xoxb-...` or put in `.env`
   - Cloud: `zibby agent env set <workflow> SLACK_BOT_TOKEN=...`

7. **Validate + test:**
   ```bash
   zibby agent validate <name>
   zibby agent run <name> -p ...
   ```

   The agent should now have access to `mcp__slack__*` tools in the
   nodes that opted in.

## When NOT to use a custom skill

- If the work can be done with plain Node.js (HTTP call, file write,
  git command) — use a custom-code node with `execute()` instead. MCP
  skills are for tool surfaces the agent decides to use, not for
  deterministic glue.

## When to use `middleware` instead of MCP

If you don't have an MCP server but want to attach a JS helper that
nodes can use, see the "Custom skill via a non-MCP function" section
of `.claude/CLAUDE.md`. This is rare — prefer MCP when one exists.
