Metadata-Version: 2.4
Name: merge-workforce
Version: 0.2.0
Summary: Merge for Workforce CLI (mfw) — models, tool-calling, and admin provisioning from the terminal.
Author-email: Merge <support@merge.dev>
License-Expression: MIT
Project-URL: Homepage, https://merge.dev
Project-URL: Repository, https://github.com/merge-api/merge-workforce-cli
Keywords: merge,workforce,cli,gateway,mcp,llm
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer==0.12.5
Requires-Dist: click==8.1.8
Requires-Dist: httpx==0.27.2
Requires-Dist: prompt_toolkit==3.0.53
Requires-Dist: rich==15.0.0
Dynamic: license-file

# Merge for Workforce CLI (`mfw`)

A command-line tool for Merge for Workforce employees: chat with your provisioned
models and tools from the terminal, or point Claude Code, Codex and other AI tools
at them.

## Install

```bash
pipx install merge-workforce   # recommended (isolated env, puts `mfw` on PATH)
pip install merge-workforce    # alternative
```

[`pipx`][pipx] keeps the tool in its own environment and avoids the
"externally-managed-environment" error a plain `pip install` hits on modern
Python. One-time setup: `brew install pipx && pipx ensurepath` (macOS) or
`python3 -m pip install --user pipx && pipx ensurepath` (Linux). Update later
with `pipx upgrade merge-workforce`. Requires Python 3.10+.

> To install an unreleased/dev build straight from the repo instead:
> `pipx install git+ssh://git@github.com/merge-api/merge-workforce-cli.git`.

## Quickstart

```bash
mfw
```

That's it. The first run opens your browser to sign in, provisions this device's
Gateway credential, and drops you into a chat. Every message goes to a model
through the Gateway (your routing policy picks it unless you choose one with
`/model`), and when the model needs one of your tools it calls it through Agent
Handler, all in one conversation.

Inside the chat: `/help` lists commands, `/model` shows or switches the model
(Tab completes ids, `/model auto` returns to your routing policy), `/tools` shows
what the model can call, `/new` starts over, `/exit` quits. The Merge Manta lives
in the bottom-right corner: `/pet` makes it flap and blush, `/pet color <name|#hex>`
recolors it. `/color <name|#hex>` recolors the frame around the input and
`/rename <name>` puts a name on it; both colors are remembered. End a line with `\`
for a new line; Ctrl-C cancels a reply.

For a one-off answer, pass the prompt (or pipe it in):

```bash
mfw chat "summarize my open Linear issues"
echo "draft a standup update" | mfw chat
```

To sign in to a non-production backend, set `MFW_GATEWAY_URL` (or run
`mfw login --gateway-url <url>` once); later commands reuse it.

> **You must be a provisioned employee.** Setup mints your key only once your
> admin has activated Merge for Workforce for your group. If it returns "your
> admin has not finished setting up Merge Gateway for your group yet", that
> setup isn't complete; it's not a CLI error.

## Commands

Run `mfw --help`, or `mfw <command> --help` for details on any one.

| Command | What it does |
|---|---|
| `mfw` | Open a chat with your models and tools (signs you in and sets up first if needed). |
| `mfw chat ["…"] [-m <id>]` | The same chat; with a prompt or piped stdin, answer once and exit. |
| `mfw login` | Browser IdP login; stores a short-lived access token. |
| `mfw setup` | Provision this device's Gateway credential (per-device, revocable). |
| `mfw models` | List the models served for you. The id is what you pass as `--model`. |
| `mfw mcp [--connectors a,b] [--write .mcp.json]` | Emit an MCP config so an external client (Claude Code, Cursor) can use your tools. |
| `mfw env [--no-trace]` | Print `export` lines that route an AI tool through the Gateway (`eval "$(mfw env)"`). |
| `mfw run [--no-trace] -- <cmd> …` | Run a command with the Gateway credential injected as env (OpenAI- and Anthropic-compatible). |
| `mfw creds [--export]` | Show (or `export`) the provisioned Gateway credential. |
| `mfw whoami` / `mfw logout` | Show login state / clear the stored token. |
| `mfw admin <cmd>` | Workforce-admin operations (requires the `manage_workforce` role). See [Admin operations](#admin-operations-mfw-admin). |

The Gateway routes and bills every call and **enforces your allowlist**, so a
model or tool you aren't provisioned for comes back as a request error, never a
silent fallback.

## Admin operations (`mfw admin`)

For workforce admins — these provision and manage the org from the terminal.
They **require the `manage_workforce` role** and run against your `mfw login`
token, so **no `mfw setup` is needed** (admin commands don't use the Gateway
credential). Without the role they return a permission error.

```bash
mfw admin groups                                    # list the org's groups (id + name)
mfw admin employees                                 # list employees (id, name, origin id)

# add an employee to a group, then remove one (removal revokes their Gateway keys)
mfw admin add-employee --group <group-id> --name "Jane Doe" --origin-id "jane@corp.com"
mfw admin remove-employee <employee-id>

# a group's model allowlist — a full replace (repeat -m), or clear it
mfw admin set-models <group-id> -m anthropic/claude-haiku-4-5-20251001 -m amazon/nova-micro
mfw admin set-models <group-id> --unrestricted      # allow every model
```

Run `mfw admin --help`, or `mfw admin <command> --help`, for details on any one.

## Usage with AI agents

Two ways to give an AI agent your provisioned models and tools, both governed by
your org:

- **`mfw` / `mfw chat`** is the built-in agent: it drives a model through the
  Gateway and calls your provisioned tools over MCP, no other client needed. A
  large tool set is searched as needed (`search_tools`) instead of sent whole.
  Every request in a conversation carries one session id (`X-Merge-Thread-Id`,
  logged by the Gateway as `thread_id`; also sent to Agent Handler as
  `X-Chat-Id`) and every prompt one `X-Merge-Turn-Id`, so the Gateway request
  log and the Agent Handler tool call log join on `turn_id`.
- **`mfw mcp`** hands your tools to an external MCP client (Claude Code, Cursor,
  any SDK agent). Write the config where the client reads it:

  ```bash
  mfw mcp --write .mcp.json     # Claude Code picks this up from the project root
  ```

  The config points the client at the backend's MCP endpoint with a short-lived
  token, so the agent calls tools **as you**, exactly as the console governs them.
  Re-run when the token lapses. `--connectors notion,github` limits the tools to
  those connectors; without it every tool you are provisioned is exposed, which
  can run to thousands. `mfw env` / `mfw run` also set `ENABLE_TOOL_SEARCH=true`
  so Claude Code loads MCP tools on demand instead of all at once (Claude Code
  turns that off by itself under a custom base URL).

- **`mfw env`** and **`mfw run`** point an AI tool at the Gateway. Both set the
  credential under its Merge, OpenAI-SDK (`OPENAI_API_KEY` / `OPENAI_BASE_URL`) and
  Anthropic-SDK (`ANTHROPIC_BASE_URL` / `ANTHROPIC_AUTH_TOKEN`) spellings, so
  Claude Code, Codex, or any SDK tool routes through the Gateway unchanged:

  ```bash
  eval "$(mfw env)" && claude        # this shell
  mfw run -- claude                  # one process
  ```

  By default both also turn on Claude Code's trace propagation
  (`CLAUDE_CODE_ENABLE_TELEMETRY`, `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA`,
  `CLAUDE_CODE_PROPAGATE_TRACEPARENT`, `OTEL_TRACES_EXPORTER=otlp` with the
  Gateway's `/v1/traces` as the OTLP endpoint). With those set, every model
  request and every MCP tool call in one prompt carries the same trace id, which
  Gateway logs as `client_trace_id` and Agent Handler logs on the tool call, so
  one prompt joins across both logs. Variables you already export win; pass
  `--no-trace` to skip that block entirely.

## How it works

- **Login** is OAuth 2.0 Authorization Code + PKCE with a loopback redirect
  (RFC 8252): the public client `merge-workforce-cli` (no secret on the laptop),
  your browser → `<gateway>/o/authorize/` → IdP login + consent → code returns to
  `http://localhost:{9410-9419}/callback` → exchanged at `<gateway>/o/token/`. The
  access token is stored in `~/.mfw/credentials.json` (`0600`).
- **Setup** exchanges that token for a per-device Gateway API key
  (`~/.mfw/gateway_credential.json`), the same per-device path the desktop client
  uses — independently revocable, with spend attributed to you.
- **Chat** uses the maintained `/v1/responses` surface, continuing the
  conversation by `previous_response_id` (or re-sending it, if your org has no
  response store), and connects your provisioned tools over the backend's
  OAuth-authed `/mcp/` endpoint, running the function-calling loop for you.

[pipx]: https://pipx.pypa.io/
