Connecting Cursor to Agent Trust Hub
Bigeye can receive agent activity directly from Cursor and show each chat session under Agent Trust, the same way it does for Claude Code. Once configured, every prompt, tool call, and response from Cursor's agent becomes a conversation with turn-by-turn detail, including which files, commands, and MCP resources each turn touched. BigQuery queries are parsed into the tables and columns they read, and MCP resources (Google Drive files, GitHub files, and so on) are resolved to readable names.
No separate forwarder or proxy is required. Cursor's hooks send data straight to Bigeye.
How this differs from Claude Code
Cursor has no OpenTelemetry exporter for agent activity, so hooks are the only source and there is no OTLP setup. Token counts come from Cursor's stop hook. Cursor doesn't report cost, so the cost column stays empty and the UI shows the token count instead.
What you'll see in Bigeye
- Agent Trust → Agents: one Cursor agent that all of your organization's Cursor activity rolls up under, not one row per user.
- Agent detail → Conversations: one row per Cursor chat session, showing the initial prompt, total tokens, and the user who ran it.
- Conversation detail: one turn per prompt/response pair, with the tools Cursor used in that turn and every resource it touched.
Prerequisites
- A personal API key, generated from Profile → API Keys in Bigeye. The key's owner needs edit rights on the workspace.
- Your workspace ID, visible in the URL of any Bigeye page (
.../w/<workspace-id>/...). - Cursor support enabled for your workspace. It is off by default during rollout; ask your Bigeye contact to turn it on. Until it is on, Bigeye accepts the hooks but stores nothing.
The steps below target https://app.bigeye.com. If you're on a dedicated instance or self-hosted Bigeye, see Dedicated instance or self-hosted.
Setup
Cursor loads hooks.json from four locations, highest priority first:
| Tier | Location | Who controls it |
|---|---|---|
| Enterprise | /Library/Application Support/Cursor/hooks.json (macOS), /etc/cursor/hooks.json (Linux/WSL), C:\ProgramData\Cursor\hooks.json (Windows) | IT, via MDM |
| Team | Cursor dashboard (Enterprise plans) | Cursor admins |
| Project | <repo>/.cursor/hooks.json | Whoever commits to the repo |
| User | ~/.cursor/hooks.json | The individual developer |
For an organization-wide rollout, use the Enterprise or Team tier. Those are managed centrally, and developers can't turn them off. The Project and User tiers are fine for trying the integration on one machine.
Create hooks.json at your chosen location:
{
"version": 1,
"hooks": {
"beforeSubmitPrompt": [{ "command": "/usr/local/bin/bigeye-cursor-hook.sh", "timeout": 5 }],
"postToolUse": [{ "command": "/usr/local/bin/bigeye-cursor-hook.sh", "timeout": 5 }],
"afterAgentResponse": [{ "command": "/usr/local/bin/bigeye-cursor-hook.sh", "timeout": 5 }],
"stop": [{ "command": "/usr/local/bin/bigeye-cursor-hook.sh", "timeout": 5 }],
"afterMCPExecution": [{ "command": "/usr/local/bin/bigeye-cursor-hook.sh", "timeout": 5 }]
}
}Then create the script it points at, /usr/local/bin/bigeye-cursor-hook.sh, and make it executable with chmod +x:
#!/bin/sh
# Forwards the Cursor hook payload on stdin to Bigeye and relays Bigeye's response
# to Cursor on stdout (Cursor reads the hook's stdout as its decision). Never fails
# the agent: if the request fails for any reason, the hook answers "allow" itself.
curl -fs --max-time 2 -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: apikey $BIGEYE_API_KEY" \
-H "x-bigeye-workspace-id: $BIGEYE_WORKSPACE_ID" \
--data-binary @- \
https://app.bigeye.com/api/v1/cursor/hooks 2>/dev/null \
|| echo '{"permission":"allow","continue":true}'
exit 0Set BIGEYE_API_KEY and BIGEYE_WORKSPACE_ID in the environment Cursor runs in: your shell profile for the User tier, or the MDM profile for a managed rollout. Restart Cursor, since hooks are only read at startup.
What each hook does
| Hook | Purpose |
|---|---|
beforeSubmitPrompt | Opens the turn and sends your prompt text. |
postToolUse | Records every tool call. Shell, Read, Write, Grep, Delete, Task, and MCP tools all arrive through this one hook. |
afterAgentResponse | Sends the assistant's reply for the turn. |
stop | Sends the turn's token counts. |
afterMCPExecution | Optional. Adds the MCP server's name, so a server such as bigquery or github is identified even when the tool name alone is ambiguous. It enriches the call postToolUse already recorded and doesn't count it twice. |
Don't also wirepreToolUseorafterShellExecutionThey fire for the same tool calls as
postToolUse, so wiring them too double-counts every tool call.
Dedicated instance or self-hosted
Replace https://app.bigeye.com in the hook script with your Bigeye host, for example https://<tenant>.bigeye.com.
Verify it works
- Start a new Cursor chat and send any prompt.
- In Bigeye, go to Agent Trust. You should see a Cursor agent shared across the workspace.
- Open it and find your session under Conversations, with your email in the user column. Open the conversation and confirm the prompt and response appear as one turn, with any tool calls listed under Access detail.
If nothing shows up, see Troubleshooting below.
What's captured, what's not
Captured:
- Prompt text and the assistant's response for each turn, plus the model, Cursor version, and workspace root.
- Token totals from the
stophook, including prompt-cache reads and writes alongside uncached input and output. - Every tool call: file reads/writes, shell commands, and MCP calls.
- BigQuery MCP queries, parsed into the tables and columns the SQL touched and linked to the matching Bigeye datasets, so the access rolls up under the right asset along with its monitors and issues.
- MCP calls to known systems (Google Drive, GitHub, Google Calendar) resolved to readable names and links.
Not captured:
- Cost. Cursor doesn't report cost per conversation, so the UI shows the token count instead.
- File contents. Only paths, URLs, and metadata are recorded.
- Shell command arguments. Only the program name is stored (
git, notgit commit -m "..."), because arguments often contain file paths, search terms, and secrets. The exception is recognized data CLIs, where the objects the command touched are recorded instead. - Cursor's own reads of its terminal buffer while a command runs.
- Tab (inline completion) activity and Cursor CLI (
cursor-agent) sessions, which don't fire prompt/response hooks.
Troubleshooting
No agent appears in Bigeye
-
Confirm Cursor support is enabled for your workspace.
-
Check that your API key is valid for the workspace:
curl -f -X POST -H 'Content-Type: application/json' -H "Authorization: apikey $BIGEYE_API_KEY" -H "x-bigeye-workspace-id: $BIGEYE_WORKSPACE_ID" -d '{}' https://app.bigeye.com/api/v1/agent-conversations/listThis should return HTTP 200.
-
Restart Cursor — hooks only reload at startup.
Hooks silently fail
-
Test the endpoint directly:
echo '{"conversation_id":"test","generation_id":"t1","hook_event_name":"beforeSubmitPrompt","prompt":"hi"}' | curl -X POST -H 'Content-Type: application/json' -H "Authorization: apikey $BIGEYE_API_KEY" -H "x-bigeye-workspace-id: $BIGEYE_WORKSPACE_ID" --data-binary @- https://app.bigeye.com/api/v1/cursor/hooksThis should return
{"permission":"allow","continue":true}.
Does Bigeye ever block Cursor?
No. Bigeye only observes: it records what the agent did and always answers {"permission": "allow", "continue": true}. Malformed payloads and a workspace without Cursor support enabled get the same answer rather than an error, so even a hook configured with failClosed: true can't halt a developer's agent because of Bigeye. The only error Bigeye returns is for a rejected API key (unknown, or without edit rights on the workspace), and the script above still answers "allow" to Cursor in that case.
Updated about 2 hours ago
