mcpcli

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: MIT Imports: 17 Imported by: 0

README

mcpcli

Turn supplied MCP tool schemas into usable Go command-line interfaces. Cobra owns commands, flags, help, and shell completion; the official MCP Go SDK defines tools/results; Google's JSON Schema library validates arguments. The application owns authentication, transports, discovery, and domain behavior.

go get github.com/OlegHQ/mcpcli

Integrate

root, err := mcpcli.NewCommand(mcpcli.Options{
    Name: "nudge",
    Description: "Work with Nudge",
    Tools: tools, // []*mcp.Tool, available offline
    Invoke: func(ctx context.Context, name string, args json.RawMessage) (*mcp.CallToolResult, error) {
        return session.CallTool(ctx, &mcp.CallToolParams{Name: name, Arguments: args})
    },
    Bindings: map[string]mcpcli.Binding{
        "update_issue": {
            Path: []string{"issue", "update"},
            Positionals: []string{"id"},
            Flags: map[string]string{"patch.title": "title"},
            Columns: []mcpcli.Column{{Header: "ID", Path: "id"}},
        },
    },
})

The supplied schemas produce flag types, descriptions, string-enum completions, and validation. Explicit mappings make human command names intentional. Unmapped tools retain their tool name converted to kebab-case. AddCommands(root, options) adds generated commands to an existing Cobra tree and rejects command/flag collisions, including existing aliases and ancestor authentication/configuration flags. Treat a construction error as fatal and discard that command tree; construction may have already added preceding valid commands.

nudge issue update ISSUE-ID --title 'New title'
nudge issue update --input patch.json
cat patch.json | nudge issue update --input - --output json
nudge issue update --help

Help and completion do not call Invoke. Build a new command tree for each execution, as with ordinary mutable Cobra command objects. The executable controls exit codes: an execution error must produce a nonzero exit. errors.Is(err, mcpcli.ErrTool) distinguishes an MCP isError result.

Run the self-contained example:

go run ./examples/echo echo 'Hello'
go run ./examples/echo echo 'Hello' --output json

Inputs

Only changed flags and supplied positionals become arguments; schema defaults are not eagerly copied. Omitted values, false, zero, empty strings, empty arrays and JSON null retain their meaning. Primitive fields accept typed flag values; arrays and objects accept JSON. Inline nested object properties additionally produce flags such as --patch-title; Binding.Flags can rename them.

--input FILE accepts one complete JSON object; --input - reads stdin. It cannot combine with argument flags or positionals. The default maximum input is 20,000,000 bytes, configurable through Options.MaxInputBytes. Input JSON numbers retain their original representation when passed to Invoke. Validation uses native 64-bit integers and floating-point numbers; larger integers/out-of-range numbers fail explicitly.

The complete schema is validated by github.com/google/jsonschema-go, including properties not expanded into flags. Nested properties reached only through $ref or unions do not become flattened child flags. $ref, unions, and more complex nested schemas can use the parent JSON flag or --input; this library does not invent a competing JSON Schema engine. Property names containing dots should use whole-object input, because binding/column paths use dot notation. Schema flags conflicting with reserved names (input, output, help) or inherited flags must be renamed through bindings. For example, alias a tool’s url property to resource-url when the application already uses --url for its server endpoint. Command and flag names must start with an ASCII letter or digit and contain only letters, digits, hyphens, and underscores.

Outputs and errors

--output table renders human output with text/tabwriter. Binding.Columns selects stable useful fields; otherwise scalar keys are displayed. Common data and items envelopes are unwrapped for tables, with nextCursor displayed. Terminal control characters in human output are sanitized.

--output json emits the complete MCP CallToolResult, preserving both structuredContent and every content block. This is intentionally not a lossy text-only projection. Machine consumers can inspect .structuredContent directly.

Successful results go to Cobra's stdout writer. MCP tool errors go to its stderr writer and return ErrTool; transport errors propagate to the application's error boundary. No retry, prompt, credential logging, or automatic pagination occurs. Applications should sanitize private transport errors before exposing them. Render(writer, result, format, columns) is also available to existing commands.

The library installs --output only if it is not already inherited or present. Options.OutputFormat can supply an application resolver, for example to implement auto using its own terminal detection. It must return table or json.

Design references

Development

go test ./...
go vet ./...

MIT licensed. This library does not embed server credentials, discover remote servers implicitly, execute shell strings, or require a daemon.

Documentation

Overview

Package mcpcli adapts MCP tool schemas to Cobra commands. Applications own authentication, discovery, transport, and domain-specific presentation.

Index

Constants

This section is empty.

Variables

View Source
var ErrTool = errors.New("MCP tool failed")

Functions

func AddCommands

func AddCommands(root *cobra.Command, opts Options) error

func NewCommand

func NewCommand(opts Options) (*cobra.Command, error)

func Render

func Render(w io.Writer, result *mcp.CallToolResult, format string, columns []Column) error

Render emits the complete MCP result in JSON mode. Human mode presents structured content where available; applications supply useful column paths.

Types

type Binding

type Binding struct {
	Path        []string
	Positionals []string
	Flags       map[string]string
	Columns     []Column
}

type Column

type Column struct{ Header, Path string }

type Options

type Options struct {
	Name, Description, Version string
	Tools                      []*mcp.Tool
	Invoke                     InvokeFunc
	Bindings                   map[string]Binding
	// MaxInputBytes bounds --input files/stdin; zero uses 20,000,000 bytes.
	MaxInputBytes int64
	OutputFormat  func(*cobra.Command) string
}

Directories

Path Synopsis
examples
echo command
Example: an offline schema supplies CLI help; Invoke supplies execution.
Example: an offline schema supplies CLI help; Invoke supplies execution.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL