Connect AI tools like Claude Desktop to the Advisor and your Steward business data.
The Model Context Protocol (MCP) lets AI applications connect to external data sources and tools. With the Steward MCP server, you can use Claude Desktop (or any MCP-compatible client) to talk to the Advisor and query your business data using natural language.
The server exposes two groups of tools over one endpoint: the Advisor tools
(advisor_*) — the Advisor's own findings, grounded Q&A, and one-tap capture, which
mirror the Advisor REST API 1:1 and are how the Companion connects — and the
domain-data tools for reading the underlying clients, calendar, invoices, and knowledge
base. Each tool declares the permission it needs; calls without it are refused.
1. Generate an API key in Settings → API Keys in the Steward dashboard.
2. Open Claude Desktop settings and add this to your MCP configuration:
{
"mcpServers": {
"steward": {
"url": "https://steward.cobenian.com/mcp",
"headers": {
"Authorization": "Bearer ovst_your_api_key_here"
}
}
}
}
3. Restart Claude Desktop. You'll see Steward tools available in your conversations.
The MCP server uses the same API keys as the REST API. Include your key as a Bearer token:
Authorization: Bearer ovst_your_key_here
API keys are scoped to your account. All tool calls return only your account's data.
An API key names an organization, not a person — so on a key that several
people share, nothing in Authorization says who is actually driving the call.
A product calling Steward on a signed-in person's behalf sends that person alongside the
key, once per request:
Authorization: Bearer ovst_your_key_here
X-Cobenian-Acting-User: Bearer <that person's Cobenian Accounts access token>
Per request, not per session: an Accounts access token lives about ten minutes and
an MCP session outlives it. The Bearer prefix is required — a bare subject
identifier is rejected rather than read as an identity. The token must be an end user's
(a service token is refused) and carry the cobenian-products audience.
When one is present, the call is authorized as that person against their role in Steward,
in addition to the key's own permissions — so a viewer can read the Advisor and
cannot rewrite the destination, exactly as in the web app. The caller must also have been
granted the matching capability scope on that person's behalf:
steward:tools:read for read-only tools, steward:tools:act for the
rest.
It is optional for a key you minted yourself, which is every key created from Settings, so
Claude Desktop, ChatGPT and IDE assistants need nothing here. Errors that name your own
token carry a machine-readable data.reason:
acting_user_required, acting_user_malformed (no
Bearer prefix, a service token, or the wrong audience — do not retry),
acting_user_invalid (expired or unverifiable — refresh once, then retry),
acting_user_unavailable (we could not reach Accounts — retry with backoff,
do not refresh), and acting_user_denied (the capability was not in
your token's ceiling — do not retry). Everything else takes the ordinary
Missing permission answer, deliberately, so a refusal never reveals what
exists.
Tool results are returned as JSON text inside the standard MCP content array. Tools that
return a list of items wrap them in an {items, meta} envelope so you can page through large
result sets — identical to the REST API's meta, just alongside items instead of
data:
{
"items": [...],
"meta": {
"total": 137,
"count": 20,
"limit": 20,
"offset": 0,
"has_more": true
}
}
Every list tool accepts the same two pagination arguments:
| Argument | Type | Description |
|---|---|---|
limit | integer | Page size. Default 20 (25 for get_invoices). Clamped to 1..100. |
offset | integer | Number of items to skip. Default 0. Clamped to >= 0. |
The meta fields mean: total = all matching items (ignoring limit/offset), count = items in this page, limit/offset = the effective values applied, and has_more = whether another page exists (offset + count < total). Page by increasing offset by limit until has_more is false.
Breaking change: list tools now return an {items, meta} object. They previously returned a bare JSON array — update any client that indexed the result directly to read items instead.
The Advisor's own tools. Every one — read and write — requires the
read:advisor permission (there is no separate write scope, by
design, so a Companion key keeps working). They read and write only the Advisor's
own data and never send anything to clients. These mirror the
Advisor REST API 1:1.
question (required)finding_id (required)name (required), value_cents, stage, expected_close (YYYY-MM-DD), notes, client_id (all optional)promise (required), subject_type, subject_id, deadline (YYYY-MM-DD), project_id (all optional)statement (required), horizon (optional)objectives (required array of {name, weight?, measure_key?, target?})facet (required), fact OR key+valueconfirmed (optional: true, false, all), archived (optional: false, true, all), limit (optional), offset (optional)client_id (required)limit (optional, default 20), offset (optional)status (optional), client_id (optional), limit (optional, default 25), offset (optional)query (required)client_id (optional), limit (optional), offset (optional)topic (required), content (required), tags (optional)entry_id (required), new_content (required)entry_id (required)Ask the Advisor a question (requires read:advisor):
curl -X POST https://steward.cobenian.com/mcp \
-H "Authorization: Bearer ovst_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "advisor_ask",
"arguments": {"question": "Which clients are going quiet?"}
}
}'
100 requests per minute per API key, shared with the REST API.