---
name: "maison-agents"
description: "Configure per-hotel AI agents that evaluate every guest turn and take actions (send emails, fire webhooks, reply in chat, etc.) when their match criteria are met. Use to create, read, update, enable, disable and dry-test agents, and to browse execution history. Tools: create_agent, delete_agent, disable_agent, enable_agent, get_agent, get_agent_execution_history, get_guest_agent_settings, list_agent_execution_history, list_agent_sessions, list_agent_templates, list_agent_tools, list_agents, test_agent, update_agent, update_guest_agent_settings."
license: "Proprietary. Use with a Maison API key under the Maison terms of service."
metadata:
  author: "maison-labs"
  version: "1.0.0"
  category: "agents"
  api-base: "https://maison-labs.com"
  openapi: "https://maison-labs.com/api/v1/openapi.json"
  docs: "https://docs.maison-labs.com/skills/maison-agents/"
---

# Maison — Agents

Configure per-hotel AI agents that evaluate every guest turn and take actions (send emails, fire webhooks, reply in chat, etc.) when their match criteria are met. Use to create, read, update, enable, disable and dry-test agents, and to browse execution history.

Part of the Maison public API. Read the `maison-public-api` skill first for authentication, discovery and transport details (`https://docs.maison-labs.com/skills/maison-public-api/SKILL.md`).

## When to use

- Set up a sales-lead capture agent that emails staff when a guest expresses purchase intent.
- Configure a custom trigger that fires a webhook whenever a guest asks about a specific topic.
- Find sessions for a particular agent and date range, compare exact outcomes, and explain what caused a response.
- Dry-run an agent against a transcript before enabling it in production.
- Choose which integration tools an agent may call — `list_agent_tools`, then `resources.tools` on `create_agent` / `update_agent`.
- Start an agent from an external system's events — `list_webhooks` (webhooks skill) for the id, then `scope.webhookIds` on `create_agent` / `update_agent`.

## Before you start

1. Send `x-api-key: <key>` on every call; the key only reaches `/api/v1`.
2. `GET /api/v1/tools` (or MCP `tools/list`) returns the tools THIS key may run — if a tool below is missing there, you lack a grant; do not retry it.
3. Client-scoped tools take `clientId` (a hotel id). `whoami` lists the ids you can act on.

## Tools

| Tool | What it does | REST | Needs |
| --- | --- | --- | --- |
| `create_agent` | Create a ledger agent for a hotel. | `POST /api/v1/client/{clientId}/agent` | agents WRITE (client); plan: `agents` |
| `delete_agent` | Soft-delete a ledger agent. | `DELETE /api/v1/client/{clientId}/agent/{agentId}` | agents WRITE (client); plan: `agents` |
| `disable_agent` | Disable a ledger agent so it no longer evaluates live turns. | `POST /api/v1/client/{clientId}/agent/{agentId}/disable` | agents WRITE (client); plan: `agents` |
| `enable_agent` | Enable a ledger agent so it evaluates live turns. | `POST /api/v1/client/{clientId}/agent/{agentId}/enable` | agents WRITE (client); plan: `agents` |
| `get_agent` | Fetch one ledger agent by id, with `attention` — true when it had a failed or errored run in the last 24 hours (the console rail's flag) — and the attention details. | `GET /api/v1/client/{clientId}/agent/{agentId}` | agents READ (client); plan: `agents`; read-only |
| `get_agent_execution_history` | Fetch the durable source-message, trigger and action evidence for one execution, including output message references. | `GET /api/v1/client/{clientId}/agents/history/{executionId}` | agents READ (client); plan: `agents`; read-only |
| `get_guest_agent_settings` | Read resource permissions and current settings version for the built-in, always-on Guest agent. | `GET /api/v1/client/{clientId}/agent/guest/settings` | agents READ (client); plan: `agents`; read-only |
| `list_agent_execution_history` | List indexed action-history metadata: source-message identity, agent configuration version, status, confidence, threshold and timing. | `GET /api/v1/client/{clientId}/agents/history` | agents READ (client); plan: `agents`; read-only |
| `list_agent_sessions` | Find the sessions where an agent was triggered in a date range, with exact matched, delivered, failed and pending counts across the full result set, not just this page. | `GET /api/v1/client/{clientId}/agents/sessions` | agents READ (client); plan: `agents`; read-only |
| `list_agent_templates` | List predefined agent templates with suggested criteria, actions, and outputs. | `GET /api/v1/agenttemplates` | agents READ (global); read-only |
| `list_agent_tools` | List the hotel's integration tools an agent may be allowed to call — the ids `create_agent` / `update_agent` accept in `resources.tools` — with each tool's provider, description and whether it only reads. | `GET /api/v1/client/{clientId}/agents/tools` | agents READ (client); plan: `agents`; read-only |
| `list_agents` | List a hotel's configurable specialists, each with its live `counter` (matches and outcomes; null before its first run), plus `guest` — the built-in, always-on Guest agent's resources and settings version — and `templates`, the catalogue `create_agent` starts from. | `GET /api/v1/client/{clientId}/agents` | agents READ (client); plan: `agents`; read-only |
| `test_agent` | Dry-run a ledger agent against a transcript. | `POST /api/v1/client/{clientId}/agent/{agentId}/test` | agents EXECUTE (client); plan: `agents` |
| `update_agent` | Partially update a ledger agent; the live runtime picks it up at once and the change is recorded in the client activity feed. | `PUT /api/v1/client/{clientId}/agent/{agentId}` | agents WRITE (client); plan: `agents` |
| `update_guest_agent_settings` | Update resource permissions for the built-in Guest agent using its current settings version (0 for untouched defaults). | `PUT /api/v1/client/{clientId}/agent/guest/settings` | agents WRITE (client); plan: `agents` |

Full input fields for every tool: [references/tools.md](references/tools.md).

## Recommended workflows

### Create and enable an agent

1. Call `list_agent_templates` to see predefined templates (e.g. `sales_lead`).
2. Call `create_agent` with the chosen `templateId`, a `name`, `criteria`, `action`, `outputs` and optional `channels`/`threshold`/`repeat`.
3. Call `enable_agent` to start evaluating live turns.
4. Call `list_agent_sessions` with clientId, agentId, from and to to monitor results.

### Investigate agent sessions and decisions

1. Call `list_agent_sessions` with clientId, agentId, from and to: the sessions where the agent triggered. The date window includes from and excludes to; analytics cover the full window rather than just the current page.
2. Follow nextOffset until null to retrieve every matching session. Keep the same date and agent filters between pages.
3. Call `list_agent_execution_history` with the sessionId to inspect its triggered runs. Set executionsOnly=false only when diagnosing why an agent did not trigger (nonmatches, below-threshold and dedupe decisions).
4. Use `get_agent_execution_history` for one execution's configuration version, trigger prompt, confidence/reason, extracted fields and output references. Distinguish the model's explanation from verified delivery evidence.

### Dry-run before enabling

1. Build a representative transcript array (role + message + optional datetime).
2. Call `test_agent` — returns verdicts without writing any execution row or firing any output.
3. Adjust `criteria` and `threshold` based on the confidence scores, then enable.

## Tips

- `channels: ['*']` means the agent applies to every channel; narrow it to `['web', 'whatsapp']` to limit scope.
- `threshold` (0–1, default 0.70) sets the minimum confidence for a match; raise it to reduce false positives.
- `repeat.mode = 'once_per_session'` prevents duplicate firings within a single conversation; use `cooldown` for cross-session rate limiting.
- SQL history tools accept at most 366 days and 100 rows per page. Configured agent ids are UUIDs — never pass 'guest' as agentId. History remains queryable after an agent is deleted.
- The Guest agent is always on and is not written to the execution ledger. Use list_agents' builtInAgents field for its identity, and get_guest_agent_settings/update_guest_agent_settings for its resources.
- The router excludes agents that do not match the channel or scope before evaluation. Excluded agents are never written to execution history.
- `list_agents` returns each agent's `counter`, the Guest agent's settings under `guest`, and the template catalogue; `get_agent` adds `attention` (a failed or errored run in the last 24 h).
- Every create, update, enable and disable is recorded in the hotel's activity feed (`agent_created`, …), exactly as a console change.

## Pitfalls

- An agent is evaluated only when it is `enabled`; creating an agent does not start evaluation.
- The `version` field is required for `update_agent` — always re-read before updating to avoid a 409 conflict.
- `outputs` with `kind: 'email'` require at least one recipient; `kind: 'sms'` is accepted but always returns `no_transport` until a provider is wired.
- A matched/pending action is not a successful delivery. Report success only from an acted record and successful output results; partial, failed and evaluation errors must stay distinct.
- `agentId` in history tools must be a configured UUID. Passing 'guest' returns an input error.
- Webhook outputs must be `https://` URLs; `http://` is refused with 400.

## Calling conventions

Same tool, three transports — pick whichever your runtime already speaks. Always send `x-api-key`.

```bash
# REST
curl -X POST "https://maison-labs.com/api/v1/client/<clientId>/agent" -H "x-api-key: $MAISON_API_KEY" -H "content-type: application/json" -d '{ "templateId": …, "name": …, "channels": …, "criteria": …, "action": …, "outputs": … }'
```

```json
// MCP (https://maison-labs.com/mcp, Streamable HTTP): tools/call
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "create_agent", "arguments": { "templateId": …, "name": …, "channels": …, "criteria": …, "action": …, "outputs": … } } }
```

```json
// A2A (https://maison-labs.com/a2a): tasks/send with a data part
{ "jsonrpc": "2.0", "id": 1, "method": "tasks/send", "params": { "message": { "role": "user", "parts": [{ "type": "data", "data": { "tool": "create_agent", "input": { "templateId": …, "name": …, "channels": …, "criteria": …, "action": …, "outputs": … } } }] } } }
```

Errors are the same everywhere: `401` no/invalid key; `403 forbidden` with `details.missing` (the grants you lack — fall back to the composite's parts or stop); `403 not_entitled` (the hotel's plan lacks the feature); `404`, `409`, `413 too_large`, `503`. Inputs that fail validation return `400 invalid_input` with the Zod issues — fix and retry once.
