chron-mcp 0.1.20 → 0.1.25

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "chron",
3
3
  "description": "Audit-grade timestamped logs for every AI conversation — stored locally, owned by you.",
4
- "version": "0.1.20",
4
+ "version": "0.1.24",
5
5
  "author": {
6
6
  "name": "Nivaya"
7
7
  },
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  <div align="center">
2
2
  <img src="assets/chron-icon-png-transperent.png" alt="Chron" width="96" />
3
3
  <h1>Chron</h1>
4
- <p>A timestamped audit trail for every AI conversation stored locally, owned by you.</p>
4
+ <p>Local-first, tamper-evident audit trails for AI conversations, tool calls, code changes, and secrets.</p>
5
5
  </div>
6
6
 
7
- AI tools show when you sent a message. Chron logs when the AI responded too — and keeps a permanent, queryable record of every exchange across every tool you use.
7
+ AI tools show when you sent a message. Chron logs when the AI responded too — and keeps a permanent, queryable, tamper-evident record of the AI work happening across your tools.
8
8
 
9
9
  Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP-compatible AI tool.
10
10
 
@@ -16,9 +16,29 @@ AI tools produce no audit trail by default. You cannot answer:
16
16
  - What did the AI say, and when exactly?
17
17
  - How long did the AI take to respond?
18
18
  - What was the full conversation that produced this output?
19
+ - Which tool calls, command results, and code diffs happened during the session?
20
+ - Did a secret or credential get pasted into an AI prompt?
21
+ - Has this audit record been edited after the fact?
19
22
  - What did I ask Claude last week about this codebase?
20
23
 
21
- Chron fixes that. Every exchange is logged with a precise local datetime (including timezone offset) to a SQLite file you own. No cloud, no vendor lock-in, no data leaving your machine.
24
+ Chron fixes that. Every exchange is logged with a precise local datetime (including timezone offset) to a SQLite file you own. It can hash-chain every event, sign sessions with Ed25519, detect secrets/PII, produce SOC 2 evidence, and stream metadata-only events to your SIEM. No cloud, no vendor lock-in, no message content leaving your machine.
25
+
26
+ ---
27
+
28
+ ## What Chron captures
29
+
30
+ Chron stores a local audit trail of:
31
+
32
+ - User and assistant messages
33
+ - Tool calls and tool results
34
+ - Code changes with file path, operation, and unified diff
35
+ - Session start/resume metadata, including parent session and external refs
36
+ - Secret/PII detections with masked values
37
+ - Hash-chain integrity data
38
+ - Optional Ed25519 session signatures
39
+ - Optional NTP clock attestation metadata
40
+
41
+ Chron's SIEM integrations send only metadata: session starts, role-only message events, and masked secret detections. Message content and raw secret values stay local.
22
42
 
23
43
  ---
24
44
 
@@ -49,6 +69,18 @@ npm install -g chron-mcp
49
69
 
50
70
  First run creates `~/.chron/chron.db` automatically. No database setup, no env vars, no migrations.
51
71
 
72
+ Check your setup:
73
+
74
+ ```bash
75
+ chron doctor
76
+ ```
77
+
78
+ For CI or automation:
79
+
80
+ ```bash
81
+ chron doctor --json
82
+ ```
83
+
52
84
  ---
53
85
 
54
86
  ## CLI
@@ -65,18 +97,57 @@ Commands:
65
97
  secrets List detected secrets across sessions
66
98
  settings View current configuration
67
99
  connect Connect to a SIEM integration (crowdstrike, sentinel, splunk)
100
+ summary Structured summary of a session (timeline, mutations, secrets)
101
+ sign Sign a session with its Ed25519 key — produces a .chron.sig file
102
+ verify Verify a session's hash chain and Ed25519 signature
103
+ prune Delete sessions older than a retention cutoff
104
+ doctor Check your Chron setup — Node version, DB, MCP configs, SIEM
68
105
 
69
106
  Options (history):
70
107
  --limit=<n> Max sessions to show (default: 20)
108
+ --ref=<value> Filter by external_ref prefix (e.g. --ref=jira:ENG-123)
71
109
  <id-prefix> Show full log for the session with this ID prefix
72
110
 
73
111
  Options (report):
74
- --since=<range> Filter by date: 7d, 30d, or YYYY-MM-DD (default: all time)
75
-
76
- Options (export / secrets):
77
- <id-prefix> Scope to a single session
112
+ --since=<range> Filter by date: 7d, 30d, or YYYY-MM-DD (default: all time)
113
+ --format=soc2 Generate SOC 2 HTML evidence package
114
+ --output=<file> Output file for --format=soc2
115
+
116
+ Options (export):
117
+ <id-prefix> Markdown export for a single session
118
+ --signed Tamper-evident bundle (JSONL + manifest + Ed25519 sig)
119
+ --session=<id> Filter bundle to a single session
120
+ --since=<range> Filter bundle by date: 7d, 30d, or YYYY-MM-DD
121
+ --output=<file> Output path (default: bundle.chron.tar.gz)
122
+
123
+ Options (verify):
124
+ <id-prefix> Verify a session's hash chain + Ed25519 signature
125
+ --bundle=<file> Verify a signed bundle offline (no DB needed)
126
+
127
+ Options (prune):
128
+ --older-than=<n>d Cutoff in days (falls back to retention_days in config)
129
+ --dry-run Show what would be deleted without deleting
130
+ --confirm Required flag to actually delete
131
+
132
+ Options (doctor):
133
+ --json Machine-readable JSON output
78
134
  ```
79
135
 
136
+ ### `chron doctor`
137
+
138
+ `chron doctor` validates the pieces that make Chron useful in real life:
139
+
140
+ - Node.js version (v18+ required)
141
+ - Local Chron version vs npm latest
142
+ - `npx chron-mcp --version`
143
+ - DB directory and key directory write access
144
+ - Claude Desktop, Claude Code, Cursor, and Windsurf MCP config presence
145
+ - Whether Chron is configured in each MCP client
146
+ - Optional HTTP mode health check on `/health`
147
+ - Splunk, Sentinel, and LogScale configuration via env vars or `~/.chron/config.json`
148
+
149
+ Warnings for optional integrations do not fail the command. Real failures exit with code `1`.
150
+
80
151
  ---
81
152
 
82
153
  ## What it logs
@@ -186,21 +257,26 @@ Chron ships with `skills/chron.skill.md` — a plain-text instruction file that
186
257
  | `init_session` | Initialize or resume a session — returns session_id, message count, and recent messages in one call |
187
258
  | `start_session` | Create a new named audit session (legacy — prefer `init_session`) |
188
259
  | `log_message` | Record a single message with the current local datetime |
260
+ | `log_tool_call` | Record an AI tool invocation as an audit event |
261
+ | `log_tool_result` | Record tool output and link it to a tool call |
262
+ | `log_code_change` | Record a file edit with operation and unified diff |
189
263
  | `log_exchange` | Log a user/assistant pair atomically (for batch imports) |
190
264
  | `list_sessions` | List all sessions ordered by most recently active |
191
265
  | `get_session_history` | Retrieve the full timestamped log for a session |
192
266
  | `verify_session` | Verify the tamper-evident hash chain — detects any post-log edits |
193
267
  | `scan_prompt` | Scan text for secrets (API keys, credentials) before logging — returns masked detections |
194
268
  | `rehydrate_response` | Restore redacted placeholders in an assistant response back to their original values |
269
+ | `delete_session` | Delete a session and cascade its messages/secrets |
270
+ | `summarize_session` | Return a timeline summary with latency, mutations, secrets, and prod references |
195
271
 
196
272
  ---
197
273
 
198
- ## Tamper-evident hash chaining
274
+ ## Integrity and signing
199
275
 
200
- Every message is linked to the previous one via a SHA-256 chain:
276
+ Every new audit event is linked to the previous one via a SHA-256 chain:
201
277
 
202
278
  ```
203
- content_hash = SHA256(session_id | role | content | created_at | prev_hash)
279
+ content_hash = SHA256(session_id | role | content | created_at | prev_hash | event_type)
204
280
  ```
205
281
 
206
282
  `verify_session` walks the chain and returns:
@@ -209,6 +285,58 @@ content_hash = SHA256(session_id | role | content | created_at | prev_hash)
209
285
 
210
286
  This turns your local log into a verifiable audit artifact. Any edit to a stored message — content, timestamp, or role — breaks the chain and is detected immediately.
211
287
 
288
+ Chron also generates an Ed25519 keypair per new session when possible. The private key stays under `~/.chron/keys`. Use:
289
+
290
+ ```bash
291
+ chron sign <session-id-prefix>
292
+ chron verify <session-id-prefix>
293
+ ```
294
+
295
+ For portable evidence:
296
+
297
+ ```bash
298
+ chron export --signed --session=<session-id-prefix> --output=evidence.chron.tar.gz
299
+ chron verify --bundle=evidence.chron.tar.gz
300
+ ```
301
+
302
+ `chron verify` also reports NTP clock attestation metadata for sessions created with clock-check support.
303
+
304
+ ---
305
+
306
+ ## Secrets and PII detection
307
+
308
+ Chron can detect and mask:
309
+
310
+ - API keys: OpenAI, Anthropic, AWS, Google, GitHub, Slack, Stripe, SendGrid, HuggingFace
311
+ - Private keys, JWTs, URL credentials, password assignments, env-style secrets
312
+ - Credit cards, IBANs, SSNs, DOBs, passports
313
+ - Email addresses, US/E.164 phone numbers, internal RFC-1918 IPs
314
+
315
+ Use:
316
+
317
+ ```bash
318
+ chron secrets
319
+ chron secrets <session-id-prefix>
320
+ ```
321
+
322
+ MCP tools can also call `scan_prompt` before sending content to an AI tool. Redaction uses `$CHRON_*` placeholders and `rehydrate_response` can restore values from the returned token map.
323
+
324
+ ---
325
+
326
+ ## Reports and evidence
327
+
328
+ ```bash
329
+ chron history
330
+ chron summary <session-id-prefix>
331
+ chron report --since=30d
332
+ chron report --format=soc2 --output=soc2-report.html
333
+ chron export <session-id-prefix>
334
+ chron export --signed --since=30d --output=bundle.chron.tar.gz
335
+ chron prune --older-than=90d --dry-run
336
+ ```
337
+
338
+ The SOC 2 report and signed bundles are designed for audit review, legal hold, and incident reconstruction without sending conversation content to Chron infrastructure.
339
+
212
340
  ---
213
341
 
214
342
  ## CrowdStrike LogScale integration
@@ -484,6 +612,7 @@ All six must be set for events to flow. Token refresh is automatic (1-hour Azure
484
612
  | `CHRON_SENTINEL_STREAM` | _(none)_ | Stream name (e.g. `Custom-ChronEvents_CL`) |
485
613
  | `CHRON_SPLUNK_URL` | _(none)_ | Splunk HEC base URL (enables Splunk integration) |
486
614
  | `CHRON_SPLUNK_TOKEN` | _(none)_ | Splunk HEC ingest token |
615
+ | `CHRON_SPLUNK_INSECURE` | _(none)_ | Set to `1` to skip TLS verification for local Splunk/self-signed certs |
487
616
  | `CHRON_RELAY_URL` | _(none)_ | Generic relay endpoint (any SIEM or webhook) |
488
617
  | `CHRON_RELAY_TOKEN` | _(none)_ | Bearer token for generic relay |
489
618
 
@@ -73,7 +73,7 @@ The dashboard includes five widgets:
73
73
  - **AI Tool Usage** — breakdown by tool (Claude, Cursor, Windsurf, etc.)
74
74
  - **Secrets Detected by Type** — credential exposures over time
75
75
  - **Sessions by Developer** — per-machine session count with AI tool
76
- - **Credential Exposures** — full table of api_key, jwt, aws_key detections for SOC review
76
+ - **Credential Exposures** — full table of API keys, tokens, passwords, and private-key detections for SOC review
77
77
 
78
78
  ## Step 6 — Set up the API key alert (optional)
79
79
 
@@ -81,7 +81,7 @@ In LogScale, create a **Scheduled Search** using `api-key-alert.lql`:
81
81
 
82
82
  ```
83
83
  event_type = "secret_detected"
84
- | detection_type in ["api_key", "aws_key", "gcp_key", "azure_key", "private_key", "jwt"]
84
+ | detection_type in ["private_key", "aws_access_key", "anthropic_api_key", "openai_api_key", "google_api_key", "github_token", "slack_token", "stripe_key", "sendgrid_key", "huggingface_token", "jwt", "url_credentials", "password", "credential_pair"]
85
85
  | table([#host, ai_tool, detection_type, masked_value, session_id_prefix, @timestamp])
86
86
  ```
87
87
 
@@ -104,7 +104,7 @@ All events arrive in LogScale with:
104
104
  | `os` | All events: `darwin`, `linux`, `win32` |
105
105
  | `chron_version` | All events |
106
106
  | `role` | `message_logged` only: `user` or `assistant` |
107
- | `detection_type` | `secret_detected` only: `api_key`, `aws_key`, `jwt`, etc. |
107
+ | `detection_type` | `secret_detected` only: `openai_api_key`, `aws_access_key`, `github_token`, `jwt`, etc. |
108
108
  | `masked_value` | `secret_detected` only: e.g. `AKIA****F3K2` |
109
109
 
110
110
  **What is never transmitted:** message content, actual secret values, file paths, or any user-typed text.
@@ -1,5 +1,5 @@
1
1
  // Alert: API key or credential sent to AI tool
2
2
  // Use as a Scheduled Search alert — notify SOC on any match
3
3
  event_type = "secret_detected"
4
- | detection_type in ["api_key", "aws_key", "gcp_key", "azure_key", "private_key", "jwt"]
4
+ | detection_type in ["private_key", "aws_access_key", "anthropic_api_key", "openai_api_key", "google_api_key", "github_token", "slack_token", "stripe_key", "sendgrid_key", "huggingface_token", "jwt", "url_credentials", "password", "credential_pair"]
5
5
  | table([#host, ai_tool, detection_type, masked_value, session_id_prefix, @timestamp])
@@ -62,5 +62,5 @@ widgets:
62
62
  height: 4
63
63
  query: |
64
64
  event_type = "secret_detected"
65
- | detection_type in ["api_key", "aws_key", "gcp_key", "azure_key", "private_key", "jwt"]
65
+ | detection_type in ["private_key", "aws_access_key", "anthropic_api_key", "openai_api_key", "google_api_key", "github_token", "slack_token", "stripe_key", "sendgrid_key", "huggingface_token", "jwt", "url_credentials", "password", "credential_pair"]
66
66
  | table([#host, ai_tool, detection_type, masked_value, session_id_prefix, @timestamp])
@@ -113,7 +113,7 @@ All events arrive in `ChronEvents_CL` with:
113
113
  | `ChronVersion` | All events |
114
114
  | `Computer` | All events: developer's machine hostname |
115
115
  | `Role` | `message_logged` only: `user` or `assistant` |
116
- | `DetectionType` | `secret_detected` only: `api_key`, `aws_key`, `jwt`, etc. |
116
+ | `DetectionType` | `secret_detected` only: `openai_api_key`, `aws_access_key`, `github_token`, `jwt`, etc. |
117
117
  | `MaskedValue` | `secret_detected` only: e.g. `AKIA****F3K2` |
118
118
 
119
119
  **What is never transmitted:** message content, actual secret values, file paths, or any user-typed text.
@@ -3,5 +3,5 @@
3
3
  ChronEvents_CL
4
4
  | where TimeGenerated > ago(1h)
5
5
  | where EventType == "secret_detected"
6
- | where DetectionType in ("api_key", "aws_key", "gcp_key", "azure_key", "private_key", "jwt")
6
+ | where DetectionType in ("private_key", "aws_access_key", "anthropic_api_key", "openai_api_key", "google_api_key", "github_token", "slack_token", "stripe_key", "sendgrid_key", "huggingface_token", "jwt", "url_credentials", "password", "credential_pair")
7
7
  | project TimeGenerated, Computer, AiTool, DetectionType, MaskedValue, SessionIdPrefix
@@ -2,6 +2,6 @@
2
2
  ChronEvents_CL
3
3
  | where TimeGenerated > ago(30d)
4
4
  | where EventType == "secret_detected"
5
- | where DetectionType in ("api_key", "aws_key", "gcp_key", "azure_key", "private_key", "jwt")
5
+ | where DetectionType in ("private_key", "aws_access_key", "anthropic_api_key", "openai_api_key", "google_api_key", "github_token", "slack_token", "stripe_key", "sendgrid_key", "huggingface_token", "jwt", "url_credentials", "password", "credential_pair")
6
6
  | project TimeGenerated, Computer, AiTool, DetectionType, MaskedValue, SessionIdPrefix
7
7
  | sort by TimeGenerated desc
@@ -122,7 +122,7 @@ All events arrive with `sourcetype=chron:event` and these fields:
122
122
  | `os` | All events: `darwin`, `linux`, `win32` |
123
123
  | `chron_version` | All events |
124
124
  | `role` | `message_logged` only: `user` or `assistant` |
125
- | `detection_type` | `secret_detected` only: `api_key`, `aws_key`, `jwt`, etc. |
125
+ | `detection_type` | `secret_detected` only: `openai_api_key`, `aws_access_key`, `github_token`, `jwt`, etc. |
126
126
  | `masked_value` | `secret_detected` only: e.g. `AKIA****F3K2` |
127
127
 
128
128
  **What is never transmitted:** message content, actual secret values, file paths, or any user-typed text.
@@ -1,3 +1,3 @@
1
1
  sourcetype="chron:event" event_type="secret_detected" earliest=-1h
2
- | where detection_type IN ("api_key","aws_key","gcp_key","azure_key","private_key","jwt")
2
+ | where detection_type IN ("private_key","aws_access_key","anthropic_api_key","openai_api_key","google_api_key","github_token","slack_token","stripe_key","sendgrid_key","huggingface_token","jwt","url_credentials","password","credential_pair")
3
3
  | table _time, host, ai_tool, detection_type, masked_value, session_id_prefix
@@ -1,4 +1,4 @@
1
1
  sourcetype="chron:event" event_type="secret_detected" earliest=-30d
2
- | where detection_type IN ("api_key","aws_key","gcp_key","azure_key","private_key","jwt")
2
+ | where detection_type IN ("private_key","aws_access_key","anthropic_api_key","openai_api_key","google_api_key","github_token","slack_token","stripe_key","sendgrid_key","huggingface_token","jwt","url_credentials","password","credential_pair")
3
3
  | table _time, host, ai_tool, detection_type, masked_value, session_id_prefix
4
4
  | sort -_time