🌐 Cross-runtime: el problema
Escribes una skill para Claude Code. Funciona perfecto. Entonces tu colega usa Codex y pregunta: "¿cómo ejecuto esto aquí?". Respuesta breve: no se ejecuta. Respuesta larga: cada agente tiene su propia sintaxis: frontmatter, formato de tools, sistema de permisos. Copiar y pegar no basta.
💡 Consejo
Las Skills son documentación ejecutable. La lógica es la misma en cualquier runtime: lo que cambia es el envoltorio: cómo el agente carga, activa y llama tools. Resolver el envelope es el trabajo.
✓ Formato portable (fuente única)
- ✓Escribe una vez en formato neutro
- ✓El build genera versiones para cada runtime
- ✓El cambio se propaga a todos con un comando
- ✓Las pruebas se ejecutan contra la fuente, no contra copias
✗ Copiar y pegar entre runtimes
- ✗3 copias divergen en 2 semanas
- ✗Bug corregido en una y olvidado en las demás
- ✗Frontmatter dañado por un runtime incorrecto
- ✗No hay forma de probar la coherencia
📦 polyskill — formato portable
La skill polyskill (presente en el repo) resuelve el problema del sobre. Escribes una fuente única y ella genera builds específicos para cada runtime. Piensa en "Babel para skills".
🗂️ Estructura típica de un polyskill
minha-skill/
├── source.md # fonte única (neutra)
├── polyskill.config.json # mapeamento de tools
├── claude-code/ # build pra Claude Code
│ └── SKILL.md # frontmatter + Read/Edit/Bash
├── codex/ # build pra Codex
│ └── skill.yaml # frontmatter Codex + read_file/write_file
└── tests/
└── snapshot.test.ts # garante paridade entre builds
⚡ Traducción automática
O polyskill crea tres traductoras esenciales:
- →Frontmatter:
name/description/toolsmapeados para cada runtime - →Herramientas:
Read↔read_file,Bash↔shell - →Activación: Skill tool (Claude Code) vs activate_skill (Codex)
Ventaja práctica: ajustas un párrafo en la fuente única, ejecutas polyskill build y los dos builds salen coherentes. Un bug en producción es un git diff, no un "¿en qué copia lo corregí?".
🔀 Diferencias entre Claude Code y Codex
Antes de portar una skill, conviene entender dónde los dos difieren. Adelanto: en la superficie son iguales (markdown + frontmatter), pero en los detalles son muy diferentes.
| Dimensión | Claude Code | Codex |
|---|---|---|
| Herramientas de archivos | Read, Edit, Write |
read_file, write_file, apply_patch |
| Ejecución de shell | Bash con sandbox por permiso |
shell con workspace-write/read |
| Carga de skills | Skill tool (/skill-name) + la descripción se activa automáticamente |
activate_skill explícito o activado por prompt |
| Permisos | Allowlist en settings.json, prompt por tool |
Modos (suggest / auto-edit / full-auto) |
| Compatibilidad con MCP | Nativo, configurado en ~/.claude/mcp.json |
Compatibilidad reciente, en evolución |
| Subagents | Sí (Task tool, agentes paralelos) | Limitado: una sesión a la vez |
| Slash commands | Sí, ~/.claude/commands/ |
Sí, pero con un formato distinto |
La regla práctica: si tu skill solo lee archivos y escribe markdown, es trivialmente portable. Si ella orquesta subagentes paralelos con hooks, va a necesitar una adaptación seria: probablemente se convierta en dos skills.
🔗 Cómo llamar a skills vía MCP
En vez de pedirle al otro agente que entienda tu formato de skill, envuelve la skill en un servidor MCP. Cualquier cliente MCP (Claude Code, Codex, Cursor, Cline) puede llamarla como tool sin saber que detrás hay una skill.
🛠️ Fragmento: skill como endpoint MCP
// mcp-skills-server/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { readFileSync } from "fs";
const server = new Server({ name: "skills-bridge", version: "0.1.0" });
server.tool({
name: "grill-me",
description: "Stress-test a plan adversarially. Returns gaps and risks.",
inputSchema: {
type: "object",
properties: { plan: { type: "string" } },
required: ["plan"]
},
handler: async ({ plan }) => {
const skillBody = readFileSync("./skills/grill-me/SKILL.md", "utf8");
return runAgentLoop({ system: skillBody, user: plan });
}
});
server.start();
Caso de uso: skills como API. Tu skill /grill-me se convierte en un endpoint que cualquier agente — o incluso tu CI — llama vía HTTP/MCP. Centraliza la lógica, evita la duplicación.
📊 Cuándo usar MCP vs. polyskill
- polyskill: la skill es principalmente documentación — guía al modelo, no ejecuta lógica pesada
- Servidor MCP: la skill llama a APIs externas, mantiene estado o tiene código que no quieres duplicar
- Híbrido: polyskill emite la documentación, el servidor MCP expone las tools especializadas
🤖 Skills en CI/CD
Las skills no tienen que ser interactivas. En CI/CD las ejecutas en modo batch (no interactivo, con entrada fija y salida en un archivo). Útil para la revisión automática de PR, la generación de docs y la validación de migrations.
✓ Funciona en CI
- ✓Skills deterministas con una entrada bien definida
- ✓Salida en archivo (markdown, JSON)
- ✓Herramientas restringidas (Read + Write, sin acceso libre a Bash)
- ✓Timeout configurado, fallback en caso de error
✗ No funciona en CI
- ✗Skills que le preguntan al usuario (aclaraciones)
- ✗Skills que dependen del estado de una sesión local
- ✗Skills con TUIs interactivas o prompts
- ✗Skills que tardan > 10min (límite de tiempo del runner)
⚠️ Consejo importante
Antes de ejecutar una skill en CI, prueba con --non-interactive localmente. Si te pide input en algún momento, se va a bloquear en el runner — y GitHub Actions cobra las 6h hasta el timeout.
🧪 Ejemplo práctico: /tdd en GitHub Actions
Escenario concreto: cuando un PR rompa las pruebas, activa automáticamente la skill /tdd. Analiza el error, propone una solución y abre un commit en el propio PR. El desarrollador se despierta al día siguiente con el build en verde.
📄 .github/workflows/tdd-loop.yml
name: tdd-loop
on:
pull_request:
types: [opened, synchronize]
jobs:
run-tdd:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run tests (capture failure)
id: tests
run: npm test || echo "failed=true" >> $GITHUB_OUTPUT
- name: Run /tdd skill
if: steps.tests.outputs.failed == 'true'
uses: anthropics/claude-action@v1
with:
skill: tdd
input: "fix failing tests in this PR"
allowed-tools: "Read,Edit,Bash(npm test)"
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Commit fix
if: steps.tests.outputs.failed == 'true'
run: |
git config user.name "tdd-bot"
git config user.email "bot@example.com"
git add -A
git commit -m "fix: /tdd auto-repair" || exit 0
git push
Trigger en el PR
Ejecuta en cada opened e synchronize (nuevos commits)
Capturamos el flujo desde el principio: no esperamos a que el desarrollador pida ayuda.
Ejecuta pruebas y detecta fallas
Output failed=true sirve como condición para los próximos steps
Activa la skill solo si algo realmente se rompió; así no desperdicia cuota de API.
Activa /tdd con tools restringidas
allowed-tools limita a Read, Edit y Bash(npm test) — nada de rm o curl
La allowlist es el cinturón de seguridad. Sin ella, la skill tendría demasiado poder en un entorno sin revisión humana.
Commit + push de vuelta en el PR
La corrección pasa a formar parte del historial del PR, con la autoría del bot
El dev revisa el diff humano y el del bot, no un patch fantasma sin contexto.
🧩 Integración con Cursor, Aider, Continue
Cursor, Aider y Continue no tienen el concepto nativo de Skill. Tienen rules, conventions o prompts del sistema. La buena noticia: el contenido de una skill cabe perfectamente en estos formatos.
📐 Estado actual de portabilidad
- Cursor: archivos
.cursorrulesaceptan markdown directamente desde la skill (sin frontmatter) - Aider: usa
CONVENTIONS.mdo--readpara cargar contexto - Sigue:
config.jsonpermitesystemMessagecon el cuerpo de la skill - Cline / Roo Code: acepta
.clinerulesen markdown
🔄 Adapter genérico — emite para cualquier agente
// scripts/sync-skills.ts
import { readFileSync, writeFileSync } from "fs";
import { stripFrontmatter } from "./utils";
const skill = readFileSync("./skills/tdd/SKILL.md", "utf8");
const body = stripFrontmatter(skill);
// Cursor
writeFileSync(".cursorrules", body);
// Aider
writeFileSync("CONVENTIONS.md", body);
// Continue
const config = JSON.parse(readFileSync(".continue/config.json", "utf8"));
config.systemMessage = body;
writeFileSync(".continue/config.json", JSON.stringify(config, null, 2));
console.log("✓ skill syncronized to Cursor / Aider / Continue");
Limitación: agentes sin El concepto de skill carga el contenido todo el tiempo (sin activación dinámica). Para las skills cortas, no hay problema. Para las skills largas, considera dividirlas en rules más pequeñas y específicas para cada contexto.
🎼 Skills + MCP servers
La composición más poderosa hoy: la skill orquesta; el servidor MCP ejecuta. La skill guía al modelo en el cuándo e como; el servidor MCP ofrece tools especializadas (DB, GitHub, Figma, Slack).
🏗️ Arquitectura de composición
┌──────────────────────────────────────────────────────────┐
│ USUÁRIO │
│ "/release-notes v2.3" │
└────────────────────────┬─────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ SKILL: /release-notes (markdown + frontmatter) │
│ "Quando o user pedir release notes: │
│ 1. liste commits desde a última tag │
│ 2. agrupe por tipo (feat/fix/chore) │
│ 3. publique no Slack #releases" │
└──────┬───────────────────┬───────────────────┬───────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌───────────────┐ ┌──────────────┐
│ MCP: github │ │ MCP: linear │ │ MCP: slack │
│ list-commits │ │ get-issues │ │ post-message │
└──────────────┘ └───────────────┘ └──────────────┘
🎯 Principio de diseño
La skill es el guion; el MCP es la caja de herramientas. Un guion sin escenario es teoría; un escenario sin guion es caos.
- →Una skill describe cuándo usar cada tool MCP
- →El servidor MCP expone lo que qué hace cada tool y su schema
- →El modelo vincula ambos en el como de la ejecución
🚧 Limitaciones actuales
Entre entornos de ejecución es un trabajo en curso. Algunas cosas ya funcionan bien; otras todavía dependen de soluciones improvisadas. Mapa honesto del territorio:
✓ Funciona bien en distintos entornos
- ✓Skills declarativas (sin código)
- ✓Herramientas básicas: leer, escribir, ejecutar
- ✓Servidores MCP (estándar abierto)
- ✓Skills cortas (< 200 líneas)
- ✓Sincronización mediante polyskill / adapters
✗ Todavía no / con reservas
- ✗Subagents paralelos (solo Claude Code)
- ✗Hooks (PreToolUse, PostToolUse): específicos
- ✗Slash commands con argumentos complejos
- ✗Los modelos de permisos difieren bastante
- ✗Skills que usan features experimentales de un runtime
🗺️ Hoja de ruta (estado real, no promesas)
Matt mencionó en el repo que el objetivo es que "que toda skill del curso funcione al menos en Claude Code y Codex". Hoy (2026), esto aplica al 80% de los casos más simples. Las skills que dependen de subagents en paralelo o de hooks complejos todavía son específicas de cada runtime.
Tendencia: la estandarización vendrá de MCP, no de un formato universal de skill. Si tu skill es principalmente un system prompt + tools, ya es portable hoy.
🎓 Conclusión del curso
Llegaste al final. Repaso de las tres rutas, un párrafo por cada una, para fijar el camino recorrido.
Ruta 1 — Fundamentos: los 4 problemas
Por qué existen las skills y qué resuelven
Mostramos los 4 problemas que resuelven las skills: contexto repetido, prompts difusos, falta de un proceso replicable y ausencia de memoria entre sesiones. A partir de ahí, elegir una skill se convirtió en una decisión racional, no estética.
Ruta 2 — Sobre el Repo: estructura e instalación
Cómo está organizado el repositorio de Matt Pocock y cómo instalar
Recorremos la estructura skills/, productivity/, engineering/, misc/, e hicimos la instalación mediante el plugin de Claude Code. Después de eso, cualquier skill nueva encuentra su lugar sin que tengas que preguntar.
Ruta 3 — Avanzado: composición, personalización, integración
Cómo ir más allá del uso básico
Componemos skills entre sí, las adaptamos al contexto local del proyecto y las integramos con otros agentes mediante MCP y CI/CD. Ahora tú no usa skills — tú construye con ellas.
🚀 Siguientes pasos
La teoría sin práctica se convierte en polvo. Siguiente paso concreto: elige un proyecto tuyo real para las próximas 48h e instala 3 skills. Úsalas durante una semana entera. Observa qué te ahorra tiempo y qué falla.
Después de eso, hay tres caminos:
- 1.Personalizar: ajusta el frontmatter, edita el cuerpo, haz tus propias
- 2.Compón: encadena skills (ej.:
/grill-me+/tdd) - 3.Porte: use
polyskilly lleva tus skills a Codex / Cursor
🎯 Qué vas a saber al terminar
Sigue aprendiendo:
- 📬 Newsletter de Matt Pocock: aihero.dev/s/skills-newsletter
- 📦 Repositorio del curso: github.com/inematds/mp-skill
- 🌐 INEMA.CLUB — comunidad brasileña: inema.club