HappierDocs
Extending Happier

Happier MCP (external)

Run Happier as an external stdio MCP server so editors and agents can start/manage sessions and execute Happier actions.

MCP points in two directions, and this page covers one of them: something else driving Happier. If you are here to give your agent more tools, you want MCP servers instead.

Happier can run its own external MCP server so other MCP hosts — editors, agents, automations — can control Happier:

  • list and inspect sessions
  • start/stop/archive sessions
  • send messages to sessions
  • change a session’s title / permission mode / model
  • start execution runs (review / plan / delegate / voice agent)
  • execute any enabled Happier action (using the action spec as source of truth)

This is separate from MCP servers you manage inside Happier (Playwright, GitHub, etc). Those are documented under MCP servers.

The external MCP server uses the same action catalog as the app, CLI, voice, and session-agent surfaces. An action can be:

  • available on a surface,
  • discoverable through action_spec_search / action_spec_get,
  • exposed as its own direct named MCP tool.

Those are separate controls. External MCP and CLI surfaces keep direct named tools by default for compatibility, while in-session agents default to a smaller discovery-first direct tool set.

This direct/discoverable exposure model is for Happier action-backed tools. It does not make tools from MCP servers managed inside Happier discoverable-only; those custom tools remain controlled from Settings → MCP servers.

What you are granting

happier mcp serve runs with the same local privileges as the MCP host process, using your CLI's authenticated credentials. Configuring a host to spawn it is a privilege grant, not a connection setting.

That host can execute enabled Happier actions, request approvals — and execute immediately where the surface does not require one — and reach whatever sessions your account allows.

Treat an MCP host's server configuration the way you would treat a shell profile: anything that can edit it can act as you.

Run the server

The external MCP server is a stdio MCP server (meant to be spawned by an MCP host):

happier mcp serve

happier mcp start is accepted as a compatibility alias.

If you are wiring up a new host, keep serve as the canonical command name in your config so the intent is obvious to the next person who reads it.

Optionally set a default session context for tools that can infer “current session”:

happier mcp serve --session <session-id>

Configure an MCP host

Most MCP hosts let you configure a server by specifying a command and args.

Example shape:

{
  "mcpServers": {
    "happier": {
      "command": "happier",
      "args": ["mcp", "serve"]
    }
  }
}

Notes:

  • Ensure happier is on PATH, or use an absolute path to the binary — many hosts do not run in the same shell environment as your terminal. which happier gives you the path to paste.
  • Match the lane you actually use. A preview or dev install is a different command: happier (stable), hprev (preview), hdev (dev). Configuring the host with a lane you do not use is a common cause of confusing behaviour.
  • The MCP host must run on a machine that is already authenticated to Happier, or the server will fail with not_authenticated.
  • For security, happier mcp serve does not honor server-selection environment variables (like HAPPIER_SERVER_URL). To target a non-default server, pass the CLI server flags in args (see below) or switch the active server profile in the CLI home directory.

Target a specific server

If your MCP host supports it, include the normal CLI server selection flags in the configured args:

{
  "mcpServers": {
    "happier": {
      "command": "happier",
      "args": ["--server", "company", "mcp", "serve"]
    }
  }
}

Or use ad-hoc URLs:

{
  "mcpServers": {
    "happier": {
      "command": "happier",
      "args": ["--server-url", "https://api.company.example", "--webapp-url", "https://app.company.example", "mcp", "serve"]
    }
  }
}

Quick smoke test

If you want to verify the server is wired correctly, point any MCP host or inspector at:

  • command: happier
  • args: ["mcp", "serve"]

Then try the session-control tools first:

  • session_list
  • session_message_send
  • change_title
  • session_title_set
  • session_permission_mode_set

If those work, try the generic path next:

  • action_spec_search
  • action_spec_get
  • action_execute

That gives you a quick end-to-end check that the server, account auth, action catalog, and approval routing are all connected.

Tool call examples

The exact JSON shape depends on your MCP host, but tool calls generally pass an args object that matches the tool’s input schema.

If you’re unsure about a tool’s fields, use the discovery tools first:

  • action_spec_get (to see inputSchema, inputHints, and examples)
  • action_options_resolve (to resolve valid options for a field)

List sessions

Call session_list with no args:

{}

Send a message (and wait for idle)

Call session_message_send:

{
  "sessionId": "sess_123",
  "message": "ping",
  "wait": true,
  "timeoutSeconds": 60
}

Optional overrides (when supported by the backend):

  • permissionModeOverride
  • modelOverride (use null to clear an override when applicable)

Wait for a session to become idle (no message send)

Call session_wait_idle:

{
  "sessionId": "sess_123",
  "timeoutSeconds": 60
}

Rename a session

Rename the current/default session context:

Call change_title:

{
  "title": "Fix flaky tests"
}

Rename a specific session by id/prefix:

Call session_title_set:

{
  "sessionId": "sess_123",
  "title": "Fix flaky tests"
}

Change the permission mode for a session

Call session_permission_mode_set:

{
  "sessionId": "sess_123",
  "permissionMode": "read_only"
}

Start an execution run (plan/review/delegate/voice agent)

Call execution_run_start to start a structured Happier-managed run in a session. It requires an intent plus a backend target.

Example:

{
  "sessionId": "sess_123",
  "intent": "plan",
  "backendTarget": { "kind": "builtInAgent", "agentId": "claude" },
  "instructions": "Plan a safe refactor and list risks."
}

The backend target selects which provider/backend runs the execution run. It is not a capacity slot. If you choose multiple backend targets through an action that supports that shape, Happier starts one managed run per selected provider/backend.

What tools you get

The external MCP surface is a blend of:

  • Happier action tools (generated from the action spec catalog)
  • a few manual convenience tools (for common control-plane behaviors)

Common session control tool examples:

  • session_list
  • session_status_get
  • session_message_send
  • session_stop
  • session_archive / session_unarchive
  • change_title (rename the current/default session)
  • session_title_set
  • session_permission_mode_set
  • session_model_set
  • session_wait_idle

Action discovery tools:

  • action_spec_search
  • action_spec_get
  • action_options_resolve

Generic executor tool:

  • action_execute (execute any enabled action by actionId with structured input)

Execution run tool:

  • execution_run_start

The exact set depends on what your account has enabled, which surfaces are enabled, and whether the action is configured as a direct tool or discoverable-only for that surface. See “Approvals, enablement, and exposure”.

Session context and tool variants

Some tools operate on a specific session, and some operate on the current/default session.

Default session (--session) vs explicit sessionId

  • Many session control tools accept an explicit sessionId argument.
  • If a tool supports inferring the session and you do not pass sessionId, Happier uses:
    1. the --session <session-id> value passed at happier mcp serve startup (if any), otherwise
    2. a global “no session selected” context (some tools will fail with session_not_selected in that case).

For deterministic automations, prefer passing an explicit sessionId.

Session ids and prefixes

When a tool accepts sessionId, it generally accepts either:

  • a full session id, or
  • an unambiguous prefix.

If the prefix matches multiple sessions, the tool call fails and includes candidates. For saved MCP host configs (long-lived), prefer full ids.

Changing titles: change_title vs session_title_set

There are two common ways to rename a session:

  • change_title: a convenience tool that takes only { "title": "..." } and renames the current/default session context.
  • session_title_set: the action-backed tool for session.title.set that supports passing a sessionId when you want to rename a specific session.

Both routes go through the same action catalog and the same per-surface policy (enablement + approvals).

Generic action execution

The external MCP server also exposes a generic tool:

  • action_execute

Use it when:

  • you already know the exact actionId
  • you want to call an action that does not have a dedicated named tool
  • you want to manage approval artifacts programmatically

Shape:

{
  "actionId": "session.title.set",
  "input": {
    "sessionId": "sess_123",
    "title": "Fix flaky tests"
  }
}

Notes:

  • actionId is the canonical dotted id (example: session.title.set).
  • Tool names are typically snake_case (example: session_title_set) and map to the same underlying action.

This is also the path to advanced approval actions such as:

  • approval.request.create
  • approval.request.decide

Those approval actions are available through the action catalog, but they are not advertised as separate named MCP tools. Use action_execute when you need them.

Approvals, enablement, and exposure

Happier treats actions as a single catalog that can be enabled/disabled per “surface”, including:

  • session agents (in-session tools)
  • voice
  • CLI
  • external MCP

In the app, configure this under:

  • Settings → Actions

For each action + surface, you can:

  • enable/disable the action
  • optionally require approval (approval-gated execution)
  • choose direct tool exposure for eligible tool-backed surfaces

If a tool is approval-gated, the MCP tool call returns an approval_request_created payload (with an artifactId). This applies both to generic action_execute calls and to built-in aliases such as session_title_set, because they share the same action + surface policy. Use the app's Inbox to approve/deny and view the final result:

Programmatic approval decisions

If you want an MCP host to manage approvals directly, call action_execute with approval.request.decide.

Example:

{
  "actionId": "approval.request.decide",
  "input": {
    "artifactId": "2765bc88-69ea-4316-9085-290ce5b3a3b6",
    "decision": "approve"
  }
}

That executes the same approval object you can review in the app Inbox. The same generic approval model works regardless of whether the request came from the CLI, an external MCP host, a session agent, or another Happier surface.

Direct tool exposure

For eligible action-backed tools, Settings → Actions can set tool exposure per surface:

  • Use default follows Happier’s default for that action and surface.
  • Discoverable only keeps the action callable through action_execute, but removes the named direct tool from that surface.
  • Direct tool exposes the named tool when the action is otherwise enabled.

This is useful when you want a smaller direct tool list but still want the action available through discovery and generic execution.

Troubleshooting

not_authenticated

Authenticate the CLI first:

happier auth login

If you’re targeting a self-hosted server, ensure the MCP host launches Happier with the right server profile (or server URL flags). See CLI → Server profiles.

No daemon running / session create fails

Starting and managing local provider processes (creating sessions, sending messages, attaching, etc.) generally requires a running Happier daemon on that machine.

If a tool call fails with an error like No daemon running (or similar), run:

happier daemon start

For a smoother always-on setup (recommended), install it as a user service:

happier daemon install

A tool is missing

Tool visibility is driven by the action spec catalog and your account settings. Check:

  • Settings → Actions (surface enablement, approvals, and direct/discoverable exposure)
  • Settings → MCP servers (if you expected a custom MCP server tool, not a Happier action tool)

If an action is discoverable-only on the MCP surface, it will not appear as a named direct tool. Use action_spec_search, action_spec_get, and action_execute, or change the action’s MCP exposure setting to Direct tool.

On this page