npm package: @sloop-dev/skill-forge
Description: A CLI middleware that bridges AI agents to MCP servers and CLI tools via skill files
Latest version: 0.1.0

# skill-forge

**A CLI middleware that bridges AI agents to MCP servers and CLI tools via lightweight skill files.**

## The Problem

Modern AI agents rely on tool definitions to interact with the outside world. As the number of tools grows, so does the context window overhead: full MCP schemas, argument descriptions, and usage examples eat into the tokens available for actual reasoning. A project with ten registered tools can easily burn thousands of tokens before the agent even starts working.

## The Solution

skill-forge sits between your AI agent and its tools. Instead of feeding raw schemas into the context window, it **generates compact Markdown skill files** that summarize each tool's capabilities, triggers, and invocation syntax. At runtime, the agent reads a single `SKILL.md` to discover what is available and calls tools through skill-forge's thin proxy layer.

```
                  SKILL.md
                     |
    AI Agent ----> skill-forge ----> MCP Server
                     |
                     +-------------> CLI Tool
```

The result: smaller context windows, faster agent loops, and a single registry for every tool your agent can reach.

## Architecture

```
+------------+       +--------------+       +----------------+
|            | add   |              | stdio |                |
|  AI Agent  +------>| skill-forge  +------>|   MCP Server   |
|            | call  |              |       |                |
|            |       |  - registry  |       +----------------+
|            |       |  - gen       |
|            |       |  - proxy     |       +----------------+
|            |       |              | spawn |                |
|            |       |              +------>|    CLI Tool     |
+------------+       +--------------+       +----------------+
                           |
                           v
                    skill-forge/
                      SKILL.md
                      references/
                        tool-a.md
                        tool-b.md
```

skill-forge manages a **tool registry** (JSON config), connects to MCP servers via the SDK stdio transport, and spawns CLI tools as child processes. The `gen` command introspects every registered tool and writes a `SKILL.md` plus per-tool reference files that any agent can consume.

## Installation

```bash
npm install -g skill-forge
```

**Requirements:** Node.js 18 or later.

Verify the installation:

```bash
skill-forge --version
```

## Quick Start

### 1. Register a tool

```bash
# Add an MCP server
skill-forge add my-server mcp --command npx --args @example/mcp-server

# Add a CLI tool
skill-forge add git-tool cli --command git
```

### 2. List registered tools

```bash
skill-forge list
```

```
  my-server (mcp) — npx
  git-tool (cli) — git
```

### 3. Generate skill files

```bash
skill-forge gen
```

This creates a `skill-forge/` directory containing `SKILL.md` and a `references/` folder with one file per tool.

### 4. Call a tool

```bash
# Call an MCP method
skill-forge call my-server list_files '{"path": "/src"}'

# Call a CLI tool
skill-forge call git-tool "status --short"
```

## Commands

| Command   | Description                                      |
| --------- | ------------------------------------------------ |
| `add`     | Register a new MCP or CLI tool                   |
| `update`  | Update settings for a registered tool            |
| `remove`  | Unregister a tool                                |
| `list`    | Show all registered tools                        |
| `gen`     | Generate skill files from registered tools       |
| `call`    | Invoke a registered MCP method or CLI command    |

---

### `add`

Register a new MCP or CLI tool in the config.

```bash
skill-forge add <name> <type> --command <cmd> [--args <items...>] [--env <pairs...>]
```

**Arguments:**

- `name` -- Unique identifier for the tool
- `type` -- `mcp` or `cli`

**Options:**

- `--command <cmd>` -- Command to execute (required)
- `--args <items...>` -- Arguments passed to the command (MCP only)
- `--env <pairs...>` -- Environment variables as `KEY=VALUE` pairs (MCP only)

**Examples:**

```bash
skill-forge add my-server mcp --command npx --args @example/mcp-server
skill-forge add my-server mcp --command node --args server.js --env API_KEY=abc123
skill-forge add docker cli --command docker
```

---

### `update`

Modify settings for a tool that is already registered.

```bash
skill-forge update <name> [--command <cmd>] [--args <items...>] [--env <pairs...>] [--timeout <ms>]
```

**Options:**

- `--command <cmd>` -- Replace the command
- `--args <items...>` -- Replace arguments (MCP only)
- `--env <pairs...>` -- Merge environment variables (MCP only)
- `--timeout <ms>` -- Set a custom timeout in milliseconds

**Example:**

```bash
skill-forge update my-server --timeout 60000
skill-forge update my-server --env API_KEY=new-value
```

---

### `remove`

Unregister a tool from the config.

```bash
skill-forge remove <name>
```

**Example:**

```bash
skill-forge remove my-server
```

---

### `list`

Display all registered tools with their type and command.

```bash
skill-forge list
```

---

### `gen`

Generate skill files by introspecting every registered tool. For MCP tools, skill-forge connects via stdio and calls `tools/list`. For CLI tools, it runs `--help` and parses the output.

```bash
skill-forge gen [-o, --output <dir>]
```

**Options:**

- `-o, --output <dir>` -- Output directory (defaults to `.`)

The command produces:

```
<output>/skill-forge/
  SKILL.md                  # Summary with trigger keywords
  .skill-forge-manifest.json  # Tracks config hashes for incremental updates
  references/
    my-server.md            # Detailed MCP tool schemas
    docker.md               # Parsed CLI help
```

A **manifest file** tracks the config hash of each tool. On subsequent runs, skill-forge detects added, removed, and changed tools so it can clean up stale reference files automatically.

---

### `call`

Invoke a tool through skill-forge's proxy layer.

```bash
# MCP tool — pass the method name and a JSON argument object
skill-forge call <name> <method> '<json>'

# CLI tool — pass the full command string
skill-forge call <name> "<command>"
```

**Examples:**

```bash
skill-forge call my-server list_files '{"path": "/src"}'
skill-forge call docker "ps -a --format json"
```

For MCP tools, skill-forge opens a stdio connection, sends the `tools/call` request, prints the JSON result, and disconnects. For CLI tools, it spawns the configured command with the provided arguments and streams stdout/stderr.

## Configuration

skill-forge stores its configuration at:

```
~/.skill-forge/config.json
```

**Format:**

```json
{
  "version": 1,
  "tools": {
    "my-server": {
      "type": "mcp",
      "command": "npx",
      "args": ["@example/mcp-server"],
      "env": {
        "API_KEY": "abc123"
      }
    },
    "docker": {
      "type": "cli",
      "command": "docker",
      "timeout": 15000
    }
  },
  "defaults": {
    "timeout": 30000
  }
}
```

**Fields:**

| Field              | Type     | Description                                         |
| ------------------ | -------- | --------------------------------------------------- |
| `version`          | `number` | Config format version (currently `1`)               |
| `tools`            | `object` | Map of tool name to tool configuration              |
| `defaults.timeout` | `number` | Default timeout in milliseconds (default: `30000`)  |

**Per-tool fields:**

| Field     | Type       | Applies to | Description                          |
| --------- | ---------- | ---------- | ------------------------------------ |
| `type`    | `string`   | all        | `"mcp"` or `"cli"`                   |
| `command` | `string`   | all        | Executable to run                    |
| `args`    | `string[]` | mcp        | Arguments passed to the command      |
| `env`     | `object`   | mcp        | Environment variables for the process|
| `timeout` | `number`   | all        | Per-tool timeout override (ms)       |

The config file is created automatically on first use. You can also edit it directly.

## How It Works

### Thin Proxy Architecture

skill-forge does not wrap or reimplement tool protocols. It acts as a **thin proxy**:

- **MCP tools** are connected via the official `@modelcontextprotocol/sdk` stdio transport. skill-forge spawns the server process, performs the JSON-RPC handshake, and forwards requests verbatim.
- **CLI tools** are spawned as child processes with arguments split by whitespace. No shell is invoked, so command strings are executed safely.

### Skill Generation

The `gen` command introspects each tool and produces Markdown output:

1. **MCP tools** -- skill-forge connects, calls `tools/list`, and renders each tool's name, description, parameter schema, and an example invocation.
2. **CLI tools** -- skill-forge runs `<command> --help`, parses the output into subcommands, and renders each with a description and example.

The top-level `SKILL.md` includes YAML front matter with trigger keywords that help agents decide when to use skill-forge.

### Manifest Sync

A `.skill-forge-manifest.json` file tracks the SHA-256 config hash of each tool. On subsequent `gen` runs, skill-forge compares hashes to detect changes and removes reference files for tools that are no longer registered.

## Security

skill-forge is designed to be safe by default:

- **No shell injection.** CLI tools are spawned with `shell: false`. The command string is split by whitespace into an argument array, preventing shell metacharacter injection.
- **Config file permissions.** On Unix-like systems, the config file is written with mode `600` (owner read/write only).
- **No secrets in generated files.** Skill files contain only tool names, descriptions, and usage examples. Environment variables and connection details stay in the config.
- **Timeouts.** Every tool invocation has a configurable timeout (default 30 seconds). On timeout, the process receives `SIGTERM` followed by `SIGKILL` after a 3-second grace period.

## Cross-Platform

skill-forge works on **Windows**, **macOS**, and **Linux**. The child process layer uses Node.js `spawn` directly, and the config directory resolves via `os.homedir()` on all platforms.

Config location by platform:

| Platform | Path                              |
| -------- | --------------------------------- |
| Linux    | `~/.skill-forge/config.json`      |
| macOS    | `~/.skill-forge/config.json`      |
| Windows  | `%USERPROFILE%\.skill-forge\config.json` |

## License

[MIT](./LICENSE)