Identity & auth
mcp_audit
Every MCP tool call: who (grant / dancer / app), which tool, what for (`target`: a profile handle or event id), a hash of the input (never the input), the outcome and how long it took. `confirmNonce` makes a publish confirmation single use.
Columns
| Column | Type | Null | Default | Keys |
|---|---|---|---|---|
| id | uuid | no | gen_random_uuid() | PK |
| grant_id | uuid | yes | — | |
| dancer_id | uuid | yes | — | |
| client_id | text | yes | — | |
| tool | text | no | — | |
| target | text | yes | — | |
| profile_id | uuid | yes | — | |
| input_hash | text | no | — | |
| result | text okerrorpreviewdenied | no | — | |
| error_code | text | yes | — | |
| latency_ms | integer | yes | — | |
| confirm_nonce | text | yes | — | unique |
| created_at | timestamp | no | now() |
Value lists come from .$type<'a' | 'b'>() in the schema — enforced in TypeScript only, not by the database.
Keys, constraints & indexes
Unique
- (confirm_nonce) mcp_audit_confirm_nonce_unique
Indexes
- (grant_id, created_at)mcp_audit_grant_idx
- (profile_id, created_at)mcp_audit_profile_idx
Foreign keys
- grant_id → oauth_grants.id on delete set null
- dancer_id → dancers.id on delete set null
- profile_id → profiles.id on delete set null
Used by
Code that reads or writes this table, found by static analysis of the tRPC routers and API handlers (including helpers they call).
tRPC procedures
REST & webhooks
- ANY /mcp
- ANY /mcp/public
Relations
Rendering diagram…
Diagram source
erDiagram
dancers {
uuid id PK
text email UK
text neon_auth_id UK
text username UK
}
mcp_audit {
uuid id PK
uuid grant_id FK
uuid dancer_id FK
uuid profile_id FK
text confirm_nonce UK
}
oauth_grants {
uuid id PK
uuid dancer_id FK
text client_id FK
}
profiles {
uuid id PK
text username UK
}
oauth_grants |o--o{ mcp_audit : "grant_id"
dancers |o--o{ mcp_audit : "dancer_id"
profiles |o--o{ mcp_audit : "profile_id"
dancers ||--o{ oauth_grants : "dancer_id" Defined at server/database/schema.ts:1406 as mcpAudit.