clarity-api 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- clarity_api-1.0.0/LICENSE +20 -0
- clarity_api-1.0.0/MANIFEST.in +5 -0
- clarity_api-1.0.0/PKG-INFO +330 -0
- clarity_api-1.0.0/README.md +297 -0
- clarity_api-1.0.0/clarity_api/__init__.py +77 -0
- clarity_api-1.0.0/clarity_api/__main__.py +4 -0
- clarity_api-1.0.0/clarity_api/agent_data/IDENTITY.md +23 -0
- clarity_api-1.0.0/clarity_api/agent_server.py +86 -0
- clarity_api-1.0.0/clarity_api/api/__init__.py +14 -0
- clarity_api-1.0.0/clarity_api/api/api_client_base.py +125 -0
- clarity_api-1.0.0/clarity_api/api/api_client_insights.py +59 -0
- clarity_api-1.0.0/clarity_api/api_client.py +26 -0
- clarity_api-1.0.0/clarity_api/auth.py +81 -0
- clarity_api-1.0.0/clarity_api/clarity_api.py +12 -0
- clarity_api-1.0.0/clarity_api/clarity_models.py +161 -0
- clarity_api-1.0.0/clarity_api/decorators.py +20 -0
- clarity_api-1.0.0/clarity_api/exceptions.py +41 -0
- clarity_api-1.0.0/clarity_api/main_agent.json +13 -0
- clarity_api-1.0.0/clarity_api/mcp/__init__.py +10 -0
- clarity_api-1.0.0/clarity_api/mcp/mcp_insights.py +67 -0
- clarity_api-1.0.0/clarity_api/mcp_config.json +3 -0
- clarity_api-1.0.0/clarity_api/mcp_server.py +91 -0
- clarity_api-1.0.0/clarity_api/models.py +21 -0
- clarity_api-1.0.0/clarity_api/services/__init__.py +9 -0
- clarity_api-1.0.0/clarity_api/services/insights_service.py +40 -0
- clarity_api-1.0.0/clarity_api/version.py +5 -0
- clarity_api-1.0.0/clarity_api.egg-info/PKG-INFO +330 -0
- clarity_api-1.0.0/clarity_api.egg-info/SOURCES.txt +50 -0
- clarity_api-1.0.0/clarity_api.egg-info/dependency_links.txt +1 -0
- clarity_api-1.0.0/clarity_api.egg-info/entry_points.txt +3 -0
- clarity_api-1.0.0/clarity_api.egg-info/requires.txt +21 -0
- clarity_api-1.0.0/clarity_api.egg-info/top_level.txt +6 -0
- clarity_api-1.0.0/pyproject.toml +59 -0
- clarity_api-1.0.0/requirements.txt +1 -0
- clarity_api-1.0.0/scripts/security_sanitizer.py +160 -0
- clarity_api-1.0.0/scripts/verify_api_integration.py +237 -0
- clarity_api-1.0.0/setup.cfg +4 -0
- clarity_api-1.0.0/tests/__init__.py +0 -0
- clarity_api-1.0.0/tests/conftest.py +64 -0
- clarity_api-1.0.0/tests/integration/__init__.py +0 -0
- clarity_api-1.0.0/tests/integration/test_data_export_integration.py +62 -0
- clarity_api-1.0.0/tests/unit/__init__.py +0 -0
- clarity_api-1.0.0/tests/unit/test_api_client.py +71 -0
- clarity_api-1.0.0/tests/unit/test_auth.py +56 -0
- clarity_api-1.0.0/tests/unit/test_clarity_api.py +28 -0
- clarity_api-1.0.0/tests/unit/test_clarity_models.py +86 -0
- clarity_api-1.0.0/tests/unit/test_concept_parity.py +114 -0
- clarity_api-1.0.0/tests/unit/test_errors.py +75 -0
- clarity_api-1.0.0/tests/unit/test_init_dynamics.py +36 -0
- clarity_api-1.0.0/tests/unit/test_insights_service.py +47 -0
- clarity_api-1.0.0/tests/unit/test_mcp_registration.py +38 -0
- clarity_api-1.0.0/tests/unit/test_startup.py +35 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2012-2023 Audel Rouhi
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clarity-api
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Microsoft Clarity API + MCP Server + A2A Server
|
|
5
|
+
Author-email: Audel Rouhi <knucklessg1@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: License :: Public Domain
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: <3.15,>=3.11
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: agent-utilities>=0.47.0
|
|
16
|
+
Requires-Dist: requests>=2.8.1
|
|
17
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
18
|
+
Requires-Dist: pydantic[email]>=2.8.2
|
|
19
|
+
Requires-Dist: urllib3>=2.2.2
|
|
20
|
+
Provides-Extra: mcp
|
|
21
|
+
Requires-Dist: agent-utilities[mcp]>=0.47.0; extra == "mcp"
|
|
22
|
+
Provides-Extra: agent
|
|
23
|
+
Requires-Dist: agent-utilities[agent,logfire]>=0.47.0; extra == "agent"
|
|
24
|
+
Requires-Dist: logfire>=0.50.0; extra == "agent"
|
|
25
|
+
Provides-Extra: all
|
|
26
|
+
Requires-Dist: clarity-api[agent,mcp]>=1.0.0; extra == "all"
|
|
27
|
+
Provides-Extra: test
|
|
28
|
+
Requires-Dist: pytest-xdist>=3.6.0; extra == "test"
|
|
29
|
+
Requires-Dist: pytest; extra == "test"
|
|
30
|
+
Requires-Dist: pytest-asyncio; extra == "test"
|
|
31
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Microsoft Clarity API
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+

|
|
38
|
+

|
|
39
|
+

|
|
40
|
+

|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+
|
|
45
|
+

|
|
46
|
+

|
|
47
|
+

|
|
48
|
+
|
|
49
|
+

|
|
50
|
+

|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
*Version: 1.0.0*
|
|
54
|
+
|
|
55
|
+
**Microsoft Clarity API + MCP Server + A2A Agent**
|
|
56
|
+
|
|
57
|
+
`clarity-api` is a typed, action-routed connector for the
|
|
58
|
+
[Microsoft Clarity Data Export API](https://learn.microsoft.com/en-us/clarity/setup-and-installation/clarity-data-export-api),
|
|
59
|
+
built on [`agent-utilities`](https://github.com/Knuckles-Team/agent-utilities). It
|
|
60
|
+
ships a Python `Api` client, a [FastMCP](https://github.com/jlowin/fastmcp) MCP server
|
|
61
|
+
(`clarity-mcp`), and an optional Pydantic-AI A2A agent server (`clarity-agent`).
|
|
62
|
+
|
|
63
|
+
It works with the dashboard data — structured over a specified date range and broken
|
|
64
|
+
down by up to three dimensions.
|
|
65
|
+
|
|
66
|
+
This repository is actively maintained — contributions are welcome!
|
|
67
|
+
|
|
68
|
+
## Table of Contents
|
|
69
|
+
|
|
70
|
+
- [Architecture](#architecture)
|
|
71
|
+
- [Key Features](#key-features)
|
|
72
|
+
- [Available MCP Tools](#available-mcp-tools)
|
|
73
|
+
- [Dynamic Tool Selection](#dynamic-tool-selection)
|
|
74
|
+
- [Environment Variables](#environment-variables)
|
|
75
|
+
- [Configuration](#configuration)
|
|
76
|
+
- [Agent](#agent)
|
|
77
|
+
- [Usage (Python client)](#usage-python-client)
|
|
78
|
+
- [Security & Governance](#security--governance)
|
|
79
|
+
- [Installation](#installation)
|
|
80
|
+
- [Documentation](#documentation)
|
|
81
|
+
- [Contributing](#contributing)
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
`clarity-api` follows the standard agent-package layering: a typed REST client at
|
|
86
|
+
the bottom, an action-routed MCP tool layer in the middle, and an optional
|
|
87
|
+
Pydantic-AI A2A agent server on top. The MCP tool depends on an injected client
|
|
88
|
+
via `Depends(get_client)`, which resolves credentials (OIDC delegation or a fixed
|
|
89
|
+
`CLARITY_TOKEN`) before talking to the Microsoft Clarity REST API.
|
|
90
|
+
|
|
91
|
+
```mermaid
|
|
92
|
+
graph TD
|
|
93
|
+
User(["User / A2A Client"]) --> Agent["clarity-agent<br/>Pydantic-AI A2A Server"]
|
|
94
|
+
Agent --> MCP["clarity-mcp<br/>FastMCP Server"]
|
|
95
|
+
MCP --> Tool["clarity_insights tool<br/>(CONCEPT:CLA-001)"]
|
|
96
|
+
Tool -->|Depends get_client| Auth["get_client<br/>auth.py"]
|
|
97
|
+
Tool --> Service["InsightsService<br/>clarity_api/services/"]
|
|
98
|
+
Auth --> Client["Api facade<br/>clarity_api/api/"]
|
|
99
|
+
Service --> Client
|
|
100
|
+
Client --> Clarity(["Microsoft Clarity<br/>Data Export REST API"])
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
| Layer | Module | Responsibility |
|
|
104
|
+
|-------|--------|----------------|
|
|
105
|
+
| Agent | `clarity_api/agent_server.py` | Pydantic-AI A2A server, AG-UI web interface |
|
|
106
|
+
| Tooling | `clarity_api/mcp/`, `clarity_api/mcp_server.py` | Action-routed MCP tool registration |
|
|
107
|
+
| Service | `clarity_api/services/` | `InsightsService` — dependency-injected data-export use case |
|
|
108
|
+
| Auth seam | `clarity_api/auth.py` | `get_client` dependency: OIDC delegation / fixed token |
|
|
109
|
+
| Client | `clarity_api/api/` | `ClarityApiBase` + `ClarityApiInsights` mixins composed into `Api` |
|
|
110
|
+
| Models | `clarity_api/clarity_models.py` | Pydantic request/response validation |
|
|
111
|
+
|
|
112
|
+
## Key Features
|
|
113
|
+
|
|
114
|
+
- **Typed Python client** — `clarity_api.api_client.Api`, composed from modular per-domain
|
|
115
|
+
mixins in `clarity_api/api/`, validating credentials against `GET /projects`.
|
|
116
|
+
- **Action-routed MCP tool** — `clarity_insights` (`CONCEPT:CLA-001`) consolidates the
|
|
117
|
+
Data Export surface to minimize LLM token overhead.
|
|
118
|
+
- **A2A agent server** — `clarity-agent` auto-discovers the MCP tools and exposes an
|
|
119
|
+
AG-UI web interface.
|
|
120
|
+
- **Enterprise-ready** — inherits OIDC auth, OpenTelemetry, audit logging, prompt-injection
|
|
121
|
+
defense, and guardrails from `agent-utilities`.
|
|
122
|
+
|
|
123
|
+
## Available MCP Tools
|
|
124
|
+
|
|
125
|
+
| Tool | Concept | Actions | Description |
|
|
126
|
+
|------|---------|---------|-------------|
|
|
127
|
+
| `clarity_insights` | `CONCEPT:CLA-001` | `get_data_export` | Export Clarity dashboard data / live insights |
|
|
128
|
+
|
|
129
|
+
### Parameters
|
|
130
|
+
- `number_of_days` (1, 2, or 3): last 24, 48, or 72 hours.
|
|
131
|
+
- `dimension_1`, `dimension_2`, `dimension_3`: breakdown dimensions.
|
|
132
|
+
|
|
133
|
+
#### Dimension Options
|
|
134
|
+
`Browser`, `Device`, `Country`, `OS`, `Source`, `Medium`, `Campaign`, `Channel`, `URL`.
|
|
135
|
+
|
|
136
|
+
## Dynamic Tool Selection
|
|
137
|
+
|
|
138
|
+
Each tool domain is gated behind an env toggle so deployments can trim their surface:
|
|
139
|
+
|
|
140
|
+
| Toggle | Default | Domain |
|
|
141
|
+
|--------|---------|--------|
|
|
142
|
+
| `INSIGHTSTOOL` | `True` | `clarity_insights` |
|
|
143
|
+
|
|
144
|
+
## Environment Variables
|
|
145
|
+
|
|
146
|
+
All runtime configuration is supplied via environment variables (or a `.env`
|
|
147
|
+
file — see [`.env.example`](.env.example)). Never commit real tokens.
|
|
148
|
+
|
|
149
|
+
### Clarity credentials
|
|
150
|
+
|
|
151
|
+
| Variable | Default | Description |
|
|
152
|
+
|----------|---------|-------------|
|
|
153
|
+
| `CLARITY_URL` | `https://www.clarity.ms` | Base URL of the Microsoft Clarity instance. |
|
|
154
|
+
| `CLARITY_TOKEN` | _(none)_ | Bearer API token generated in the Clarity project settings. Required unless OIDC delegation is enabled. |
|
|
155
|
+
| `CLARITY_SSL_VERIFY` | `True` | Whether to verify TLS certificates when calling the Clarity API. |
|
|
156
|
+
|
|
157
|
+
### MCP server / transport
|
|
158
|
+
|
|
159
|
+
| Variable | Default | Description |
|
|
160
|
+
|----------|---------|-------------|
|
|
161
|
+
| `TRANSPORT` | `stdio` | MCP transport: `stdio`, `streamable-http`, or `sse`. |
|
|
162
|
+
| `HOST` | `0.0.0.0` | Bind host for HTTP transports. |
|
|
163
|
+
| `PORT` | `8000` | Bind port for HTTP transports. |
|
|
164
|
+
| `AUTH_TYPE` | `none` | MCP server auth scheme inherited from `agent-utilities` (e.g. `none`, `oidc`). |
|
|
165
|
+
| `FASTMCP_LOG_LEVEL` | `ERROR` | FastMCP log verbosity. Set to `ERROR` at startup to suppress log spam. |
|
|
166
|
+
| `INSIGHTSTOOL` | `True` | Toggle registration of the `clarity_insights` tool (see [Dynamic Tool Selection](#dynamic-tool-selection)). |
|
|
167
|
+
|
|
168
|
+
### Telemetry & access governance
|
|
169
|
+
|
|
170
|
+
| Variable | Default | Description |
|
|
171
|
+
|----------|---------|-------------|
|
|
172
|
+
| `ENABLE_OTEL` | `True` | Enable OpenTelemetry export of traces/metrics. |
|
|
173
|
+
| `EUNOMIA_TYPE` | `none` | Eunomia authorization mode: `none`, `embedded`, or `remote`. |
|
|
174
|
+
| `EUNOMIA_POLICY_FILE` | `mcp_policies.json` | Path to the local Eunomia policy file (embedded mode). |
|
|
175
|
+
|
|
176
|
+
### Build / terminal (set automatically — usually no action needed)
|
|
177
|
+
|
|
178
|
+
| Variable | Default | Description |
|
|
179
|
+
|----------|---------|-------------|
|
|
180
|
+
| `UV_COMPILE_BYTECODE` | `1` | Set in the Docker image to precompile bytecode for faster cold starts. |
|
|
181
|
+
| `NO_COLOR` / `TERM` | `1` / `dumb` | Terminal-control variables set at MCP startup to keep stdio transport output machine-clean. Not app configuration — listed for completeness. |
|
|
182
|
+
|
|
183
|
+
## Configuration
|
|
184
|
+
|
|
185
|
+
### stdio (local agent integration)
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"mcpServers": {
|
|
190
|
+
"clarity-api": {
|
|
191
|
+
"command": "uv",
|
|
192
|
+
"args": ["run", "--with", "clarity-api", "clarity-mcp"],
|
|
193
|
+
"env": {
|
|
194
|
+
"CLARITY_URL": "https://www.clarity.ms",
|
|
195
|
+
"CLARITY_TOKEN": "<YOUR_CLARITY_TOKEN>"
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Streamable HTTP
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
export CLARITY_URL=https://www.clarity.ms
|
|
206
|
+
export CLARITY_TOKEN=<your-clarity-token>
|
|
207
|
+
clarity-mcp --transport streamable-http --host 0.0.0.0 --port 8000
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Docker
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
docker pull knucklessg1/clarity-api:latest
|
|
214
|
+
docker compose -f docker/mcp.compose.yml up -d
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Agent
|
|
218
|
+
|
|
219
|
+
The `clarity-agent` entry point (`clarity_api/agent_server.py`) starts a
|
|
220
|
+
Pydantic-AI A2A server that auto-discovers the MCP tools and exposes an AG-UI web
|
|
221
|
+
interface.
|
|
222
|
+
|
|
223
|
+
### Run locally
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
clarity-agent --web --provider openai --model-id gpt-4o
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The agent reads its identity from `clarity_api/agent_data/IDENTITY.md` and discovers
|
|
230
|
+
tools via `mcp_config.json`.
|
|
231
|
+
|
|
232
|
+
### Deploy with Docker Compose
|
|
233
|
+
|
|
234
|
+
`docker/agent.compose.yml` runs the MCP server and the agent server side by side;
|
|
235
|
+
the agent connects to the MCP server over `MCP_URL`:
|
|
236
|
+
|
|
237
|
+
```yaml
|
|
238
|
+
services:
|
|
239
|
+
clarity-api-mcp:
|
|
240
|
+
image: knucklessg1/clarity-api:latest
|
|
241
|
+
restart: always
|
|
242
|
+
env_file: [ ../.env ]
|
|
243
|
+
environment:
|
|
244
|
+
- HOST=0.0.0.0
|
|
245
|
+
- PORT=8000
|
|
246
|
+
- TRANSPORT=streamable-http
|
|
247
|
+
ports: [ "8000:8000" ]
|
|
248
|
+
|
|
249
|
+
clarity-api-agent:
|
|
250
|
+
image: knucklessg1/clarity-api:latest
|
|
251
|
+
restart: always
|
|
252
|
+
depends_on: [ clarity-api-mcp ]
|
|
253
|
+
command: [ "clarity-agent" ]
|
|
254
|
+
env_file: [ ../.env ]
|
|
255
|
+
environment:
|
|
256
|
+
- HOST=0.0.0.0
|
|
257
|
+
- PORT=9017
|
|
258
|
+
- MCP_URL=http://clarity-api-mcp:8000/mcp
|
|
259
|
+
- PROVIDER=${PROVIDER:-openai}
|
|
260
|
+
- MODEL_ID=${MODEL_ID:-gpt-4o}
|
|
261
|
+
- ENABLE_WEB_UI=True
|
|
262
|
+
- ENABLE_OTEL=True
|
|
263
|
+
ports: [ "9017:9017" ]
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
docker compose -f docker/agent.compose.yml up -d
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Usage (Python client)
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
#!/usr/bin/python
|
|
274
|
+
# coding: utf-8
|
|
275
|
+
import clarity_api
|
|
276
|
+
|
|
277
|
+
token = "<TOKEN>"
|
|
278
|
+
url = "https://www.clarity.ms"
|
|
279
|
+
client = clarity_api.Api(url=url, token=token)
|
|
280
|
+
|
|
281
|
+
response = client.get_data_export(number_of_days=2, dimension_1="OS", dimension_2="Channel")
|
|
282
|
+
print("Status Code:", response.status_code)
|
|
283
|
+
print("JSON Output:", response.json())
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Security & Governance
|
|
287
|
+
|
|
288
|
+
`clarity-api` inherits enterprise infrastructure from `agent-utilities`: JWT/OIDC
|
|
289
|
+
authentication, OpenTelemetry instrumentation, HashiCorp Vault secret resolution,
|
|
290
|
+
append-only audit logging (agent-utilities `OS-5.4`), prompt-injection defense
|
|
291
|
+
(`OS-5.1`), and the guardrail engine (`OS-5.3`). The connector stays
|
|
292
|
+
inactive until `CLARITY_URL` and `CLARITY_TOKEN` are configured. Never commit `.env`
|
|
293
|
+
files or tokens.
|
|
294
|
+
|
|
295
|
+
## Installation
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
python -m pip install "clarity-api[all]"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
| Extra | Use for |
|
|
302
|
+
|-------|---------|
|
|
303
|
+
| _(none)_ | the `Api` client |
|
|
304
|
+
| `mcp` | the `clarity-mcp` MCP server |
|
|
305
|
+
| `agent` | the `clarity-agent` A2A agent |
|
|
306
|
+
| `all` | everything |
|
|
307
|
+
|
|
308
|
+
### Obtaining Access Tokens
|
|
309
|
+
**Note**: Only project admins can manage access tokens.
|
|
310
|
+
|
|
311
|
+
1. Go to your Clarity project. Select `Settings` → `Data Export` → `Generate new API token`.
|
|
312
|
+
2. Provide a descriptive name for the token for easy identification.
|
|
313
|
+
|
|
314
|
+
## Documentation
|
|
315
|
+
|
|
316
|
+
- [Documentation site](https://knuckles-team.github.io/clarity-api/)
|
|
317
|
+
- [Overview](docs/overview.md)
|
|
318
|
+
- [Installation](docs/installation.md)
|
|
319
|
+
- [Usage](docs/usage.md)
|
|
320
|
+
- [Deployment](docs/deployment.md)
|
|
321
|
+
- [Concepts](docs/concepts.md)
|
|
322
|
+
|
|
323
|
+
## Contributing
|
|
324
|
+
|
|
325
|
+
Contributions are welcome. Run quality checks before pushing:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
pre-commit run --all-files
|
|
329
|
+
python -m pytest -q
|
|
330
|
+
```
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Microsoft Clarity API
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+

|
|
13
|
+

|
|
14
|
+

|
|
15
|
+
|
|
16
|
+

|
|
17
|
+

|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
*Version: 1.0.0*
|
|
21
|
+
|
|
22
|
+
**Microsoft Clarity API + MCP Server + A2A Agent**
|
|
23
|
+
|
|
24
|
+
`clarity-api` is a typed, action-routed connector for the
|
|
25
|
+
[Microsoft Clarity Data Export API](https://learn.microsoft.com/en-us/clarity/setup-and-installation/clarity-data-export-api),
|
|
26
|
+
built on [`agent-utilities`](https://github.com/Knuckles-Team/agent-utilities). It
|
|
27
|
+
ships a Python `Api` client, a [FastMCP](https://github.com/jlowin/fastmcp) MCP server
|
|
28
|
+
(`clarity-mcp`), and an optional Pydantic-AI A2A agent server (`clarity-agent`).
|
|
29
|
+
|
|
30
|
+
It works with the dashboard data — structured over a specified date range and broken
|
|
31
|
+
down by up to three dimensions.
|
|
32
|
+
|
|
33
|
+
This repository is actively maintained — contributions are welcome!
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
- [Architecture](#architecture)
|
|
38
|
+
- [Key Features](#key-features)
|
|
39
|
+
- [Available MCP Tools](#available-mcp-tools)
|
|
40
|
+
- [Dynamic Tool Selection](#dynamic-tool-selection)
|
|
41
|
+
- [Environment Variables](#environment-variables)
|
|
42
|
+
- [Configuration](#configuration)
|
|
43
|
+
- [Agent](#agent)
|
|
44
|
+
- [Usage (Python client)](#usage-python-client)
|
|
45
|
+
- [Security & Governance](#security--governance)
|
|
46
|
+
- [Installation](#installation)
|
|
47
|
+
- [Documentation](#documentation)
|
|
48
|
+
- [Contributing](#contributing)
|
|
49
|
+
|
|
50
|
+
## Architecture
|
|
51
|
+
|
|
52
|
+
`clarity-api` follows the standard agent-package layering: a typed REST client at
|
|
53
|
+
the bottom, an action-routed MCP tool layer in the middle, and an optional
|
|
54
|
+
Pydantic-AI A2A agent server on top. The MCP tool depends on an injected client
|
|
55
|
+
via `Depends(get_client)`, which resolves credentials (OIDC delegation or a fixed
|
|
56
|
+
`CLARITY_TOKEN`) before talking to the Microsoft Clarity REST API.
|
|
57
|
+
|
|
58
|
+
```mermaid
|
|
59
|
+
graph TD
|
|
60
|
+
User(["User / A2A Client"]) --> Agent["clarity-agent<br/>Pydantic-AI A2A Server"]
|
|
61
|
+
Agent --> MCP["clarity-mcp<br/>FastMCP Server"]
|
|
62
|
+
MCP --> Tool["clarity_insights tool<br/>(CONCEPT:CLA-001)"]
|
|
63
|
+
Tool -->|Depends get_client| Auth["get_client<br/>auth.py"]
|
|
64
|
+
Tool --> Service["InsightsService<br/>clarity_api/services/"]
|
|
65
|
+
Auth --> Client["Api facade<br/>clarity_api/api/"]
|
|
66
|
+
Service --> Client
|
|
67
|
+
Client --> Clarity(["Microsoft Clarity<br/>Data Export REST API"])
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Layer | Module | Responsibility |
|
|
71
|
+
|-------|--------|----------------|
|
|
72
|
+
| Agent | `clarity_api/agent_server.py` | Pydantic-AI A2A server, AG-UI web interface |
|
|
73
|
+
| Tooling | `clarity_api/mcp/`, `clarity_api/mcp_server.py` | Action-routed MCP tool registration |
|
|
74
|
+
| Service | `clarity_api/services/` | `InsightsService` — dependency-injected data-export use case |
|
|
75
|
+
| Auth seam | `clarity_api/auth.py` | `get_client` dependency: OIDC delegation / fixed token |
|
|
76
|
+
| Client | `clarity_api/api/` | `ClarityApiBase` + `ClarityApiInsights` mixins composed into `Api` |
|
|
77
|
+
| Models | `clarity_api/clarity_models.py` | Pydantic request/response validation |
|
|
78
|
+
|
|
79
|
+
## Key Features
|
|
80
|
+
|
|
81
|
+
- **Typed Python client** — `clarity_api.api_client.Api`, composed from modular per-domain
|
|
82
|
+
mixins in `clarity_api/api/`, validating credentials against `GET /projects`.
|
|
83
|
+
- **Action-routed MCP tool** — `clarity_insights` (`CONCEPT:CLA-001`) consolidates the
|
|
84
|
+
Data Export surface to minimize LLM token overhead.
|
|
85
|
+
- **A2A agent server** — `clarity-agent` auto-discovers the MCP tools and exposes an
|
|
86
|
+
AG-UI web interface.
|
|
87
|
+
- **Enterprise-ready** — inherits OIDC auth, OpenTelemetry, audit logging, prompt-injection
|
|
88
|
+
defense, and guardrails from `agent-utilities`.
|
|
89
|
+
|
|
90
|
+
## Available MCP Tools
|
|
91
|
+
|
|
92
|
+
| Tool | Concept | Actions | Description |
|
|
93
|
+
|------|---------|---------|-------------|
|
|
94
|
+
| `clarity_insights` | `CONCEPT:CLA-001` | `get_data_export` | Export Clarity dashboard data / live insights |
|
|
95
|
+
|
|
96
|
+
### Parameters
|
|
97
|
+
- `number_of_days` (1, 2, or 3): last 24, 48, or 72 hours.
|
|
98
|
+
- `dimension_1`, `dimension_2`, `dimension_3`: breakdown dimensions.
|
|
99
|
+
|
|
100
|
+
#### Dimension Options
|
|
101
|
+
`Browser`, `Device`, `Country`, `OS`, `Source`, `Medium`, `Campaign`, `Channel`, `URL`.
|
|
102
|
+
|
|
103
|
+
## Dynamic Tool Selection
|
|
104
|
+
|
|
105
|
+
Each tool domain is gated behind an env toggle so deployments can trim their surface:
|
|
106
|
+
|
|
107
|
+
| Toggle | Default | Domain |
|
|
108
|
+
|--------|---------|--------|
|
|
109
|
+
| `INSIGHTSTOOL` | `True` | `clarity_insights` |
|
|
110
|
+
|
|
111
|
+
## Environment Variables
|
|
112
|
+
|
|
113
|
+
All runtime configuration is supplied via environment variables (or a `.env`
|
|
114
|
+
file — see [`.env.example`](.env.example)). Never commit real tokens.
|
|
115
|
+
|
|
116
|
+
### Clarity credentials
|
|
117
|
+
|
|
118
|
+
| Variable | Default | Description |
|
|
119
|
+
|----------|---------|-------------|
|
|
120
|
+
| `CLARITY_URL` | `https://www.clarity.ms` | Base URL of the Microsoft Clarity instance. |
|
|
121
|
+
| `CLARITY_TOKEN` | _(none)_ | Bearer API token generated in the Clarity project settings. Required unless OIDC delegation is enabled. |
|
|
122
|
+
| `CLARITY_SSL_VERIFY` | `True` | Whether to verify TLS certificates when calling the Clarity API. |
|
|
123
|
+
|
|
124
|
+
### MCP server / transport
|
|
125
|
+
|
|
126
|
+
| Variable | Default | Description |
|
|
127
|
+
|----------|---------|-------------|
|
|
128
|
+
| `TRANSPORT` | `stdio` | MCP transport: `stdio`, `streamable-http`, or `sse`. |
|
|
129
|
+
| `HOST` | `0.0.0.0` | Bind host for HTTP transports. |
|
|
130
|
+
| `PORT` | `8000` | Bind port for HTTP transports. |
|
|
131
|
+
| `AUTH_TYPE` | `none` | MCP server auth scheme inherited from `agent-utilities` (e.g. `none`, `oidc`). |
|
|
132
|
+
| `FASTMCP_LOG_LEVEL` | `ERROR` | FastMCP log verbosity. Set to `ERROR` at startup to suppress log spam. |
|
|
133
|
+
| `INSIGHTSTOOL` | `True` | Toggle registration of the `clarity_insights` tool (see [Dynamic Tool Selection](#dynamic-tool-selection)). |
|
|
134
|
+
|
|
135
|
+
### Telemetry & access governance
|
|
136
|
+
|
|
137
|
+
| Variable | Default | Description |
|
|
138
|
+
|----------|---------|-------------|
|
|
139
|
+
| `ENABLE_OTEL` | `True` | Enable OpenTelemetry export of traces/metrics. |
|
|
140
|
+
| `EUNOMIA_TYPE` | `none` | Eunomia authorization mode: `none`, `embedded`, or `remote`. |
|
|
141
|
+
| `EUNOMIA_POLICY_FILE` | `mcp_policies.json` | Path to the local Eunomia policy file (embedded mode). |
|
|
142
|
+
|
|
143
|
+
### Build / terminal (set automatically — usually no action needed)
|
|
144
|
+
|
|
145
|
+
| Variable | Default | Description |
|
|
146
|
+
|----------|---------|-------------|
|
|
147
|
+
| `UV_COMPILE_BYTECODE` | `1` | Set in the Docker image to precompile bytecode for faster cold starts. |
|
|
148
|
+
| `NO_COLOR` / `TERM` | `1` / `dumb` | Terminal-control variables set at MCP startup to keep stdio transport output machine-clean. Not app configuration — listed for completeness. |
|
|
149
|
+
|
|
150
|
+
## Configuration
|
|
151
|
+
|
|
152
|
+
### stdio (local agent integration)
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"mcpServers": {
|
|
157
|
+
"clarity-api": {
|
|
158
|
+
"command": "uv",
|
|
159
|
+
"args": ["run", "--with", "clarity-api", "clarity-mcp"],
|
|
160
|
+
"env": {
|
|
161
|
+
"CLARITY_URL": "https://www.clarity.ms",
|
|
162
|
+
"CLARITY_TOKEN": "<YOUR_CLARITY_TOKEN>"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Streamable HTTP
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
export CLARITY_URL=https://www.clarity.ms
|
|
173
|
+
export CLARITY_TOKEN=<your-clarity-token>
|
|
174
|
+
clarity-mcp --transport streamable-http --host 0.0.0.0 --port 8000
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Docker
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
docker pull knucklessg1/clarity-api:latest
|
|
181
|
+
docker compose -f docker/mcp.compose.yml up -d
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Agent
|
|
185
|
+
|
|
186
|
+
The `clarity-agent` entry point (`clarity_api/agent_server.py`) starts a
|
|
187
|
+
Pydantic-AI A2A server that auto-discovers the MCP tools and exposes an AG-UI web
|
|
188
|
+
interface.
|
|
189
|
+
|
|
190
|
+
### Run locally
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
clarity-agent --web --provider openai --model-id gpt-4o
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The agent reads its identity from `clarity_api/agent_data/IDENTITY.md` and discovers
|
|
197
|
+
tools via `mcp_config.json`.
|
|
198
|
+
|
|
199
|
+
### Deploy with Docker Compose
|
|
200
|
+
|
|
201
|
+
`docker/agent.compose.yml` runs the MCP server and the agent server side by side;
|
|
202
|
+
the agent connects to the MCP server over `MCP_URL`:
|
|
203
|
+
|
|
204
|
+
```yaml
|
|
205
|
+
services:
|
|
206
|
+
clarity-api-mcp:
|
|
207
|
+
image: knucklessg1/clarity-api:latest
|
|
208
|
+
restart: always
|
|
209
|
+
env_file: [ ../.env ]
|
|
210
|
+
environment:
|
|
211
|
+
- HOST=0.0.0.0
|
|
212
|
+
- PORT=8000
|
|
213
|
+
- TRANSPORT=streamable-http
|
|
214
|
+
ports: [ "8000:8000" ]
|
|
215
|
+
|
|
216
|
+
clarity-api-agent:
|
|
217
|
+
image: knucklessg1/clarity-api:latest
|
|
218
|
+
restart: always
|
|
219
|
+
depends_on: [ clarity-api-mcp ]
|
|
220
|
+
command: [ "clarity-agent" ]
|
|
221
|
+
env_file: [ ../.env ]
|
|
222
|
+
environment:
|
|
223
|
+
- HOST=0.0.0.0
|
|
224
|
+
- PORT=9017
|
|
225
|
+
- MCP_URL=http://clarity-api-mcp:8000/mcp
|
|
226
|
+
- PROVIDER=${PROVIDER:-openai}
|
|
227
|
+
- MODEL_ID=${MODEL_ID:-gpt-4o}
|
|
228
|
+
- ENABLE_WEB_UI=True
|
|
229
|
+
- ENABLE_OTEL=True
|
|
230
|
+
ports: [ "9017:9017" ]
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
docker compose -f docker/agent.compose.yml up -d
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Usage (Python client)
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
#!/usr/bin/python
|
|
241
|
+
# coding: utf-8
|
|
242
|
+
import clarity_api
|
|
243
|
+
|
|
244
|
+
token = "<TOKEN>"
|
|
245
|
+
url = "https://www.clarity.ms"
|
|
246
|
+
client = clarity_api.Api(url=url, token=token)
|
|
247
|
+
|
|
248
|
+
response = client.get_data_export(number_of_days=2, dimension_1="OS", dimension_2="Channel")
|
|
249
|
+
print("Status Code:", response.status_code)
|
|
250
|
+
print("JSON Output:", response.json())
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Security & Governance
|
|
254
|
+
|
|
255
|
+
`clarity-api` inherits enterprise infrastructure from `agent-utilities`: JWT/OIDC
|
|
256
|
+
authentication, OpenTelemetry instrumentation, HashiCorp Vault secret resolution,
|
|
257
|
+
append-only audit logging (agent-utilities `OS-5.4`), prompt-injection defense
|
|
258
|
+
(`OS-5.1`), and the guardrail engine (`OS-5.3`). The connector stays
|
|
259
|
+
inactive until `CLARITY_URL` and `CLARITY_TOKEN` are configured. Never commit `.env`
|
|
260
|
+
files or tokens.
|
|
261
|
+
|
|
262
|
+
## Installation
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
python -m pip install "clarity-api[all]"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
| Extra | Use for |
|
|
269
|
+
|-------|---------|
|
|
270
|
+
| _(none)_ | the `Api` client |
|
|
271
|
+
| `mcp` | the `clarity-mcp` MCP server |
|
|
272
|
+
| `agent` | the `clarity-agent` A2A agent |
|
|
273
|
+
| `all` | everything |
|
|
274
|
+
|
|
275
|
+
### Obtaining Access Tokens
|
|
276
|
+
**Note**: Only project admins can manage access tokens.
|
|
277
|
+
|
|
278
|
+
1. Go to your Clarity project. Select `Settings` → `Data Export` → `Generate new API token`.
|
|
279
|
+
2. Provide a descriptive name for the token for easy identification.
|
|
280
|
+
|
|
281
|
+
## Documentation
|
|
282
|
+
|
|
283
|
+
- [Documentation site](https://knuckles-team.github.io/clarity-api/)
|
|
284
|
+
- [Overview](docs/overview.md)
|
|
285
|
+
- [Installation](docs/installation.md)
|
|
286
|
+
- [Usage](docs/usage.md)
|
|
287
|
+
- [Deployment](docs/deployment.md)
|
|
288
|
+
- [Concepts](docs/concepts.md)
|
|
289
|
+
|
|
290
|
+
## Contributing
|
|
291
|
+
|
|
292
|
+
Contributions are welcome. Run quality checks before pushing:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
pre-commit run --all-files
|
|
296
|
+
python -m pytest -q
|
|
297
|
+
```
|