forgejo-mcp/openspec/specs/cli-mode/spec.md
Christoph Görn d670de2d72 docs: 📝 add Purpose+Requirements headers to cli-mode spec
Spec lived under openspec/specs/ but kept the change-style
`## ADDED Requirements` header, which `openspec validate` rejects
for a finalized spec. Replace with `## Purpose` (new) and
`## Requirements`. No requirement or scenario content changed.

Closes forgejo-mcp-6un.
2026-05-11 16:29:28 +02:00

105 lines
5.8 KiB
Markdown

## Purpose
CLI mode lets users invoke registered MCP tools directly from the shell, without launching the MCP server. It supports scripting, ad-hoc inspection of Forgejo data, and pipelines that pass JSON between tools. The CLI surface mirrors the MCP tool catalog: every tool registered for the server is reachable from `forgejo-mcp --cli <tool-name>`.
## Requirements
### Requirement: CLI mode flag bypasses MCP server
The binary SHALL accept a `--cli` global flag that routes execution to direct tool invocation instead of starting the MCP server. When `--cli` is present, the binary MUST NOT start a stdio or SSE transport.
#### Scenario: CLI mode entry
- **WHEN** the user runs `forgejo-mcp --cli list`
- **THEN** the binary enters CLI mode and does not start an MCP server
#### Scenario: Normal mode unaffected
- **WHEN** the user runs `forgejo-mcp` without `--cli`
- **THEN** the binary starts the MCP server as before (stdio or SSE)
### Requirement: CLI list enumerates tools grouped by domain
The `--cli list` subcommand SHALL print all registered tools to stdout, grouped by domain (user, repo, issue, pull, search, version). Each entry MUST show the tool name and its description.
#### Scenario: List tools in human-readable format
- **WHEN** the user runs `forgejo-mcp --cli list`
- **THEN** stdout contains all registered tools grouped under domain headings, with each tool showing its name and description
#### Scenario: List tools as JSON
- **WHEN** the user runs `forgejo-mcp --cli list --json`
- **THEN** stdout contains a JSON array of tool objects, each with `name`, `description`, and `domain` fields
### Requirement: CLI tool execution with inline args
The `--cli <tool-name> --args '<json>'` form SHALL invoke the named tool handler with the provided JSON arguments and print the result to stdout.
#### Scenario: Invoke tool with inline JSON args
- **WHEN** the user runs `forgejo-mcp --cli get_my_user_info --args '{}'`
- **THEN** the tool handler is called with the parsed JSON arguments and the result is printed as JSON to stdout
#### Scenario: Unknown tool name
- **WHEN** the user runs `forgejo-mcp --cli nonexistent_tool --args '{}'`
- **THEN** the binary prints an error to stderr naming the unknown tool, exits with non-zero code
#### Scenario: Invalid JSON in --args
- **WHEN** the user runs `forgejo-mcp --cli get_my_user_info --args 'not json'`
- **THEN** the binary prints a JSON parse error to stderr and exits with non-zero code
### Requirement: CLI tool execution with stdin pipe
The binary SHALL accept JSON arguments from stdin when `--args` is not provided and stdin is not a terminal.
#### Scenario: Pipe JSON via stdin
- **WHEN** the user runs `echo '{"owner":"goern","repo":"forgejo-mcp"}' | forgejo-mcp --cli list_repo_issues`
- **THEN** the tool handler is called with the piped JSON and the result is printed to stdout
#### Scenario: Inline args take precedence over stdin
- **WHEN** the user provides both `--args '{...}'` and pipes JSON to stdin
- **THEN** the `--args` value is used and stdin is ignored
### Requirement: CLI tool help
The `--cli <tool-name> --help` form SHALL print the tool's parameter schema in a human-readable format.
#### Scenario: Show tool parameters
- **WHEN** the user runs `forgejo-mcp --cli create_issue --help`
- **THEN** stdout lists each parameter with its name, type, required/optional status, and description
### Requirement: Global output format flag
The CLI SHALL accept `--output=json|text` to control output formatting. The default SHALL be `json` for tool execution and `text` for `list`. When `--output=text` is used with tool execution, the content text fields SHALL be printed as plain text (one per line). When `--output=json` is used with `list`, a JSON array of tool objects SHALL be printed.
#### Scenario: Explicit JSON output for list
- **WHEN** the user runs `forgejo-mcp --cli list --output=json`
- **THEN** stdout contains a JSON array of tool objects
#### Scenario: Explicit text output for tool execution
- **WHEN** the user runs `forgejo-mcp --cli get_my_user_info --args '{}' --output=text`
- **THEN** stdout contains the result content as plain text
#### Scenario: Default output for tool execution is JSON
- **WHEN** the user runs `forgejo-mcp --cli get_my_user_info --args '{}'` without `--output`
- **THEN** the result is printed as JSON to stdout
#### Scenario: Default output for list is text
- **WHEN** the user runs `forgejo-mcp --cli list` without `--output`
- **THEN** the tools are printed as a human-readable grouped table
### Requirement: CLI output format
Tool execution results SHALL be written to stdout. Errors SHALL be written as text to stderr with a non-zero exit code.
#### Scenario: Successful tool execution output
- **WHEN** a tool handler returns a successful `CallToolResult`
- **THEN** the result content is written to stdout and the exit code is 0
#### Scenario: Tool handler error
- **WHEN** a tool handler returns an error
- **THEN** the error message is printed to stderr and the exit code is non-zero
#### Scenario: Tool result with IsError flag
- **WHEN** a tool handler returns a `CallToolResult` with `IsError: true`
- **THEN** the result content is printed to stderr and the exit code is non-zero
### Requirement: CLI mode requires Forgejo connection config
CLI mode SHALL require the same Forgejo URL and access token configuration as MCP server mode. The `--url` flag and `FORGEJO_URL` / `FORGEJO_ACCESS_TOKEN` environment variables MUST work identically.
#### Scenario: Missing URL in CLI mode
- **WHEN** the user runs `forgejo-mcp --cli list` without providing a URL
- **THEN** the binary exits with an error indicating the URL is required
#### Scenario: Environment variable configuration
- **WHEN** `FORGEJO_URL` and `FORGEJO_ACCESS_TOKEN` are set
- **THEN** CLI mode uses those values for the Forgejo connection