# MCP server

`cormorant-mcp` exposes Cormorant to AI agents as [Model Context
Protocol](https://modelcontextprotocol.io) tools over stdio. It is a small,
separate Python package (in `clients/mcp/` of the Cormorant repository) that
calls the public API with your project key — install it where the agent runs,
not on the Cormorant servers.

## Tools

| Tool | What it does |
|---|---|
| `cormorant_search` | Web search: ranked results with title, URL and up to three snippets. |
| `cormorant_fetch` | Fetch a page, PDF or document: main text (clipped to `max_chars`, continue with `offset`), title, `final_url`, `content_kind`, `retrieved_at`, cost and `error`. Options: `render`, `allow_paid`, `timeout_s`, `pdf_pages`, `include_body_url` (adds `body_url`, `sha256`, `body_kind`). |
| `cormorant_batch_fetch` | Queue many URLs as one batch job; returns a `job_id`. The same URL list maps to the same idempotency key, so a retried call never creates a second job. |
| `cormorant_job_status` | Job state and counts; with `include_items`, a page of results with clipped text. |
| `cormorant_sec_company` | SEC EDGAR: resolve a ticker, CIK or company name to `cik`, `title`, `tickers`, `exchanges` (candidates when a name is ambiguous). |
| `cormorant_sec_filings` | SEC EDGAR: a company's filings (accession, form, dates, primary document), filtered by `forms` and `since`; `latest: true` for the newest annual report (10-K/20-F/40-F). |
| `cormorant_sec_document` | SEC EDGAR: the documents of a filing, or the text of one of them (clipped, continue with `offset`; `pdf_pages` for PDFs). |
| `cormorant_usage` | Usage, charges and limits of the key (or the whole account with an account admin key): `view` = `summary` (totals and the busiest groups with `group_by`), `quota` (limits, allowances, recent alerts), `requests` (latest requests) or `domains`. |
| `cormorant_company_search` | Find companies by name or identifier (`scheme:value`), optionally by country; each hit has a `ref`. |
| `cormorant_company_get` | One company's register record (identifiers, names, legal form, status, addresses, relationships …) with the source of every field; `include` adds people, ownership, filings, financials, events. |
| `cormorant_company_resolve` | Match name/country/city/identifiers to the register: a confident `match` or ranked candidates. |
| `cormorant_northdata` | North Data company data: `op` = `profile` (parsed profile from `url` or `company_name` + `country` + `headquarters`), `discover`, `suggest` or `graph`. Always paid (Massive): needs `allow_paid=true` or `CORMORANT_ALLOW_PAID`. Entity lists and graph nodes clipped to `max_items`. |

The tools never return HTML and clip text, to keep the agent's context small.
Fetches **do not use the paid tiers** unless the agent passes
`allow_paid: true` or you set `CORMORANT_ALLOW_PAID=1`.

## Configuration

| Variable | Default | |
|---|---|---|
| `CORMORANT_API_KEY` | — | Required. The project key (`cmr_…`). Use a dedicated project with a modest budget for agents. |
| `CORMORANT_URL` | `https://api.cormorant.ch` | API base URL. |
| `CORMORANT_ALLOW_PAID` | off | `1` lets fetches use the paid tiers by default. |

## Install

From a checkout of the repository (Python 3.10+):

```sh
pip install ./clients/mcp            # provides the `cormorant-mcp` command
# or, without installing anything permanently:
uvx --from ./clients/mcp cormorant-mcp
```

The main project also declares the dependency as an optional group:
`pip install -e ".[mcp]"` and `python clients/mcp/cormorant_mcp/server.py`.

## Register it

### Claude Code

```sh
claude mcp add --transport stdio cormorant --scope user \
  --env CORMORANT_API_KEY=cmr_... \
  -- uvx --from /path/to/cormorant/clients/mcp cormorant-mcp
```

Use `--scope project` to share the server through the repository's
`.mcp.json` instead (then keep the key out of the file and reference an
environment variable). Check it with `claude mcp list`.

### Claude Desktop

Add to `claude_desktop_config.json` (Settings → Developer → Edit Config) and
restart Claude Desktop:

```json
{
  "mcpServers": {
    "cormorant": {
      "command": "uvx",
      "args": ["--from", "/path/to/cormorant/clients/mcp", "cormorant-mcp"],
      "env": {"CORMORANT_API_KEY": "cmr_..."}
    }
  }
}
```

### Other MCP clients

Any client that launches stdio servers works the same way: command
`cormorant-mcp` (or `uvx --from /path/to/cormorant/clients/mcp cormorant-mcp`),
with `CORMORANT_API_KEY` in its environment. To try the tools interactively,
use the MCP Inspector:

```sh
CORMORANT_API_KEY=cmr_... npx @modelcontextprotocol/inspector uvx --from ./clients/mcp cormorant-mcp
```

## How agents should use it

The server sends these instructions to the client: search first and read the
snippets, fetch only the most relevant pages, do not retry a fetch whose
result has an `error`, use the batch tool for more than 20 URLs, and cite
`final_url` and `retrieved_at`. See
[Using Cormorant from AI agents](/docs/agents.md) for the
reasoning and for patterns without MCP.

## Development

The tool logic is plain async functions over an `httpx.AsyncClient`
(`search`, `fetch`, `batch_fetch`, `job_status` in `cormorant_mcp/server.py`);
`tests/test_mcp_server.py` in the main repository tests them, and the MCP
registration, with mocked HTTP.
