---
title: "MCP analytics tools — HyperCRM"
description: "The six MCP tools for dashboard figures, the three bucketed reports, the audit trail and cross-entity search, with the arguments and role each one requires."
canonical: "https://hypercrm.app/docs/mcp/analytics"
lang: "en"
updated: "2026-07-26"
---

_MCP reference / Analytics_

# Analytics and search tools

Six tools covering headline figures, three bucketed reports, the audit trail and cross-entity search. The reports and the audit log are owner-only.

[Start the free trial](/dashboard) · [All 60 tools](/docs/mcp/tools)

## How to read this

Each tool below lists its arguments exactly as the input schema declares them — the type, whether it is required, and the permitted values where the schema fixes them. There are no argument descriptions: the schemas carry types, not prose, and inventing a sentence per argument would be writing fiction about a contract.

`practiceId` is never an argument. It comes from your token, and the write paths strip it if a client sends one anyway.

Every example is a complete `tools/call` request with this tool's required arguments filled in. Errors are returned inside a `200` response with `isError` set — see the [MCP overview](/docs/mcp) for that envelope, and the [full catalogue](/docs/mcp/tools) for every tool at a glance.

Aggregates and cross-entity search. The three reports and the audit log are owner-only.

### get_dashboard_kpis

_Read-only, Any member_

Headline figures — today's appointments, outstanding balances, recent activity counts.

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_dashboard_kpis",
    "arguments": {}
  }
}
```

**Result**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "status": 200,
      "ok": true,
      "data": { "...": "the requested records" }
    }
  }
}
```

**Errors**

| Code | Status | When |
| --- | --- | --- |
| `unauthorized` | 401 | The bearer token is missing, invalid or expired. |

### get_appointments_report

_Read-only, Owner only_

Appointment counts bucketed over a date range. groupBy is day, week or month.

**Arguments**

| Tool | Type | Required? |
| --- | --- | --- |
| `from` | `string` | Required |
| `to` | `string` | Required |
| `groupBy` | `day` \\| `week` \\| `month` | Optional |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_appointments_report",
    "arguments": {
      "from": "2026-07-08T09:00:00.000Z",
      "to": "2026-07-08T17:00:00.000Z"
    }
  }
}
```

**Result**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "status": 200,
      "ok": true,
      "data": { "...": "the requested records" }
    }
  }
}
```

**Errors**

| Code | Status | When |
| --- | --- | --- |
| `validation_failed` | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| `forbidden` | 403 | The caller is not an owner of the practice. |
| `unauthorized` | 401 | The bearer token is missing, invalid or expired. |

### get_revenue_report

_Read-only, Owner only_

Revenue totals bucketed over a date range. groupBy is day, week or month.

**Arguments**

| Tool | Type | Required? |
| --- | --- | --- |
| `from` | `string` | Required |
| `to` | `string` | Required |
| `groupBy` | `day` \\| `week` \\| `month` | Optional |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_revenue_report",
    "arguments": {
      "from": "2026-07-08T09:00:00.000Z",
      "to": "2026-07-08T17:00:00.000Z"
    }
  }
}
```

**Result**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "status": 200,
      "ok": true,
      "data": { "...": "the requested records" }
    }
  }
}
```

**Errors**

| Code | Status | When |
| --- | --- | --- |
| `validation_failed` | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| `forbidden` | 403 | The caller is not an owner of the practice. |
| `unauthorized` | 401 | The bearer token is missing, invalid or expired. |

### get_patient_acquisition_report

_Read-only, Owner only_

New-patient counts bucketed over a date range. groupBy is day, week or month.

**Arguments**

| Tool | Type | Required? |
| --- | --- | --- |
| `from` | `string` | Required |
| `to` | `string` | Required |
| `groupBy` | `day` \\| `week` \\| `month` | Optional |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_patient_acquisition_report",
    "arguments": {
      "from": "2026-07-08T09:00:00.000Z",
      "to": "2026-07-08T17:00:00.000Z"
    }
  }
}
```

**Result**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "status": 200,
      "ok": true,
      "data": { "...": "the requested records" }
    }
  }
}
```

**Errors**

| Code | Status | When |
| --- | --- | --- |
| `validation_failed` | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| `forbidden` | 403 | The caller is not an owner of the practice. |
| `unauthorized` | 401 | The bearer token is missing, invalid or expired. |

### list_audit_log

_Read-only, Owner only_

Read the practice audit trail, newest first. Filter by entity type and a date range.

**Arguments**

| Tool | Type | Required? |
| --- | --- | --- |
| `type` | `string` | Optional |
| `from` | `string` | Optional |
| `to` | `string` | Optional |
| `limit` | `integer` | Optional |
| `offset` | `integer` | Optional |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_audit_log",
    "arguments": {}
  }
}
```

**Result**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "status": 200,
      "ok": true,
      "data": { "...": "the requested records" }
    }
  }
}
```

**Errors**

| Code | Status | When |
| --- | --- | --- |
| `validation_failed` | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| `forbidden` | 403 | The caller is not an owner of the practice. |
| `unauthorized` | 401 | The bearer token is missing, invalid or expired. |

### search

_Read-only, Any member_

Cross-entity search over the practice — patients, appointments and more.

**Arguments**

| Tool | Type | Required? |
| --- | --- | --- |
| `q` | `string` | Required |
| `limit` | `integer` | Optional |

**Example call**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search",
    "arguments": {
      "q": "doe"
    }
  }
}
```

**Result**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "status": 200,
      "ok": true,
      "data": { "...": "the requested records" }
    }
  }
}
```

**Errors**

| Code | Status | When |
| --- | --- | --- |
| `validation_failed` | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| `unauthorized` | 401 | The bearer token is missing, invalid or expired. |

## Common questions

### How is patient data protected?

Patient records are encrypted in transit and at rest, files are stored privately and served through short-lived signed links, and every change is written to an audit log. Staff accounts sign in with passkeys rather than shared passwords.

### Can I export my data?

Yes. Every list in HyperCRM exports to CSV from the app, and your files can be downloaded at any time. Your practice data belongs to you, and there is no export fee or waiting period — on either plan, during the trial, and after you cancel.

### How much does HyperCRM cost?

HyperCRM is paid software. Every practice starts with a 30-day free trial of the full Complete plan, with no card required. After that, plans start at €19 and €29 a month excluding VAT, banded by how many practitioners you have. Every price is printed on the pricing page rather than quoted on a call.