mcporter-skill-builder
Scaffold an MCP wrapper skill that follows upstream OpenClaw and mcporter conventions. The output is a complete bundle the user can immediately edit, test, and publish.
When invoked
The user invokes the slash command (/mcporter-skill-builder ...) or asks naturally ("scaffold a Sentry MCP skill", "create an mcporter wrapper for Notion"). Either way, this skill is responsible for producing the bundle.
The frontmatter sets user-invocable: true but deliberately does not set command-dispatch: tool — the slash command goes through the model, loads this SKILL.md as context, and the agent drives scaffolding via shell tools (mkdir, cp, file-write primitives). Per OpenClaw skills.md § "Optional frontmatter keys", command-dispatch: tool would bypass the model and route directly to a single named tool — wrong fit here, since scaffolding is a multi-step decision tree (transport selection, input validation, file generation, post-scaffold validation) that benefits from the agent's judgment.
Step 1 — Choose a transport and auth shape
mcporter wraps several MCP server shapes. The first decision determines everything else; ask the user explicitly when their request is ambiguous.
| Mode | When to pick | What you'll need |
|---|---|---|
| HTTP + OAuth (DCR) | The MCP server has /.well-known/oauth-authorization-server and a registration_endpoint. Most hosted MCPs (Linear, Sentry, Notion, etc.). |
A base URL, token endpoint, client auth method, and optional client-secret env. The provisioner supplies refresh/access/client-id env vars. |
| HTTP + bearer token | The MCP authenticates with a static Authorization: Bearer <token> header. |
A base URL and an env-var name (e.g. ACME_API_TOKEN). |
| HTTP + custom headers | The MCP authenticates via custom headers (X-API-Key, etc.). |
A base URL and one or more <HEADER_NAME>=<ENV_VAR_NAME> pairs. |
| HTTP + no auth | Public MCP, no credentials needed. Rare. | A base URL only. |
| stdio | The MCP runs as a local subprocess (mcp-server-foo or npx -y @vendor/mcp-server). |
A command and its args. Possibly env vars. The binary must be on PATH or the package must be runnable. |
If the user said "scaffold a Linear/Sentry/Notion MCP skill" without specifying, default to HTTP + OAuth — that's the dominant pattern for hosted MCPs. If they said "scaffold an MCP wrapper for mcp-server-time" or anything mentioning npx/uvx/a local command, default to stdio. When in doubt, ask once and proceed.
The references for mode-specific scaffolding are loaded per-mode. Read only the one that matches the chosen mode:
- HTTP + OAuth:
references/http-oauth.md - HTTP + bearer:
references/http-bearer.md - HTTP + custom headers:
references/http-headers.md - HTTP + no auth:
references/http-noauth.md - stdio:
references/stdio.md
Cross-cutting context that applies regardless of mode lives in references/conventions.md. Read it before generating any bundle — it owns naming rules, body sizing, requires.bins discipline, and public-distribution boundaries.
Step 2 — Validate inputs
Universal across modes:
<slug>(required) — Lowercase, hyphenated, ≤64 chars (skill-creator naming spec). Becomes the skill directory name, the mcporter server key, the SKILL.mdnamefield, and the invocation prefix inmcporter call <slug>.<tool>. These four sites must match exactly — drift breaks invocation silently.--out <path>(optional, default:skills/) — Parent directory the new bundle gets written under, relative to cwd. The bundle itself lands at<out>/<slug>/. Default matches OpenClaw's workspace skills convention.
Mode-specific input validation lives in the per-mode reference. Read it and apply before writing any file.
If the slug is invalid (non-lowercase, contains spaces, leading/trailing hyphens, >64 chars, conflicts with an existing directory), refuse and explain. Do not "helpfully" normalize — the user should pick a clean slug intentionally.
Step 3 — Confirm the output path is empty
If <out>/<slug>/ already exists, list its contents and ask whether to overwrite, merge, or pick a different path. Default to refusing. Treat this as the most likely user error — do not silently overwrite.
Step 4 — Generate the bundle
For the file shape (always SKILL.md + mcporter.json; OAuth additionally ships scripts/setup.sh + scripts/init-mcporter-oauth.sh), see conventions.md § "Files generated by scaffolding".
The per-mode reference owns the exact templates for SKILL.md and mcporter.json (inline as fenced markdown/json blocks — substitute the slug, base URL or stdio command, env-var names, and other mode-specific values; do not improvise). Shell-script templates (OAuth mode's setup.sh and init-mcporter-oauth.sh) live as separate files at {baseDir}/scripts/templates/ and are copied byte-for-byte to <out>/<slug>/scripts/ — no substitution needed; they're slug-agnostic by design.
The cross-cutting rules — body sizing, --config {baseDir}/mcporter.json discipline, the skill-vs-MCP boundary that keeps tool names out of SKILL.md prose, requires.bins discipline, the description-as-trigger reminder, the editability and verbatim rules for Discovery / Authentication blocks — are owned by conventions.md. Read it before generating any bundle and treat it as the source of truth when the per-mode reference and conventions.md ever appear to disagree.
Step 5 — Validate
Run references/validation.md. Most checks are universal; mode-specific checks live in the per-mode reference. Do not skip — each catches a specific failure mode that has been observed.
For every bundle (regardless of mode), run the bundled verifier:
bash {baseDir}/scripts/verify-bundle.sh <out>/<slug>
The contract the verifier enforces, the failure modes it surfaces, and how to resolve each are owned by validation.md § "Bundle ⇄ template consistency". If any check fails, fix and re-run before reporting success.
Step 6 — Report back
Use the canonical shape in conventions.md § "Reporting back to the user" — universal bullets (paths written, description-is-placeholder reminder, smoke-test command) plus the mode-specific row from the table there. Keep the report under ~10 lines. The user already saw the file writes happen.
What you must NOT do
These apply regardless of mode:
- Do not enumerate the MCP's tool catalog in the generated SKILL.md body. The description should describe the integration's purpose; the body should point the agent at
mcporter list <slug> --schemafor the live tool catalog. Seeconventions.md§ "Skill-vs-MCP boundary". - Do not introduce a per-call agent runtime wrapper script. The agent calls
mcporterdirectly with--config {baseDir}/mcporter.json. For OAuth mode, the deployment harness invokesscripts/setup.shon credential rotation; the agent does not re-seed per call. mcporter's MCP SDK handles 401 →refresh_tokenexchange → vault-write transparently. - Do not put internal/proprietary content in the generated bundle. Skill bundles ship to public ClawHub — see
conventions.md§ "Public-distribution discipline" for the rule and rationale. - Do not make up auth shapes. If the user describes an auth mechanism that doesn't fit any of the five modes (HTTP×4 + stdio), stop and explain — adding a new mode requires updating templates and conventions, not improvising in a single bundle.
References
The conventions enforced by this skill are not invented; they distill upstream guidance. Cite these when justifying a generated artifact to a user:
- OpenClaw skills reference — load-time gating, frontmatter fields,
requires.bins/requires.envsemantics,{baseDir}placeholder, slash-command frontmatter (user-invocable,command-dispatch,command-arg-mode), the per-skillmcporter.jsonconfig approach: https://github.com/openclaw/openclaw/blob/main/docs/tools/skills.md - OpenClaw skill-creator playbook — naming rules (lowercase + hyphens, ≤64 chars, verb-led), body ≤500 lines, three-level loading model, "agent is already smart" default, anti-pattern files (no README/CHANGELOG/INSTALLATION_GUIDE inside bundles), no-symlinks rule, description-as-trigger: https://github.com/openclaw/openclaw/blob/main/skills/skill-creator/SKILL.md
- OpenClaw "Creating skills" — quick-start,
metadata.openclaw.osfilter,requires.configgate: https://github.com/openclaw/openclaw/blob/main/docs/tools/creating-skills.md - mcporter agent-skill pattern (v0.11.1) — "one small skill per MCP server, not a generic catch-all" guidance: https://github.com/openclaw/mcporter/blob/v0.11.1/docs/agent-skills.md
- mcporter call syntax (v0.11.1) — flag-based vs function-call invocation,
--output jsonenvelopes for transport-error handling (now preserves MCPstructuredContentfor dual text/structured responses per issue #168): https://github.com/openclaw/mcporter/blob/v0.11.1/docs/call-syntax.md - mcporter config (v0.11.1) — config discovery order (
--config>MCPORTER_CONFIG> project > home), XDG path resolution, transport selection (HTTP / stdio),bearerTokenEnv/bearerToken,headerswith${VAR}and${VAR:-fallback}interpolation (universal across string-valued fields onv0.11.0+),httpFetch: "node-http1"fallback,auth: "refreshable_bearer",importssemantics: https://github.com/openclaw/mcporter/blob/v0.11.1/docs/config.md
Mode-specific authoritative sources (OAuth vault internals, stdio spawn semantics, etc.) are cited in the per-mode references where they apply.
