Back to skills
SkillHub ClubShip Full StackFull StackBackendIntegration

agentic-mcp-server-builder

Scaffold MCP server projects and baseline tool contract checks. Use for defining tool schemas, generating starter server layouts, and validating MCP-ready structure.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,084
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
A92.4

Install command

npx @skill-hub/cli install openclaw-skills-agentic-mcp-server-builder

Repository

openclaw/skills

Skill path: skills/0x-professor/agentic-mcp-server-builder

Scaffold MCP server projects and baseline tool contract checks. Use for defining tool schemas, generating starter server layouts, and validating MCP-ready structure.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Backend, Integration.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install agentic-mcp-server-builder into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding agentic-mcp-server-builder to shared team environments
  • Use agentic-mcp-server-builder for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: agentic-mcp-server-builder
description: Scaffold MCP server projects and baseline tool contract checks. Use for defining tool schemas, generating starter server layouts, and validating MCP-ready structure.
---

# Agentic MCP Server Builder

## Overview

Create a minimal MCP server scaffold and contract summary from a structured tool list.

## Workflow

1. Define server name and tool list with descriptions.
2. Generate scaffold file map and tool contract summary.
3. Optionally materialize starter files when not in dry-run mode.
4. Review generated contract checks before adding business logic.

## Use Bundled Resources

- Run `scripts/scaffold_mcp_server.py` to generate starter artifacts.
- Read `references/mcp-scaffold-guide.md` for file layout and contract checks.

## Guardrails

- Keep tool boundaries explicit and minimal.
- Include deterministic outputs and clear input/output schemas.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/scaffold_mcp_server.py

```python
#!/usr/bin/env python3
from __future__ import annotations

import argparse
import csv
import json
from pathlib import Path

MAX_INPUT_BYTES = 1_048_576


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Scaffold an MCP server starter package.")
    parser.add_argument("--input", required=False, help="Path to JSON input.")
    parser.add_argument("--output", required=True, help="Path to output artifact.")
    parser.add_argument("--format", choices=["json", "md", "csv"], default="json")
    parser.add_argument("--dry-run", action="store_true", help="Run without writing scaffold files.")
    parser.add_argument(
        "--allow-outside-workspace",
        action="store_true",
        help="Allow scaffold_root to resolve outside the current workspace.",
    )
    return parser.parse_args()


def load_payload(path: str | None, max_input_bytes: int = MAX_INPUT_BYTES) -> dict:
    if not path:
        return {}
    input_path = Path(path)
    if not input_path.exists():
        raise FileNotFoundError(f"Input file not found: {input_path}")
    if input_path.stat().st_size > max_input_bytes:
        raise ValueError(
            f"Input file exceeds {max_input_bytes} bytes: {input_path}"
        )
    return json.loads(input_path.read_text(encoding="utf-8"))


def normalize_name(value: str) -> str:
    cleaned = "".join(ch.lower() if ch.isalnum() else "-" for ch in value.strip())
    while "--" in cleaned:
        cleaned = cleaned.replace("--", "-")
    return cleaned.strip("-")


def resolve_path_in_workspace(
    raw_path: Path,
    workspace_root: Path,
    label: str,
    allow_outside_workspace: bool,
) -> Path:
    resolved = raw_path.resolve()
    if allow_outside_workspace:
        return resolved
    try:
        resolved.relative_to(workspace_root)
    except ValueError as exc:
        raise ValueError(
            f"{label} must be inside workspace root: {workspace_root}"
        ) from exc
    return resolved


def render(result: dict, output_path: Path, fmt: str) -> None:
    output_path.parent.mkdir(parents=True, exist_ok=True)

    if fmt == "json":
        output_path.write_text(json.dumps(result, indent=2), encoding="utf-8")
        return

    if fmt == "md":
        lines = [
            f"# {result['summary']}",
            "",
            f"- status: {result['status']}",
            "",
            "## Planned Files",
        ]
        for item in result["details"]["file_map"]:
            lines.append(f"- {item}")
        lines.extend(["", "## Tools"])
        for tool in result["details"]["tools"]:
            lines.append(f"- {tool['name']}: {tool['description']}")
        output_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
        return

    with output_path.open("w", newline="", encoding="utf-8") as handle:
        writer = csv.writer(handle)
        writer.writerow(["name", "description"])
        for tool in result["details"]["tools"]:
            writer.writerow([tool["name"], tool["description"]])


def maybe_write_scaffold(root: Path, file_map: list[str], dry_run: bool) -> None:
    if dry_run:
        return
    for relative_path in file_map:
        path = root / relative_path
        path.parent.mkdir(parents=True, exist_ok=True)
        if path.suffix == ".py":
            path.write_text("# Starter file\n", encoding="utf-8")
        elif path.suffix == ".json":
            path.write_text("{}\n", encoding="utf-8")
        else:
            path.write_text("# Starter document\n", encoding="utf-8")


def main() -> int:
    args = parse_args()
    payload = load_payload(args.input)
    workspace_root = Path.cwd().resolve()
    server_name = normalize_name(str(payload.get("server_name", "mcp-server"))) or "mcp-server"
    tools = payload.get("tools", [])
    if not isinstance(tools, list):
        tools = []

    normalized_tools = []
    for tool in tools:
        normalized_tools.append(
            {
                "name": normalize_name(str(tool.get("name", "tool"))),
                "description": str(tool.get("description", "No description provided")),
            }
        )

    raw_scaffold_root = Path(payload.get("scaffold_root", f"artifacts/{server_name}"))
    scaffold_root = resolve_path_in_workspace(
        raw_scaffold_root,
        workspace_root,
        "scaffold_root",
        args.allow_outside_workspace,
    )
    file_map = [
        "server.py",
        "tool_registry.py",
        "schemas/tools.json",
        "README.md",
    ]
    maybe_write_scaffold(scaffold_root, file_map, args.dry_run)

    result = {
        "status": "ok",
        "summary": f"Prepared MCP scaffold for '{server_name}'",
        "artifacts": [str(Path(args.output))],
        "details": {
            "server_name": server_name,
            "scaffold_root": str(scaffold_root),
            "file_map": file_map,
            "tools": normalized_tools,
            "dry_run": args.dry_run,
        },
    }

    render(result, Path(args.output), args.format)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

```

### references/mcp-scaffold-guide.md

```markdown
# MCP Scaffold Guide

## Required Starter Files

- `server.py`
- `tool_registry.py`
- `schemas/tools.json`
- `README.md`

## Tool Contract Checklist

- Tool name is stable and lowercase-hyphen format.
- Tool description states purpose and expected input/output.
- Tool schema is machine-readable and versioned.
- Server startup path is deterministic.

## Validation Checklist

- Generated file map matches expected structure.
- Contract summary includes all tools.
- Dry-run mode performs no file writes.

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "0x-professor",
  "slug": "agentic-mcp-server-builder",
  "displayName": "Agentic Mcp Server Builder",
  "latest": {
    "version": "0.1.0",
    "publishedAt": 1772129788576,
    "commit": "https://github.com/openclaw/skills/commit/418d9c1c02b1a6a0cde9b51832f4d6fe432c013a"
  },
  "history": []
}

```

agentic-mcp-server-builder | SkillHub