Version: 0.2.0
Status: Draft
Last Updated: 2026-01-21
This document describes how to use Cobra to automatically generate:
--ai-helpoutput — Markdown with YAML front matter (per CLI spec)- MCP server — Auto-generated from command tree
- Cross-references — Link between CLI, MCP, API, and Web access methods
The goal is minimal code changes for existing Cobra CLIs to become fully dashdash-compliant.
┌─────────────────────┐
│ Cobra CLI App │
│ (existing) │
└──────────┬──────────┘
│
├─→ --ai-help → Markdown + YAML front matter
│
├─→ --mcp-serve → MCP server (JSON-RPC over stdio)
│
└─→ Normal Mode → Standard CLI execution
┌────────────────────────────────────┐
│ cobra-dashdash │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ AI Help Gen │ │ MCP Bridge │ │
│ │ - Introspect│ │ - Introspect │ │
│ │ - Format MD │ │ - JSON-RPC │ │
│ │ - YAML FM │ │ - Execute │ │
│ └─────────────┘ └──────────────┘ │
└────────────────────────────────────┘
package main
import (
"os"
"github.com/spf13/cobra"
"github.com/visionik/cobra-dashdash"
)
func main() {
rootCmd := &cobra.Command{
Use: "myapp",
Short: "My CLI application",
Long: "A longer description for my CLI application.",
}
// Add your commands
rootCmd.AddCommand(searchCmd, listCmd, createCmd)
// Add dashdash integration (adds --ai-help and --mcp-serve flags)
dashdash.Integrate(rootCmd, &dashdash.Config{
Name: "myapp",
Description: "CLI for MyApp. Use when user asks to search, list, or create items.",
Version: "1.0.0",
// Alternative access methods
WebURL: "https://myapp.com",
APIURL: "https://api.myapp.com/docs",
MCPURL: "https://github.com/myorg/myapp-mcp",
// Installation
Install: map[string]string{
"brew": "myorg/tap/myapp",
"go": "github.com/myorg/myapp@latest",
},
// Requirements
Requires: &dashdash.Requirements{
Auth: []string{"api-key"},
Env: []string{"MYAPP_API_KEY"},
},
})
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}# Normal CLI
myapp search "query"
# AI help (full markdown with front matter)
myapp --ai-help
# Command-specific help
myapp search --ai-help
# MCP server mode
myapp --mcp-serveThe --ai-help flag introspects the Cobra command tree and generates:
- YAML front matter with dashdash metadata
- When to Use section from command descriptions
- Quick Reference from all leaf commands
- Command Reference with full details
- Cross-references to alternative access methods
myapp --ai-helpProduces:
---
name: myapp
description: >
CLI for MyApp.
Use when user asks to search, list, or create items.
spec-url: https://github.com/visionik/dashdash
spec-version: 0.2.0
subcommand-help: true
access-level: interact
cli-url: none
api-url: https://api.myapp.com/docs
web-url: https://myapp.com
mcp-url: https://github.com/myorg/myapp-mcp
install:
brew: myorg/tap/myapp
go: github.com/myorg/myapp@latest
requires:
auth:
- api-key
env:
- MYAPP_API_KEY
invocation:
model-invocable: true
user-invocable: true
homepage: https://myapp.com
content-version: 1.0.0
---
# myapp
> CLI for MyApp
## When to Use
Use this tool when the user asks to:
- Search for items in MyApp
- List available resources
- Create new items
## Quick Reference
- **Search items:** `myapp search [query] --limit 10`
- **List all:** `myapp list --format json`
- **Create item:** `myapp create --name "Name" --type default`
## Command Reference
### myapp search
Search for items.
**Usage:** `myapp search [query] [flags]`
**Arguments:**
- `query` (required): Search query string
**Flags:**
- `--limit, -l` (int): Maximum results (default: 10)
- `--format, -f` (string): Output format (default: "table")
**Example:**
```bash
myapp search "golang" --limit 5 --format jsonList all items.
Usage: myapp list [flags]
Flags:
--format, -f(string): Output format (default: "table")--all, -a(bool): Include archived items
Create a new item.
Usage: myapp create [flags]
Flags:
--name, -n(string, required): Item name--type, -t(string): Item type (default: "default")
Set the MYAPP_API_KEY environment variable:
export MYAPP_API_KEY="your_api_key"
### Command-Level Help
With `subcommand-help: true`, individual commands also support `--ai-help`:
```bash
myapp search --ai-help
Produces focused documentation for just that command (no front matter).
Use annotations to specify trigger phrases:
searchCmd := &cobra.Command{
Use: "search [query]",
Short: "Search for items",
Annotations: map[string]string{
"dashdash:triggers": "search items, find items, look up items",
},
}searchCmd := &cobra.Command{
Use: "search [query]",
Short: "Search for items",
Example: ` myapp search "golang" --limit 5
myapp search "api" --format json`,
}deleteCmd := &cobra.Command{
Use: "delete [id]",
Short: "Delete an item",
Annotations: map[string]string{
"dashdash:dangerous": "true",
"dashdash:reversible": "false",
},
}listCmd := &cobra.Command{
Use: "list",
Short: "List items",
Annotations: map[string]string{
"dashdash:output-format": "json",
"dashdash:output-schema": `{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}`,
},
}The --mcp-serve flag starts an MCP server that:
- Introspects the Cobra command tree
- Exposes each leaf command as an MCP tool
- Executes commands when tools are called
- Returns structured output
# Start MCP server (stdio JSON-RPC)
myapp --mcp-serve
# Or with environment variable
MCP_MODE=true myapp{
"mcpServers": {
"myapp": {
"command": "myapp",
"args": ["--mcp-serve"],
"env": {
"MYAPP_API_KEY": "your_api_key"
}
}
}
}Each Cobra command becomes an MCP tool:
Cobra Command:
searchCmd := &cobra.Command{
Use: "search [query]",
Short: "Search for items",
Args: cobra.ExactArgs(1),
}
searchCmd.Flags().IntP("limit", "l", 10, "Maximum results")
searchCmd.Flags().StringP("format", "f", "json", "Output format")Generated MCP Tool:
{
"name": "search",
"description": "Search for items",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query"
},
"limit": {
"type": "integer",
"description": "Maximum results",
"default": 10
},
"format": {
"type": "string",
"description": "Output format",
"default": "json"
}
},
"required": ["query"]
}
}Nested commands are flattened with underscores:
// git → remote → add
gitCmd := &cobra.Command{Use: "git"}
remoteCmd := &cobra.Command{Use: "remote"}
addCmd := &cobra.Command{Use: "add [name] [url]", Short: "Add remote"}
remoteCmd.AddCommand(addCmd)
gitCmd.AddCommand(remoteCmd)Becomes MCP tool: git_remote_add
The MCP server includes dashdash extensions:
{
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "myapp",
"version": "1.0.0"
},
"capabilities": {
"tools": {}
},
"dashdash": {
"specVersion": "0.2.0",
"identity": {
"name": "myapp",
"description": "CLI for MyApp. Use when user asks to search, list, or create items."
},
"accessLevel": "interact",
"alternativeAccess": {
"cliUrl": null,
"apiUrl": "https://api.myapp.com/docs",
"webUrl": "https://myapp.com"
}
}
}Each tool includes operational metadata:
{
"name": "create",
"description": "Create a new item",
"inputSchema": {...},
"dashdash": {
"category": "write",
"operationType": "write",
"idempotent": false,
"sideEffects": ["creates resource"],
"reversible": true,
"reverseMethod": "delete",
"cliEquivalent": "myapp create --name {name}",
"apiEquivalent": "POST /api/items"
}
}The MCP server also exposes an ai_help method:
{
"method": "ai_help",
"params": {"format": "markdown"}
}Returns the same content as --ai-help.
| Cobra Type | JSON Schema | Notes |
|---|---|---|
string |
string |
Direct |
int, int64 |
integer |
Direct |
float64 |
number |
Direct |
bool |
boolean |
Direct |
stringSlice |
array of string |
Comma-separated |
intSlice |
array of integer |
Comma-separated |
stringToString |
object |
key=value pairs |
duration |
string with pattern |
e.g., "5m", "30s" |
count |
integer |
Incremental (-v -v -v) |
Arguments are extracted from the Use string:
Use: "search [query]" // → optional "query" argument
Use: "delete <id>" // → required "id" argument
Use: "echo [message...]" // → variadic "message" argumentOr explicitly annotated:
cmd.Annotations = map[string]string{
"dashdash:args": `[
{"name": "query", "type": "string", "required": true, "description": "Search query"}
]`,
}dashdash.Integrate(rootCmd, &dashdash.Config{
// Identity (required)
Name: "myapp",
Description: "CLI for MyApp. Use when user asks to...",
Version: "1.0.0",
// Access level
AccessLevel: "interact", // read | browse | interact | full
// Alternative access methods
WebURL: "https://myapp.com",
APIURL: "https://api.myapp.com/docs",
MCPURL: "https://github.com/myorg/myapp-mcp",
// Installation
Install: map[string]string{
"brew": "myorg/tap/myapp",
"go": "github.com/myorg/myapp@latest",
"npm": "@myorg/myapp",
},
// Requirements
Requires: &dashdash.Requirements{
Bins: []string{"myapp"},
OS: []string{"darwin", "linux"},
Auth: []string{"api-key"},
Env: []string{"MYAPP_API_KEY"},
Scopes: []string{"read:items", "write:items"},
},
// Invocation control
Invocation: &dashdash.Invocation{
ModelInvocable: true,
UserInvocable: true,
},
// Documentation
Homepage: "https://myapp.com",
Repository: "https://github.com/myorg/myapp",
StatusPage: "https://status.myapp.com",
// Rate limits
RateLimit: "1000/hour",
// MCP options
MCPOptions: &dashdash.MCPOptions{
// Filter which commands to expose
CommandFilter: func(cmd *cobra.Command) bool {
return !cmd.Hidden && cmd.Runnable()
},
// Force JSON output in MCP mode
ForceJSONOutput: true,
// Parse output
OutputParser: func(raw string) (interface{}, error) {
var result interface{}
json.Unmarshal([]byte(raw), &result)
return result, nil
},
},
// AI help options
AIHelpOptions: &dashdash.AIHelpOptions{
// Include examples in quick reference
IncludeExamples: true,
// Group commands by category
GroupByCategory: true,
// Custom sections
CustomSections: map[string]string{
"Rate Limits": "Free: 100/hour, Pro: 1000/hour",
},
},
})# Force MCP mode
MCP_MODE=true myapp
# Disable AI help flag
DASHDASH_DISABLE_AI_HELP=true myapp
# Disable MCP serve flag
DASHDASH_DISABLE_MCP_SERVE=true myapprootCmd.Annotations = map[string]string{
"dashdash:when-to-use": `
- Search for items by keyword
- List all available resources
- Create new items with metadata
- Delete items by ID`,
"dashdash:when-not-to-use": `
- File system operations (use filesystem tools)
- Code editing (use code editor)`,
}Document API equivalents for each command:
createCmd.Annotations = map[string]string{
"dashdash:api-equivalent": "POST /api/items",
"dashdash:api-body": `{"name": "{name}", "type": "{type}"}`,
}updateCmd.Annotations = map[string]string{
"dashdash:idempotent": "true",
"dashdash:side-effects": "updates resource, sends webhook",
"dashdash:reversible": "true",
"dashdash:reverse-method": "restore",
}searchCmd.Annotations = map[string]string{
"dashdash:errors": `[
{"code": "AUTH_FAILED", "message": "Invalid API key", "resolution": "Check MYAPP_API_KEY"},
{"code": "RATE_LIMITED", "message": "Too many requests", "resolution": "Wait and retry"}
]`,
}// Integrate adds --ai-help and --mcp-serve to a Cobra command
func Integrate(rootCmd *cobra.Command, config *Config)
// GenerateAIHelp produces markdown with YAML front matter
func GenerateAIHelp(rootCmd *cobra.Command, config *Config) string
// ServeMCP starts an MCP server over stdio
func ServeMCP(rootCmd *cobra.Command, config *Config) error
// CommandToMCPTool converts a Cobra command to MCP tool definition
func CommandToMCPTool(cmd *cobra.Command) MCPTooltype Config struct {
Name string
Description string
Version string
AccessLevel string
WebURL string
APIURL string
MCPURL string
Install map[string]string
Requires *Requirements
Invocation *Invocation
Homepage string
Repository string
StatusPage string
RateLimit string
MCPOptions *MCPOptions
AIHelpOptions *AIHelpOptions
}
type Requirements struct {
Bins []string
OS []string
Auth []string
Env []string
Scopes []string
}
type Invocation struct {
ModelInvocable bool
UserInvocable bool
AllowedTools []string
}
type MCPTool struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema JSONSchema `json:"inputSchema"`
Dashdash *ToolMeta `json:"dashdash,omitempty"`
}
type ToolMeta struct {
Category string `json:"category,omitempty"`
OperationType string `json:"operationType,omitempty"`
Idempotent bool `json:"idempotent,omitempty"`
SideEffects []string `json:"sideEffects,omitempty"`
CLIEquivalent string `json:"cliEquivalent,omitempty"`
APIEquivalent string `json:"apiEquivalent,omitempty"`
}- YAML front matter with all required fields
- "When to Use" section
- "Quick Reference" section
- Full command reference
- Cross-references to API, Web, MCP
- Subcommand-level
--ai-helpsupport
-
tools/listwith all commands -
tools/callexecution -
ai_helpmethod - dashdash extensions in server info
- Tool-level operational metadata
- JSON output forcing
dashdash:triggers— Trigger phrases for When to Usedashdash:when-to-use— Full When to Use contentdashdash:when-not-to-use— Negative examplesdashdash:api-equivalent— REST API equivalentdashdash:idempotent— Idempotency markerdashdash:side-effects— Side effect listdashdash:reversible— Can be undonedashdash:reverse-method— Undo commanddashdash:dangerous— Requires confirmationdashdash:output-format— Expected output formatdashdash:output-schema— JSON schema for outputdashdash:errors— Common errors with resolutionsdashdash:args— Explicit argument specifications
- Cobra Documentation
- dashdash CLI --ai-help Spec
- dashdash MCP Enhancements
- Model Context Protocol
- JSON Schema
This specification is released under CC0 1.0 Universal.