# Swift Argument Parser Mcp

> A Swift library that turns any ArgumentParser CLI into an MCP server, letting AI agents call your commands as tools.

- **Type:** MCP server
- **Install:** `agentstack add mcp-ilia3546-swift-argument-parser-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ilia3546](https://agentstack.voostack.com/s/ilia3546)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [ilia3546](https://github.com/ilia3546)
- **Source:** https://github.com/ilia3546/swift-argument-parser-mcp

## Install

```sh
agentstack add mcp-ilia3546-swift-argument-parser-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Swift Argument Parser MCP

[](https://github.com/ilia3546/swift-argument-parser-mcp/actions/workflows/ci.yml)
[](https://swiftpackageindex.com/ilia3546/swift-argument-parser-mcp)
[](https://swiftpackageindex.com/ilia3546/swift-argument-parser-mcp)
[](https://swiftpackageindex.com/ilia3546/swift-argument-parser-mcp/documentation)
[](LICENSE)
[](https://boosty.to/ilia3546/donate)

**Turn any Swift CLI into an MCP server in minutes.**

ArgumentParserMCP lets AI agents call your [Swift Argument Parser][sap] commands
as tools via the [Model Context Protocol][mcp].
Add one conformance, register your commands, and your CLI is ready for Claude, Cursor, and other MCP clients.

[sap]: https://github.com/apple/swift-argument-parser
[mcp]: https://modelcontextprotocol.io

## Usage

Start with a regular Argument Parser command and conform it to `MCPCommand`:

```swift
import ArgumentParser
import ArgumentParserMCP

struct RepeatPhrase: ParsableCommand, MCPCommand {

    static let configuration = CommandConfiguration(
        abstract: "Repeat a phrase multiple times."
    )

    @Flag(help: "Include a counter with each repetition.")
    var includeCounter = false

    @Option(name: .shortAndLong, help: "How many times to repeat 'phrase'.")
    var count: Int? = nil

    @Argument(help: "The phrase to repeat.")
    var phrase: String

    mutating func run() throws {
        let repeatCount = count ?? 2
        for i in 1...repeatCount {
            if includeCounter {
                print("\(i): \(phrase)")
            } else {
                print(phrase)
            }
        }
    }
}
```

Then add a subcommand that starts the MCP server:

```swift
import ArgumentParser
import ArgumentParserMCP

struct MCP: AsyncParsableCommand {

    static let configuration = CommandConfiguration(
        abstract: "MCP Server for AI agents"
    )

    mutating func run() async throws {
        let server = MCPServer(
            name: "my-cli",
            version: "1.0.0",
            commands: [RepeatPhrase.self]
        )
        try await server.start()
    }
}
```

Register both subcommands in your root command:

```swift
@main
struct MyCLI: AsyncParsableCommand {

    static let configuration = CommandConfiguration(
        subcommands: [
            RepeatPhrase.self,
            MCP.self,
        ]
    )
}
```

That's it. Your CLI now speaks MCP over stdio when invoked with the `mcp` subcommand:

```
$ my-cli mcp
```

The library automatically introspects your CLI via `--experimental-dump-help`,
generates JSON Schema for every registered command,
and dispatches tool calls back to the same binary as subprocesses.

## How It Works

```
AI Agent ──stdio──> my-cli mcp (MCPServer)
                       |
                       |── tools/list  -> tool definitions from --experimental-dump-help
                       |
                       └── tools/call  -> my-cli repeat-phrase --count 3 "hello"
                                          merged log + structured result
```

1. On startup, `MCPServer` runs the current executable with `--experimental-dump-help`
   to discover the full command tree and argument metadata.
2. For each registered `MCPCommand`, it builds an MCP tool with a JSON Schema `inputSchema`
   derived from the command's arguments, options, and flags.
3. When an agent calls a tool, the server converts JSON arguments back to CLI arguments
   and invokes the appropriate subcommand as a child process.

### Tool Call Result

Every tool call produces two parallel views of the subprocess output:

- A human-readable **text content block** with stdout and stderr interleaved in
  best-effort line-arrival order. Lines that came from stderr are prefixed with
  `[stderr] ` so they remain distinguishable in the merged form.
- A **`structuredContent`** object for programmatic consumption:

  ```json
  {
    "stdout": "...",
    "stderr": "...",
    "exitCode": 0,
    "terminationReason": "exit",
    "stdoutTruncated": false,
    "stderrTruncated": false,
    "durationMs": 42
  }
  ```

  `terminationReason` is `"exit"` for a normal exit or `"uncaughtSignal"` if the
  child was killed. `isError` is set when the process exits non-zero or is killed.

Captured output is capped per stream (default 256 KiB) to keep large outputs
from blowing up the agent's context. When the cap is hit the relevant
`*Truncated` flag is set. Adjust via the `outputCapBytes` parameter on
`MCPServer.init`.

> The merged log approximates what a developer would see in a terminal, not
> the exact write order at the source — pipe and libc buffering on the
> child's side mean order is best-effort. For strict checks, use
> `structuredContent.exitCode` and the raw `stdout` / `stderr` fields.

## Customization

### Custom Tool Descriptions

By default, the MCP tool description is built from `CommandConfiguration.abstract` and `.discussion`.
Override `mcpDescription` for a custom one:

```swift
extension RepeatPhrase: MCPCommand {

    static var mcpDescription: String {
        "Repeats a given phrase N times. Useful for testing and demonstrations."
    }
}
```

### Argument Interceptor

Use `transformArguments` to add, remove, or modify CLI arguments before execution on a per-command basis:

```swift
extension Deploy: MCPCommand {

    static func transformArguments(_ arguments: [String]) -> [String] {
        arguments + ["--non-interactive"]
    }
}
```

### Global Arguments

Pass arguments that should be appended to every command invocation:

```swift
let server = MCPServer(
    name: "my-cli",
    version: "1.0.0",
    commands: [Deploy.self, Status.self],
    globalArguments: ["--verbose"]
)
```

### Server Instructions

Pass an `instructions` string to give the agent server-level context about your
CLI — what it's for, when to reach for which tool, or conventions to follow.
MCP clients surface this during the `initialize` handshake:

```swift
let server = MCPServer(
    name: "my-cli",
    version: "1.0.0",
    commands: [Deploy.self, Status.self],
    instructions: """
        Production deploy CLI. Run `status` before `deploy`. \
        Tool calls are non-interactive; never wait for prompts.
        """
)
```

## Adding `ArgumentParserMCP` as a Dependency

To use the `ArgumentParserMCP` library in a SwiftPM project,
add it to the dependencies for your package and your CLI target:

```swift
let package = Package(
    // name, platforms, products, etc.
    dependencies: [
        .package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
        .package(url: "https://github.com/ilia3546/swift-argument-parser-mcp", from: "1.0.0"),
    ],
    targets: [
        .executableTarget(name: "", dependencies: [
            .product(name: "ArgumentParser", package: "swift-argument-parser"),
            .product(name: "ArgumentParserMCP", package: "swift-argument-parser-mcp"),
        ]),
    ]
)
```

### Connecting to an MCP Client

Add your CLI to the client's MCP configuration. For example, in Claude Code (`settings.json`):

```json
{
  "mcpServers": {
    "my-cli": {
      "command": "/path/to/my-cli",
      "args": ["mcp"]
    }
  }
}
```

## Documentation

API documentation is generated automatically from source and hosted by Swift Package Index:

- [ArgumentParserMCP documentation][docs]

[docs]: https://swiftpackageindex.com/ilia3546/swift-argument-parser-mcp/documentation/argumentparsermcp

## Requirements

- Swift 6.0+
- macOS 13+ or Linux

## License

This library is released under the Apache 2.0 license. See [LICENSE](LICENSE) for details.

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ilia3546](https://github.com/ilia3546)
- **Source:** [ilia3546/swift-argument-parser-mcp](https://github.com/ilia3546/swift-argument-parser-mcp)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-ilia3546-swift-argument-parser-mcp
- Seller: https://agentstack.voostack.com/s/ilia3546
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
