> For the complete documentation index, see [llms.txt](https://skyforgeai.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://skyforgeai.gitbook.io/docs/use/running-skyforge.md).

# Running SkyForge

Run modes, ports, MCP client connections, logs, keyboard shortcuts, and agents.

***

## Run modes

### Web interface (default)

```bash
skyforge
# or explicitly:
skyforge web
```

Opens `http://127.0.0.1:4096` in your browser.

### TUI (terminal interface)

```bash
skyforge tui
```

### Headless server (API only)

```bash
skyforge serve
skyforge serve --port 8080 --mcp-port 9000
```

### Run with a prompt directly

```bash
skyforge run "query the last 5 critical incidents"
```

### Attach TUI to a running server

```bash
skyforge attach http://host:4096
```

### Update

```bash
skyforge update            # updates to latest via npm
skyforge update <version>  # updates to a specific version
```

Runs `npm install -g @skyforgeai/skyforge@<target>` under the hood.

### Export skills for Claude Desktop / Claude Code

Package SkyForge's agent instructions as a Claude Skill, so you can use SkyForge's ServiceNow expertise inside Claude Desktop or Claude Code (paired with the SkyForge MCP server for tool access).

```bash
skyforge export-skills              # orchestrator skill only → ~/skyforge-skills/_zips/skyforge.zip
skyforge export-skills --all        # orchestrator + reviewer + all 71 domain skills (one zip each)
skyforge export-skills ./my-skills  # custom output dir
```

By default this exports only the **`skyforge` orchestrator skill** (always zipped). That's all you need to upload — the orchestrator loads domain skills (servicenow-dev, business-rule-patterns, reviewer, etc.) on demand through the `sn_load_skill` MCP tool, so you don't upload all 73 individually.

**Claude Desktop (upload):**

```bash
skyforge export-skills
# then in Claude: Customize → Skills → "+" → upload ~/skyforge-skills/_zips/skyforge.zip
```

**Claude Code (local folder):**

```bash
skyforge export-skills --all
cp -r ~/skyforge-skills/*/ ~/.claude/skills/
```

Run `skyforge` (or `skyforge serve` for headless) so the MCP tools — and `sn_load_skill` — are available alongside the skill.

**How it works:** the uploaded `skyforge` skill auto-triggers on any ServiceNow task and tells Claude how to work — load `servicenow-dev` first, confirm application scope, create an Update Set, load the matching domain skill, then build, loading the reviewer protocol before emitting code. ServiceNow tools aren't called directly; Claude uses `tool_search` to find them and `tool_execute({ tool, args })` to run them, with `sn_load_skill` delivering skill content on demand. Restart Claude Desktop after re-uploading the skill or restarting the server so it reconnects.

***

## Ports & Server

By default SkyForge runs on:

* **Main server** (web UI + API): `:4096`
* **HTTP MCP server** (VS Code / Claude Code / Claude Desktop): `:3006`

Both bind to `127.0.0.1` — reachable from this machine only. The MCP server can act on your ServiceNow instance using the credentials saved on this machine, so it stays on loopback unless you deliberately open it up (see [Custom hostname](#custom-hostname)).

### Connecting to the MCP server

**VS Code / Claude Code** — native HTTP transport:

```json
{ "type": "http", "url": "http://localhost:3006/mcp" }
```

**Claude Desktop** (`claude_desktop_config.json`) — Claude Desktop does not support `type: http` natively. Use `mcp-remote` as a stdio→HTTP bridge.

> **Install `mcp-remote` globally first — don't use `npx mcp-remote` in your config.** `npx` re-resolves and re-downloads the package on every launch. On a slow or unhealthy npm cache (common on locked-down corporate Windows machines) this cold start can take longer than Claude Desktop's connection timeout, and the server never gets a chance to respond — Claude Desktop just shows the MCP server as failed to connect, with no useful error.
>
> ```bash
> npm install -g mcp-remote
> ```
>
> Then point `command` at the installed binary instead of `npx`: Claude Desktop is a GUI app — it launches with a minimal `PATH` and does not inherit your shell environment. If `which mcp-remote` returns a path under nvm, Homebrew, fnm or Volta, the bare name won't resolve and the server fails with `Server disconnected` / `spawn mcp-remote ENOENT`.
>
> * macOS/Linux: run `which mcp-remote` — use the bare name only if it's under `/usr/bin` or `/usr/local/bin`, otherwise use the absolute path it prints.
> * Windows: `%APPDATA%\npm\mcp-remote.cmd`
>
> If you still see connection issues after switching, also clear a possibly-corrupted npx cache: `npm cache clean --force`, and on Windows remove `%LOCALAPPDATA%\npm-cache\_npx`.

**Basic auth:**

```json
{
  "mcpServers": {
    "skyforge-nexus": {
      "command": "mcp-remote",
      "args": [
        "http://localhost:3006/mcp",
        "--header", "X-SN-Instance:<your-instance>.service-now.com",
        "--header", "X-SN-Username:<username>",
        "--header", "X-SN-Password:<password>"
      ]
    }
  }
}
```

**OAuth 2.0:**

```json
{
  "mcpServers": {
    "skyforge-nexus": {
      "command": "mcp-remote",
      "args": [
        "http://localhost:3006/mcp",
        "--header", "X-SN-Instance:<your-instance>.service-now.com",
        "--header", "X-SN-Client-Id:<client-id>",
        "--header", "X-SN-Client-Secret:<client-secret>"
      ]
    }
  }
}
```

**Using an instance already connected in SkyForge (recommended):**

Name the instance and let SkyForge supply the credentials — no password in the config file:

```json
{
  "mcpServers": {
    "skyforge-nexus": {
      "command": "mcp-remote",
      "args": [
        "http://localhost:3006/mcp",
        "--header", "X-SN-Instance:<your-instance>.service-now.com"
      ]
    }
  }
}
```

Works with any auth type the instance was connected with. `mcp-remote` writes `--header` values verbatim to its own log file, so passing a password there puts it in plaintext on disk — naming the instance avoids that.

#### Header reference

| Header                                  | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-SN-Instance`                         | Which instance. Accepts `dev12345`, `dev12345.service-now.com`, or the full URL. Required when instances were added through the Hub — SkyForge will not guess between them. Omit it only on an older single-instance setup connected with `skyforge auth login`. Use your instance's actual domain — some regional or government deployments aren't on `.service-now.com` at all (e.g. `<instance>.servicenowcloud.com.<country>`); check the URL bar on the live instance rather than assuming the generic suffix. |
| `X-SN-Username` + `X-SN-Password`       | Supply Basic credentials per request instead of using a connected instance.                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `X-SN-Client-Id` + `X-SN-Client-Secret` | Supply OAuth credentials per request.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `X-SkyForge-Auth-Source: stored`        | Required to use an instance connected with **SSO** (browser session). Not needed for Basic or OAuth.                                                                                                                                                                                                                                                                                                                                                                                                                |

An SSO connection replays a live browser session for a real, usually privileged, account with no password, so it takes an explicit opt-in rather than being used by default. SSO sessions expire; when one does, reconnect the instance in the SkyForge UI with a fresh **Copy as cURL** paste (labeled **Copy as cURL (bash)** in current Chrome and Edge — see [Browser Session / SSO](/docs/connect/servicenow-connection.md#browser-session-sso)) — it takes effect immediately, with no client restart.

If the named instance isn't connected, the request is refused rather than quietly falling back to a different instance. Check the spelling against the instances shown in the SkyForge UI.

### Custom ports via CLI flags

```bash
skyforge --port 8080                    # custom main server port
skyforge --mcp-port 9000                # custom HTTP MCP port
skyforge --port 8080 --mcp-port 9000    # both at once

skyforge serve --port 8080 --mcp-port 9000
```

### Custom ports via environment variables

```bash
# macOS / Linux
OPENCODE_SERVER_PORT=8080 SN_MCP_HTTP_PORT=9000 skyforge
```

```powershell
# Windows PowerShell
$env:OPENCODE_SERVER_PORT="8080"; $env:SN_MCP_HTTP_PORT="9000"; skyforge
```

```
:: Windows Command Prompt
set OPENCODE_SERVER_PORT=8080
set SN_MCP_HTTP_PORT=9000
skyforge
```

{% hint style="info" %}
The `VAR=value command` form is shell syntax, not something SkyForge parses, and it only works on macOS and Linux. On Windows it fails with `'SN_MCP_HTTP_PORT' is not recognized as an internal or external command` — use one of the Windows forms above, or pass the equivalent CLI flag, which behaves the same everywhere.
{% endhint %}

### Custom hostname

Both servers bind `127.0.0.1` by default. Each is opened up separately:

```bash
skyforge --hostname 0.0.0.0       # web UI on all interfaces
skyforge --mcp-hostname 0.0.0.0   # MCP server on all interfaces
```

`--mcp-hostname` is deliberately **not** inherited from `--hostname`, and `--mdns` (which flips the web UI to `0.0.0.0`) does not affect it either. Opening the web UI to your network and opening the MCP endpoint to your network are separate decisions.

#### Exposing the MCP server

Three ways to set it. They do the same thing — pick whichever suits how you launch SkyForge:

| Method               | How                                                                                 | Best for                                              |
| -------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------- |
| CLI flag             | `skyforge --mcp-hostname 0.0.0.0`                                                   | One-off runs, testing — same syntax on every platform |
| Environment variable | `SN_MCP_HTTP_HOST` (see below for Windows)                                          | Docker, systemd, CI, shell profiles                   |
| Config file          | `{ "server": { "mcpHostname": "0.0.0.0" } }` in `~/.config/skyforge/skyforge.jsonc` | Permanent setup on a dev box                          |

Setting the environment variable:

```bash
# macOS / Linux
SN_MCP_HTTP_HOST=0.0.0.0 skyforge
```

```powershell
# Windows PowerShell
$env:SN_MCP_HTTP_HOST="0.0.0.0"; skyforge
```

```
:: Windows Command Prompt
set SN_MCP_HTTP_HOST=0.0.0.0
skyforge
```

On Windows the CLI flag is usually simpler for a one-off — `skyforge --mcp-hostname 0.0.0.0` works the same in PowerShell, Command Prompt and a Unix shell.

Precedence when more than one is set: **flag → environment variable → config file → `127.0.0.1`**.

`skyforge mcp serve` (the standalone MCP server, no web UI) takes `--hostname` for the same purpose:

```bash
skyforge mcp serve --hostname 0.0.0.0
```

Confirm which one is in effect from the startup banner:

```
  Bound to:      127.0.0.1 (this machine only)
```

Anything other than `127.0.0.1` prints a warning underneath it. To check at the socket level:

```bash
lsof -nP -i:3006 | grep LISTEN      # macOS / Linux
netstat -ano | findstr :3006        # Windows
```

`127.0.0.1:3006` is loopback-only; `*:3006` or `0.0.0.0:3006` means every interface.

{% hint style="danger" %}
**The MCP endpoint can use the ServiceNow credentials saved on the machine running SkyForge, with no per-request password.** Binding it to `0.0.0.0` means anyone who can reach port 3006 — anyone on the same office Wi-Fi, VPN, or coffee-shop network — can read from and write to your instance as you.

Only do this on a network you trust, and only when the MCP client genuinely runs on a different host: a remote dev container, Docker, or some WSL2 setups. If SkyForge and your client are on the same machine — the normal case, including Claude Desktop with `mcp-remote` — leave it alone.
{% endhint %}

#### Requests from a browser are rejected

The MCP server refuses any request carrying an `Origin` header that isn't `localhost` or `127.0.0.1`, answering `403 Cross-origin requests are not allowed`. This stops a web page you happen to have open from driving your ServiceNow instance through `http://localhost:3006` — a request a loopback bind cannot block, because it genuinely comes from your own machine.

MCP clients (`mcp-remote`, Claude Code, VS Code) send no `Origin` header, so this never affects normal use. If you are writing a browser-based MCP client, serve it from a `localhost` origin.

> When running on a custom MCP port, update your client config accordingly:
>
> ```json
> // VS Code / Claude Code
> { "type": "http", "url": "http://localhost:9000/mcp" }
>
> // Claude Desktop — update the mcp-remote URL arg
> "args": ["http://localhost:9000/mcp", ...]
> ```

***

## Logs

| Log                 | macOS / Linux                         | Windows                                           |
| ------------------- | ------------------------------------- | ------------------------------------------------- |
| Session (dev build) | `~/.local/share/skyforge/log/dev.log` | `%USERPROFILE%\.local\share\skyforge\log\dev.log` |
| Session (installed) | `~/.local/share/skyforge/log/*.log`   | `%USERPROFILE%\.local\share\skyforge\log\`        |
| MCP calls           | `~/.skyforge/skyforge-mcp.log`        | `%USERPROFILE%\.skyforge\skyforge-mcp.log`        |
| MCP metrics         | `~/.skyforge/skyforge-metrics.log`    | `%USERPROFILE%\.skyforge\skyforge-metrics.log`    |

```bash
# Tail active log (dev build)
tail -f ~/.local/share/skyforge/log/dev.log

# Tail latest session log (installed binary)
ls -t ~/.local/share/skyforge/log/*.log | head -1 | xargs tail -f

# Watch MCP tool calls
tail -f ~/.skyforge/skyforge-mcp.log

# Full debug output
skyforge --log-level DEBUG --print-logs
```

***

## Keyboard Shortcuts (TUI)

SkyForge uses a **leader key** pattern — press and **release** `Ctrl+X` first, then press the second key.

| Key               | Action                             |
| ----------------- | ---------------------------------- |
| `Ctrl+X` then `A` | Open agent picker                  |
| `Shift+Tab`       | Cycle to next agent                |
| `Ctrl+Shift+Tab`  | Cycle to previous agent            |
| `Escape`          | Interrupt / stop current operation |
| `Ctrl+X` then `↑` | Go to parent session               |
| `Ctrl+X` then `→` | Next child session                 |
| `Ctrl+X` then `←` | Previous child session             |
| `Ctrl+P`          | Command palette                    |
| `Ctrl+Shift+A`    | Toggle auto-accept permissions     |
| `Ctrl+C`          | Exit SkyForge                      |

### Slash commands (TUI)

Type `/` in the prompt, or open the command palette with `Ctrl+P`.

| Command        | Action                           |
| -------------- | -------------------------------- |
| `/models`      | Switch model                     |
| `/connect`     | Add an AI provider               |
| `/agents`      | Switch agent                     |
| `/skills`      | Browse available skills          |
| `/sessions`    | Switch session                   |
| `/new`         | Start a new session              |
| `/status`      | Connection and instance status   |
| `/auth`        | Manage ServiceNow authentication |
| `/deployments` | Deployment history               |
| `/mcps`        | Connected MCP servers            |
| `/webtools`    | Toggle web tools                 |
| `/themes`      | Change theme                     |
| `/telemetry`   | Telemetry settings               |
| `/auto-update` | Toggle automatic updates         |
| `/update`      | Update SkyForge                  |
| `/help`        | Command reference                |
| `/exit`        | Quit                             |

***

## Agents

| Agent       | Trigger     | Description                                                 |
| ----------- | ----------- | ----------------------------------------------------------- |
| **Build**   | Default     | Full tool access — creates and deploys ServiceNow artifacts |
| **Plan**    | `Shift+Tab` | Read-only — analysis and exploration                        |
| **Review**  | `Shift+Tab` | Code review — writes report to `.skyforge/reviews/`         |
| **General** | `@general`  | Multi-step subagent for complex parallel tasks              |

Switch between Build / Plan / Review with `Shift+Tab`. Invoke General with `@general`.

Custom agents can be defined in `skyforge.jsonc` — see [Configuration → Custom Agents](/docs/reference/configuration.md#custom-agents).

***

## Need help?

[Submit an issue →](https://github.com/tryskyforge/skyforgeissues)
