Skip to content

generate-cli: auto-generate SKILL.md agent skill#3115

Merged
jlowin merged 7 commits intomainfrom
generate-cli-skill
Feb 8, 2026
Merged

generate-cli: auto-generate SKILL.md agent skill#3115
jlowin merged 7 commits intomainfrom
generate-cli-skill

Conversation

@jlowin
Copy link
Copy Markdown
Member

@jlowin jlowin commented Feb 8, 2026

generate-cli now produces a SKILL.md alongside the CLI script — a Claude Code agent skill that pre-computes every tool's exact invocation syntax. An agent reading the skill can immediately call tools without running --help or experimenting with flag names.

$ fastmcp generate-cli weather
Discovered 3 tool(s) from weather
✓ Wrote cli.py with 3 tool command(s)
✓ Wrote SKILL.md

The generated skill includes typed parameter tables, example invocations, and utility commands:

### get_forecast

Get the weather forecast for a city.

python cli.py call-tool get_forecast --city <value> --days <value>

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--city` | string | yes | City name |
| `--days` | integer | no | Number of forecast days |

Skill generation is on by default; pass --no-skill to opt out. Both files are protected by the existing -f overwrite check.

generate-cli now produces a SKILL.md agent skill file next to the CLI
script, documenting every tool's exact invocation syntax, parameter
flags, and types. Agents can use the CLI immediately without discovery.
@jlowin jlowin added the feature Major new functionality. Reserved for 2-4 significant PRs per release. Not for issues. label Feb 8, 2026
@marvin-context-protocol marvin-context-protocol Bot added enhancement Improvement to existing functionality. For issues and smaller PR improvements. cli Related to FastMCP CLI commands (run, dev, install) or CLI functionality. and removed feature Major new functionality. Reserved for 2-4 significant PRs per release. Not for issues. labels Feb 8, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48a38e172b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +588 to +591
f"{description} (JSON string)" if description else "JSON string"
)
description = description.replace("|", "\\|")
rows.append(f"| {flag} | {type_label} | {is_required} | {description} |")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Escape union type labels in SKILL.md tables

When a parameter schema uses a union type (e.g., {"type": ["string", "null"]}), _schema_type_label returns a string containing " | ". In _tool_skill_section, that type_label is inserted directly into the markdown table while only the description is escaped. The unescaped pipe characters split the table into extra columns, producing malformed SKILL.md output for any tool with union-typed parameters. Escaping type_label the same way as description, or rendering union types without |, would avoid the formatting break.

Useful? React with 👍 / 👎.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 8, 2026

Walkthrough

The CLI generator now produces a companion SKILL.md by default and will refuse to overwrite if either the CLI file or its companion SKILL.md already exists (unless forced). Generation of SKILL.md can be skipped with the --no-skill option. A new public function generate_skill_content(server_name: str, cli_filename: str, tools: list[mcp.types.Tool]) -> str and internal helpers build per-tool sections, map JSON Schema to CLI flags and human-readable types, and emit usage/invocation examples. Documentation was updated to describe SKILL.md and the --no-skill option.

Possibly related PRs

  • jlowin/fastmcp PR 3065: Adds and modifies src/fastmcp/cli/generate.py and the original generate_cli_command flow that this change extends with SKILL.md generation and the --no-skill option.
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is comprehensive and well-structured but does not include the Contributors Checklist and Review Checklist sections required by the repository template. Add the Contributors Checklist and Review Checklist from the template with appropriate checkboxes marked to confirm testing, documentation updates, self-review, and issue closure.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: auto-generating SKILL.md alongside CLI scripts in the generate-cli command.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch generate-cli-skill

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Comment thread docs/clients/generate-cli.mdx
Comment thread src/fastmcp/cli/generate.py Outdated
Comment thread src/fastmcp/cli/generate.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment thread src/fastmcp/cli/generate.py
- Escape pipe chars in union type labels so markdown tables render
- Boolean params omit <value> placeholder in example invocations
- Quote YAML frontmatter values to handle special chars in names
- Match cyclopts camelCase→snake_case in flag derivation
- Use four-backtick fence for nested code block in docs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment thread src/fastmcp/cli/generate.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment thread src/fastmcp/cli/generate.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/fastmcp/cli/generate.py (1)

525-533: _JSON_SCHEMA_TYPE_LABELS is an identity mapping — consider simplifying.

Every key equals its value. You could replace _JSON_SCHEMA_TYPE_LABELS.get(t, t) with just t (or a set membership check if the intent is validation). If you plan to diverge keys from values in the future (e.g., "integer""int"), then keeping the dict as a forward-looking mapping is fine.

Comment thread src/fastmcp/cli/generate.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment on lines +588 to +590
invocation = f"uv run --with fastmcp python {cli_filename} call-tool {tool.name}"
if flag_parts:
invocation += f" {flag_parts}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Tool names containing spaces or shell metacharacters will produce broken invocation examples.

tool.name is interpolated directly into the bash example without quoting. While MCP tool names are typically simple identifiers, the spec doesn't forbid special characters. Consider quoting the tool name in the invocation.

Proposed fix
-    invocation = f"uv run --with fastmcp python {cli_filename} call-tool {tool.name}"
+    invocation = f"uv run --with fastmcp python {cli_filename} call-tool '{tool.name}'"

@jlowin jlowin merged commit f7cdd20 into main Feb 8, 2026
15 checks passed
@jlowin jlowin deleted the generate-cli-skill branch February 8, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli Related to FastMCP CLI commands (run, dev, install) or CLI functionality. enhancement Improvement to existing functionality. For issues and smaller PR improvements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant