Metadata-Version: 2.4
Name: meta-council-mcp
Version: 0.12.0
Summary: MCP server for Meta Council — multi-expert AI decision intelligence
Author: Dave Liu
License: MIT
Project-URL: Homepage, https://meta-council.com
Project-URL: Repository, https://github.com/daliu/meta-council
Project-URL: Documentation, https://meta-council.com/static/docs.html
Keywords: mcp,ai,agents,decision-intelligence,meta-council
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: mcp<2,>=1.27
Requires-Dist: jsonschema>=4.20

# Meta Council MCP Server

Let any MCP-compatible AI agent convene expert panels on Meta Council.

## Hosted Streamable HTTP

The production MCP resource URL is `https://meta-council.com/mcp` (JSON-RPC 2.0
over stateless [MCP Streamable HTTP](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports)).
No local package or clone is required for the hosted transport:

```bash
# Claude Code
claude mcp add --transport http meta-council https://meta-council.com/mcp \
  --header "Authorization: Bearer mc_your_key_here"
```

Get an `mc_` key at meta-council.com → Settings → Developer API Keys. Only four
catalog tools are anonymous: `list_panels`, `list_agents`, `list_workflows`, and
`get_agent_detail`. Query-bearing tools such as `recommend_panel`, private
artifacts such as `get_visualization`, and every run, settings, clinical,
Legal, Accounting, Marketing, Consulting, ticketing, or outreach tool requires
a key with the relevant scope.

The repository contains the hardened transport described here. Do not treat
documentation or source state as proof that a particular release is deployed;
see [`docs/ENTERPRISE_READINESS.md`](../docs/ENTERPRISE_READINESS.md) for the
production verification gates and current compliance posture.

### Claude Desktop

The hosted endpoint currently authenticates with static scoped API keys; MCP
OAuth protected-resource discovery is not implemented yet. A Claude Desktop
custom connector that requires OAuth will therefore not complete authorization.
Until OAuth is shipped and verified, bridge the HTTP endpoint through
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote) in
`~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
    "mcpServers": {
        "meta-council": {
            "command": "npx",
            "args": ["-y", "mcp-remote", "https://meta-council.com/mcp",
                     "--header", "Authorization: Bearer ${MC_API_KEY}"],
            "env": {"MC_API_KEY": "mc_your_key_here"}
        }
    }
}
```

### Other MCP clients

Cursor, Windsurf, and anything else that speaks MCP over HTTP: URL
`https://meta-council.com/mcp`, header `Authorization: Bearer mc_your_key_here`.
Clients that only speak stdio can use the same `mcp-remote` bridge as above.
The hosted server is published in the official
[MCP Registry](https://registry.modelcontextprotocol.io/?q=com.meta-council%2Fdecision-intelligence)
as `com.meta-council/decision-intelligence` version `1.4.0`. Configure the URL
and scoped key explicitly because the Registry listing does not provision
credentials.

## stdio adapter: published package

For clients that prefer a local stdio server over the hosted HTTP endpoint, the
adapter is published on PyPI as
[`meta-council-mcp`](https://pypi.org/project/meta-council-mcp/).
`pip install meta-council-mcp` installs the 0.12.0 release with
98 tools, three resources, and three prompts, including Legal research,
configuration and legacy outreach operations, plus mirrors of the hosted
Accounting, Marketing, ticket-board, Consulting, feedback, and Sales CRM
surfaces. Accounting synchronization, ticket plan/batch, ticket field-parity,
and credential-backed validation finalization — source-only during the
previous stable 0.8.0 (93-tool) release — ship in this release. The admin-only
`list_feedback` stays hosted-only. The adapter calls the Meta Council REST API
at `META_COUNCIL_URL` (default
`https://meta-council.com`); it does not replace the Meta Council backend.

```bash
pip install meta-council-mcp
export META_COUNCIL_API_KEY="mc_your_key_here"   # meta-council.com > Settings > Developer API Keys
claude mcp add meta-council -- meta-council-mcp
```

`pip install meta-council-mcp` puts a `meta-council-mcp` console script (entry
point `meta_council_mcp.server:main`) on your PATH — no clone required. To run
from a source checkout instead (e.g. for development), point Python at
`mcp/server.py`, kept byte-identical to the packaged `meta_council_mcp/server.py`:

```bash
claude mcp add meta-council -- python /path/to/meta-council/mcp/server.py
```

> **Note:** install `meta-council-mcp`, not `mcp` — the latter is only the
> upstream MCP SDK, not Meta Council. The adapter still needs an `mc_` key in
> `META_COUNCIL_API_KEY`; set `META_COUNCIL_URL` only to target a non-default
> deployment.

Claude Desktop with the stdio server (after `pip install meta-council-mcp`):

```json
{
    "mcpServers": {
        "meta-council": {
            "command": "meta-council-mcp",
            "env": {
                "META_COUNCIL_API_KEY": "mc_your_key_here"
            }
        }
    }
}
```

If Claude Desktop can't find `meta-council-mcp` (GUI apps don't always inherit
your shell PATH), use the absolute path from `which meta-council-mcp` as the
`command`.

## Hosted transport details (raw JSON-RPC)

Any server-to-server client that can send an HTTP POST can talk to Meta Council
directly—no MCP client library is required. Browser clients additionally need
an explicitly allowed Origin and compatible CORS response handling:

```
POST https://meta-council.com/mcp
Content-Type: application/json
Accept: application/json
Authorization: Bearer mc_your_key_here      # see below
```

Standard MCP methods are supported: `initialize`, `tools/list`, `tools/call`,
`ping`. The server negotiates MCP `2025-11-25`, `2025-06-18`, or `2025-03-26`.
Send the negotiated version in `MCP-Protocol-Version` on requests after
initialization. The implementation is stateless: it returns one JSON response per
POST and does not issue an `MCP-Session-Id` or expose a standalone SSE stream.

Auth uses an `mc_` API key in `Authorization: Bearer ...` (preferred) or
`X-API-Key`. New keys have explicit scopes and an expiry (90 days by default,
configurable from 1–365 days); the raw key is shown only once. Create narrow
keys and rotate them before expiry.

Initialize:

```bash
curl -s https://meta-council.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
```

List the tools:

```bash
curl -s https://meta-council.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
```

Call an anonymous catalog tool:

```bash
curl -s https://meta-council.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"list_panels","arguments":{}}}'
```

Start a council (requires `councils:run`):

```bash
curl -s https://meta-council.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -H 'Authorization: Bearer mc_your_key_here' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call",
       "params":{"name":"run_council","arguments":{"query":"...","panel":"auto"}}}'
```

`run_council`, `run_workflow`, and `score_locus_case` return a session ID
immediately by default. Poll with `get_session` or `get_workflow_session`. A
caller may request `wait_seconds` from 0–90, but should still handle a running
response and poll; long proxy-held requests are not the default.

The 2.5.0 hosted source candidate defines a 94-tool surface spanning councils,
discovery,
workflows, LOCUS, citation-grounded Legal research, settings reads, governed
Sales/outreach operations, the private ticket board, feature feedback, and the
owner-private Accounting, Marketing, and Consulting workspaces. Accounting performs
deterministic analysis and stores encrypted audit runs; it never files, pays,
or sends records externally. Marketing covers brands, audiences,
campaigns, revision-safe content with immutable submitted snapshots, the planning calendar, draft
submission, and separately scoped review; it exposes no publish, send,
archive, or delete operation. Live outreach sends and destructive
campaign/deal deletes remain outside hosted MCP.
Consulting covers clients,
engagements, revision-safe proposals/SOWs, idempotent stable milestones, and
internal deliverables. It deliberately has no publish, share, send, or delete
tool. Approval requires both the exact version/hash returned by a read and a
credential different from the one that last edited that snapshot. Use separate
writer and reviewer keys even when both keys belong to the same account.
Source state is not proof that this surface is deployed; initialize and list
tools on the target endpoint, or consult the corresponding release evidence,
before describing it as production.

The current repository transport identifies itself as server version `2.5.0`.
That source identity and the 94-tool catalog are development facts, not proof
that a particular production deployment has been upgraded.

### Ticket traversal, field parity, and provenance

`ticket_list` is an opaque-cursor traversal rather than a fixed result window.
Each call returns at most 200 tickets and ends with a machine-readable
`Pagination` object containing `has_more` and `next_cursor`. Reuse
`next_cursor` with exactly the same filters. The cursor is bound to the owner
and filter set, and immutable `(created_at, id)` ordering makes a full-board
walk exact even when already-returned tickets are edited, reordered, or moved.
It is not a database snapshot: concurrent ticket creation/deletion, or
reparenting that changes membership in a recursive subtree, can change what
later pages contain.

Set `recursive=true` with an owned UUID `parent_id` to traverse every
descendant as one flat, cycle-safe result set; the anchor ticket itself is not
returned. Without `recursive`, `parent_id` retains its direct-child behavior,
and `parent_id="none"` selects root tickets. Session and workflow-session
filters are opaque metadata matches only and never grant access to the linked
resource.

The hosted and stdio `ticket_create`, `ticket_update`, and `ticket_get` surfaces
carry the same ticket metadata: hierarchy, session/workflow links, labels,
acceptance criteria, effort points, order index, and external references in
addition to the core title, description, state, priority, effort, action type,
and assignee fields. Updates use explicit clear flags for parent, session,
workflow-session, and effort-points values so transports that omit JSON nulls
can still clear them safely. External-reference writes replace only
caller-owned references. Provider synchronization, Accounting, plan, and batch
references are system-owned: generic MCP writes preserve them and reject
attempts to supply, change, or remove them. Accounting-managed workflow links
must be changed through the Accounting synchronization flow.

Ticket creator, comment author, and mutation-trail provenance is derived
server-side from the credential that actually performed the call and recorded
as `api_key:<UUID>`. The ticket tools do not accept caller-supplied
`creator_agent` or `author` fields. MCP security audit events separately retain
the acting key's id, name, and prefix without storing ticket content or tool
arguments.

### Evidence-backed ticket validation

Hosted and source-run stdio expose `ticket_validation_finalize` for one
immutable terminal result against an exact ticket-scenario revision. It
requires an API key carrying the opt-in `tickets:validate` scope; it is not
included in default or legacy compatibility grants. The equivalent REST route,
`POST /api/tickets/{ticket_id}/scenarios/{scenario_id}/validation-runs`,
accepts either a user JWT or that scoped API key. In every transport, the owner
and actor come only from the verified credential/session. Request bodies cannot
override either identity.

Choose a caller-stable visible-ASCII `idempotency_key` and retain it locally.
An exact retry made with the same API-key actor returns the original committed
run with `"replayed":true`; a newly rotated key is a different actor and
conflicts if it reuses the old retry key even when the remaining payload is
unchanged. Resolve outstanding retries before rotating the calling key.
Reusing the key for any other changed scenario, verdict, runner, environment,
revision, summary, or evidence content also conflicts. Success is not returned
until the database commit completes.

Evidence is bounded opaque JSON: at most 100 items, 64 KiB canonical JSON per
payload, and 1 MiB canonical evidence in total. Public adapters additionally
admit at most 10,000 JSON nodes per payload and 100,000 evidence JSON nodes
across the request. Locator-looking strings, including URLs and paths, are
stored as data and never fetched, resolved, or opened. The compact receipt
deliberately does not echo payloads; it returns each evidence item's sequence,
kind, and SHA-256 digest plus the run's evidence count and manifest hash. Raw
retry keys, keyed identity hashes, and request fingerprints are also omitted.

The REST request body is capped at 5 MiB before parsing. The positive
`TICKET_VALIDATION_ATTEMPTS_PER_MIN` setting (default 60) independently limits
REST source-IP ingress and the authenticated API-key/JWT actor. Hosted MCP
retains its normal transport IP/key admission and applies the same validation
actor ceiling. Durable owner-wide and per-scenario backstops retain at most
10,000 runs, 100,000 evidence items, and 268,435,456 canonical evidence-JSON
characters per owner, plus 1,000 runs per scenario. The character ceiling
bounds UTF-8 evidence storage to at most four times that count. Same-actor exact
replay remains available at those caps. The owner quota uses a transactionally
updated constant-time ledger, with a one-time startup backfill for pre-adapter
history.

The in-process model-facing built-in ticket tools intentionally omit this
mutation. Council run-context labels are not verified credential principals
and cannot establish the immutable actor. Direct local/offline finalization is
therefore unsupported; use authenticated REST, hosted MCP, or this source-run
stdio forwarder, which delegates to hosted MCP with the same scoped key.

External ticket list/get calls do not yet expose scenario discovery. Until
PLT-019 adds owner-scoped scenario read/export parity, a trusted planner or
operator must provision the exact scenario id, version, and hash out of band.
The placeholder coordinates below are illustrative rather than discoverable
validator inputs.

Hosted MCP example:

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "ticket_validation_finalize",
    "arguments": {
      "ticket_id": "11111111-1111-4111-8111-111111111111",
      "scenario_id": "22222222-2222-4222-8222-222222222222",
      "scenario_version": 3,
      "scenario_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "verdict": "passed",
      "runner": "ci",
      "environment": "staging",
      "source_revision": "git:0123456789abcdef",
      "evidence": [
        {"kind": "artifact", "payload": {"uri": "s3://bucket/report.json"}}
      ],
      "idempotency_key": "validation-run-2026-07-29-001"
    }
  }
}
```

### API-key scopes used by hosted MCP

| Scope | Hosted operations |
|---|---|
| `catalog:read` | `recommend_panel` |
| `councils:read` | `get_session`, `get_visualization` |
| `councils:run` | `run_council` |
| `workflows:read` | `get_workflow_session` |
| `workflows:run` | `run_workflow` |
| `workflows:approve` | `advance_workflow` |
| `clinical:run` | LOCUS tools |
| `legal:run` | `ask_legal` |
| `accounting:read` | `list_accounting_runs`, `get_accounting_run`; also required by both Accounting-to-ticket tools |
| `accounting:write` | `create_accounting_run`, `delete_accounting_run` |
| `settings:read` | `get_settings` |
| `outreach:read` | Hosted outreach reporting tools |
| `outreach:agent_write` | Governed campaign, lead, pitch, deal, activity, and draft writes (no live send or delete) |
| `tickets:read` | `ticket_list`, `ticket_get`; combines with `accounting:read` for `preview_accounting_ticket_sync` |
| `tickets:write` | Ticket create/update/comment/claim plus provider-free plan/batch preview/commit; prompt-only `ticket_plan` preview also requires `councils:run`. Combines with `accounting:read` for `sync_accounting_tickets` and also satisfies ticket reads |
| `tickets:validate` | `ticket_validation_finalize`; separate opt-in authority that does not imply ticket read or write |
| `feedback:write` | `submit_feedback` |
| `feedback:admin` | Admin-only feedback listing and triage |
| `marketing:read` | List/get owned brands, audiences, campaigns, assets, and calendar |
| `marketing:agent_write` | Create/update owned Marketing context and drafts; revise/submit content (also satisfies reads) |
| `marketing:approve` | Approve/reject an exact submitted revision (also satisfies reads; cannot draft or publish) |
| `consulting:read` | List/get the caller's private consulting workspace |
| `consulting:write` | Create/update consulting drafts and submit deliverables for review; also satisfies consulting reads |
| `consulting:approve` | Approve and lock an exact SOW/proposal revision or submitted deliverable using caller-supplied version/hash evidence; does not imply write |

`list_panels`, `list_agents`, `list_workflows`, and `get_agent_detail` are
anonymous catalog reads. Legacy keys created before scopes were introduced must
be rotated; they retain compatibility access until revoked.

## stdio package (0.12.0): 98 tools

The tables below describe the 98-tool stdio surface that `pip install
meta-council-mcp` (0.12.0) provides. It includes Legal
research, local configuration, and legacy outreach operations plus mirrors of
the hosted Accounting, Marketing, Consulting, ticket-board, submit-feedback, and Sales-CRM
deal/task/analytics/recommendation/health tools. Mirrored tools forward to the
hosted transport with the same names and Bearer key, so their auth, scopes,
and rendering match the hosted behavior. The previous stable release was
0.8.0 with 93 tools. The mirrored tools require
a matching 2.5.0 backend. Set `META_COUNCIL_URL` to a verified matching
deployment.

**Councils**
| Tool | Description |
|------|-------------|
| `convene_council` | Submit a question to a panel of AI experts. Returns synthesis with executive summary, risk matrix, and action plan. |
| `list_panels` | Browse all expert panels (biotech, finance, software, crisis, LOCUS, etc.) |
| `list_agents` | Browse 290+ expert agents, filterable by domain |
| `get_session` | Retrieve results from a previous council session |
| `recommend_panel` | Get the best panel recommendation for your query |
| `get_visualization` | Fetch a result chart by `artifact_id` — the spec JSON, plus the SVG markup with `include_svg: true`. Requires the owning API key. |

**Workflows (composable multi-step pipelines)**
| Tool | Description |
|------|-------------|
| `list_workflows` | Browse available workflow pipelines (each step can run on its own model/provider). |
| `run_workflow` | Run a pipeline end-to-end; returns each step's model + output and the final synthesis. |
| `get_workflow_session` | Poll a running workflow for step-by-step progress. |
| `advance_workflow` | Approve/reject a human checkpoint to advance a paused workflow. |

**LOCUS (behavioral-health level-of-care automation)**
| Tool | Description |
|------|-------------|
| `score_locus_case` | Convene the LOCUS panel on an anonymized adult case; returns a deterministic Level-of-Care determination (composite + override floors applied in code) plus narrative. |
| `locus_determine_from_scores` | Instant, no-LLM determination from six dimension ratings you already have (1-5 each). |

See `docs/locus_integration.md` for the full LOCUS guide.

**Legal research**
| Tool | Description |
|------|-------------|
| `ask_legal` | Citation-grounded U.S. federal/California research through Themis. Requires `legal:run`; the server owns the service credential and generation-mode decision. Informational, not legal advice. |

**Accounting (private deterministic audit runs)**
| Tool | Description |
|------|-------------|
| `create_accounting_run` | Analyze 1–50 textual `.txt`, `.md`, `.text`, `.eml`, `.csv`, `.ofx`, `.qfx`, or `.qif` records and create an encrypted owner-scoped run. Requires `accounting:write`. |
| `list_accounting_runs` | List the caller's audit metadata only; input and results are omitted. Requires `accounting:read`. |
| `get_accounting_run` | Return one owned run's deterministic estimates, disclaimer, engine revision, and timestamps. Decrypted input is opt-in. Requires `accounting:read`. |
| `delete_accounting_run` | Permanently delete one audit run owned by the caller. Requires `accounting:write`. |
| `preview_accounting_ticket_sync` | Read-only plan showing stable-ticket creates/updates, preserved edits to generated content fields, and conflicts. Requires both `accounting:read` and `tickets:read`; `tickets:write` satisfies the latter. |
| `sync_accounting_tickets` | Idempotently commit the exact previewed plan using its required `expected_plan_hash`. Requires both `accounting:read` and `tickets:write`. |

Accounting output is an estimate for professional review. These tools do not
file a return, move money, or send records to an external accounting service.
Read/write scopes are independent and are never added to default or legacy
keys; explicitly grant the applicable ticket scope for synchronization.
Preview before commit: ticket projections are owner-private but are not stored
inside the encrypted Accounting payload. Full source documents and Accounting
amount fields are not copied, but work-plan text itself may reproduce
source-derived filenames, merchant/date snippets, column headers, or parser
details. Once committed, that task text is readable by the owner's agents and
API keys with `tickets:read`, even without `accounting:read`; review the exact
projection before confirming it. Sync preserves human edits to generated
content fields and never resets status, assignee, hierarchy, or completion.
Stable identity comes from the encrypted run's versioned source/item/rule
envelope; visible WRITEOff IDs and merchant targets are display-only. Runs
created before that provenance contract must be reprocessed before preview.
The `accounting_run` external reference and `workflow_session_id` are
system-owned mirrors of the newest surviving linked Accounting run.

**Configuration**
| Tool | Description |
|------|-------------|
| `get_settings` | Current model preference + configured provider/tool keys. |
| `configure_model` | Set your preferred LLM model. |
| `configure_provider_key` | Add an LLM provider API key (anthropic, openai, google, …). |
| `configure_tool_key` | Add a premium-tool API key (alpha_vantage, tavily, …). |
| `get_agent_detail` | Full detail on one agent (role, model, tools). |

**Outreach (sales-pipeline management)**
| Tool | Description |
|------|-------------|
| `list_outreach_campaigns` / `create_outreach_campaign` / `update_outreach_campaign` / `delete_outreach_campaign` | Campaign CRUD. |
| `search_outreach_leads` / `update_lead_status` / `edit_outreach_email` | Lead management. |
| `assign_leads_to_campaign` / `send_outreach_batch` / `campaign_pipeline_stats` | Run a campaign. |
| `list_campaign_triggers` / `create_campaign_trigger` / `delete_campaign_trigger` | Automation rules. |
| `list_campaign_replies` / `outreach_analytics` | Replies + analytics. |

**Ticket board & feedback (mirrors of the hosted transport)**
| Tool | Description |
|------|-------------|
| `ticket_list` / `ticket_get` | Traverse work on the caller's board in owner/filter-bound cursor pages of up to 200, including direct-child or flat recursive-descendant filters; get full metadata, acceptance criteria, subticket progress, external references, and activity. Requires `tickets:read`. |
| `ticket_create` / `ticket_update` / `ticket_comment` / `ticket_claim` | Create with full ticket metadata, safely edit/reparent/clear caller-owned fields, comment, and claim-to-in_progress. System refs are protected, and the acting API-key UUID is stamped server-side on creator/author/mutation provenance. Requires `tickets:write`. |
| `ticket_plan` | Preview a bounded normalized plan, then commit that exact plan without a second provider call. Requires the caller-held idempotency key and returned preview token; exact retries return the same IDs. Requires `tickets:write`; prompt-only preview additionally requires `councils:run`, while supplied-plan preview and commit are provider-free. |
| `ticket_batch_create` | Preview or atomically commit an explicit ticket/subticket tree with stable refs and deterministic IDs. Exact retries do not duplicate tickets; no work is executed and no external system is changed. Requires `tickets:write`. |
| `ticket_validation_finalize` | Commit or exactly replay one evidence-backed terminal result for an exact scenario revision. Owner/actor are credential-derived; opaque evidence is never fetched and only compact digest receipts are returned. Requires the separate `tickets:validate` scope. |
| `submit_feedback` | Write-only product feedback to the platform admins (`feedback:write`). The admin-only `list_feedback` is deliberately hosted-only. |

**Sales CRM — deals, tasks, analytics & health (mirrors of the hosted transport)**
| Tool | Description |
|------|-------------|
| `list_deals` / `get_deal` | List the caller's deals with a weighted pipeline forecast (open/weighted/won); fetch one deal with its full activity timeline. Requires `outreach:read`. |
| `get_sales_analytics` / `get_sales_recommendations` | Pipeline analytics (probability-weighted forecast, per-stage $ rollup, win rate, sales-cycle days, open-deal aging) and prioritized next-best actions (leads to convert, stale deals to follow up, overdue tasks — each with a rationale + the exact governed tool to run next). Read-only; both require `outreach:read`. |
| `get_deal_health` | Deterministically score and rank the caller's open deals as healthy/watch/at-risk with reasons. Read-only; requires `outreach:read`. |
| `create_deal` / `update_deal` / `convert_lead_to_deal` | Create a deal, advance its stage (auto-stamps the close date on won/lost), or convert an owned lead into a deal. Requires `outreach:agent_write`. |
| `log_deal_activity` / `list_sales_tasks` / `complete_sales_task` | Log a note/call/meeting/email or a due-dated follow-up task on a deal or lead, list open tasks bucketed overdue/today/upcoming, and close one. `log_deal_activity`/`complete_sales_task` require `outreach:agent_write`; `list_sales_tasks` requires `outreach:read`. No deletes are exposed over MCP. |

**Marketing workspace (mirrors of the hosted transport)**
| Tool | Description |
|------|-------------|
| `list_marketing_brands` / `get_marketing_brand` / `create_marketing_brand` / `update_marketing_brand` | Owner-private brand voice, positioning, and guidelines. Reads require `marketing:read`; writes require `marketing:agent_write`. |
| `list_marketing_audiences` / `get_marketing_audience` / `create_marketing_audience` / `update_marketing_audience` | Reusable owner-private audience definitions. |
| `list_marketing_campaigns` / `get_marketing_campaign` / `create_marketing_campaign` / `update_marketing_campaign` | Content campaigns, separate from Sales outreach campaigns. Campaign status never publishes content. |
| `list_content_assets` / `get_content_asset` / `get_content_calendar` | Read revision lineage, immutable submitted/reviewed snapshots, exact review hashes, and planned dates (`marketing:read`). |
| `create_content_asset` / `update_content_asset` / `create_content_asset_revision` / `submit_content_asset` | Governed draft/revise/submit flow (`marketing:agent_write`). Submitted revisions freeze. |
| `approve_content_asset` / `reject_content_asset` | Separate reviewer authority (`marketing:approve`). Approval records the exact content hash; it does not publish or send. |

**Consulting workspace (mirrors of the hosted transport)**
| Tool | Description |
|------|-------------|
| `list_consulting_clients` / `create_consulting_client` / `update_consulting_client` | Manage client records private to the API-key owner. Reads require `consulting:read`; writes require `consulting:write`. |
| `list_consulting_engagements` / `get_consulting_engagement` / `create_consulting_engagement` / `update_consulting_engagement` | Manage engagements and inspect their full internal workspace, including nullable Sales/Accounting refs. |
| `create_consulting_document_revision` / `update_consulting_document_revision` / `approve_consulting_document_revision` | Draft revision-safe proposals/SOWs and separately approve one exact immutable revision. Approval requires `consulting:approve`, the fetched `version`/`content_hash`, and a different credential from the last editor. |
| `initialize_consulting_milestones` / `update_consulting_milestone` | Idempotently initialize stable milestone IDs/external refs and advance owned milestones with `expected_version` compare-and-swap protection. |
| `create_consulting_deliverable` / `update_consulting_deliverable` / `submit_consulting_deliverable` / `reopen_consulting_deliverable` / `approve_consulting_deliverable` | Draft and review internal deliverables. Approval supplies the fetched `version`/`content_hash` and uses a reviewer credential distinct from the last editor; it never publishes or sends. |

All changes flow through the same backend as the web UI, so they appear live in the dashboard.

**Resources & Prompts**

Beyond tools, the server exposes 3 MCP **resources** for browsing — `council://panels`, `council://workflows`, `council://agents` — and 3 **prompt** templates for common council / LOCUS / workflow flows.

## Visualizations

Results ship with charts automatically — nothing to render, no extra calls. When
a council completes, the server draws dark-themed SVG charts (per-agent consensus
confidence; for LOCUS, dimension ratings with override-floor flags) and stores
them alongside the result. Tool responses list them under **Visuals**, and the raw
API/session JSON carries refs like:

```json
{
    "artifact_id": "9f3c…32-hex…a1",
    "svg_url": "/api/viz/9f3c….svg",
    "spec_url": "/api/viz/9f3c….json"
}
```

- **`svg_url`** — an artifact URL. Artifacts created by authenticated hosted MCP
  runs are private by default and require the owning identity; an artifact ID is
  not a bearer capability. Browser clients should fetch it with an
  `Authorization` header and render the returned blob rather than placing a key
  in a query string.
- **`spec_url`** — the chart's underlying data as JSON, for agents that want the
  numbers rather than the picture. The same owner check applies.
- **`get_visualization`** — fetches both by `artifact_id`; pass
  `include_svg: true` to receive the SVG markup inline. It requires
  `councils:read` and verifies the artifact owner.

The same charts appear on the session page at meta-council.com.

## Example Usage (from Claude Code)

> "Convene the biotech panel to analyze whether we should proceed with our Phase IIb trial given the marginal endpoint miss."

The hosted transport calls `run_council`; the source-run stdio adapter calls
`convene_council`. Both return the council result through their respective
asynchronous/polling flow.

> "Score this LOCUS case using synthetic or properly de-identified data. What level of care?"

Claude calls `score_locus_case` and returns the deterministic level (e.g. "Level 5 — Medically Monitored Residential") with the override audit trail.

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `META_COUNCIL_API_KEY` | (none) | Your API key from meta-council.com. Only the four catalog tools can work without it; runs, recommendations, session/artifact reads, settings, regulated-domain tools, and every private workspace operation require an appropriately scoped key. |
| `META_COUNCIL_URL` | `https://meta-council.com` | Server URL (for self-hosted) |

## Self-Hosted

Point to your own Meta Council instance:

```bash
export META_COUNCIL_URL="http://localhost:8080"
export META_COUNCIL_API_KEY="mc_your_local_key"
```
