@pcircle/footprint 1.1.1 → 1.2.0
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.
- package/README.md +165 -12
- package/SKILL.md +72 -15
- package/dist/src/analyzers/content-analyzer.d.ts +20 -0
- package/dist/src/analyzers/content-analyzer.d.ts.map +1 -0
- package/dist/src/analyzers/content-analyzer.js +169 -0
- package/dist/src/analyzers/content-analyzer.js.map +1 -0
- package/dist/src/index.d.ts +38 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +243 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/crypto/decrypt.d.ts.map +1 -0
- package/dist/{lib → src/lib}/crypto/decrypt.js +4 -0
- package/dist/src/lib/crypto/decrypt.js.map +1 -0
- package/dist/src/lib/crypto/encrypt.d.ts.map +1 -0
- package/dist/src/lib/crypto/encrypt.js.map +1 -0
- package/dist/{lib → src/lib}/crypto/index.d.ts +1 -1
- package/dist/src/lib/crypto/index.d.ts.map +1 -0
- package/dist/{lib → src/lib}/crypto/index.js +1 -1
- package/dist/src/lib/crypto/index.js.map +1 -0
- package/dist/{lib → src/lib}/crypto/key-derivation.d.ts +17 -3
- package/dist/src/lib/crypto/key-derivation.d.ts.map +1 -0
- package/dist/{lib → src/lib}/crypto/key-derivation.js +44 -3
- package/dist/src/lib/crypto/key-derivation.js.map +1 -0
- package/dist/src/lib/crypto/types.d.ts.map +1 -0
- package/dist/src/lib/crypto/types.js.map +1 -0
- package/dist/src/lib/errors/base-error.d.ts +15 -0
- package/dist/src/lib/errors/base-error.d.ts.map +1 -0
- package/dist/src/lib/errors/base-error.js +34 -0
- package/dist/src/lib/errors/base-error.js.map +1 -0
- package/dist/src/lib/errors/crypto-error.d.ts +29 -0
- package/dist/src/lib/errors/crypto-error.d.ts.map +1 -0
- package/dist/src/lib/errors/crypto-error.js +43 -0
- package/dist/src/lib/errors/crypto-error.js.map +1 -0
- package/dist/src/lib/errors/index.d.ts +26 -0
- package/dist/src/lib/errors/index.d.ts.map +1 -0
- package/dist/src/lib/errors/index.js +26 -0
- package/dist/src/lib/errors/index.js.map +1 -0
- package/dist/src/lib/errors/storage-error.d.ts +25 -0
- package/dist/src/lib/errors/storage-error.d.ts.map +1 -0
- package/dist/src/lib/errors/storage-error.js +38 -0
- package/dist/src/lib/errors/storage-error.js.map +1 -0
- package/dist/src/lib/errors/validation-error.d.ts +21 -0
- package/dist/src/lib/errors/validation-error.d.ts.map +1 -0
- package/dist/src/lib/errors/validation-error.js +29 -0
- package/dist/src/lib/errors/validation-error.js.map +1 -0
- package/dist/{lib → src/lib}/storage/database.d.ts +14 -2
- package/dist/src/lib/storage/database.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/database.js +65 -29
- package/dist/src/lib/storage/database.js.map +1 -0
- package/dist/src/lib/storage/export.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/export.js +16 -1
- package/dist/src/lib/storage/export.js.map +1 -0
- package/dist/{lib → src/lib}/storage/git.d.ts +1 -1
- package/dist/src/lib/storage/git.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/git.js +5 -2
- package/dist/src/lib/storage/git.js.map +1 -0
- package/dist/{lib → src/lib}/storage/index.d.ts +1 -0
- package/dist/src/lib/storage/index.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/index.js +1 -0
- package/dist/src/lib/storage/index.js.map +1 -0
- package/dist/src/lib/storage/salt-storage.d.ts +25 -0
- package/dist/src/lib/storage/salt-storage.d.ts.map +1 -0
- package/dist/src/lib/storage/salt-storage.js +66 -0
- package/dist/src/lib/storage/salt-storage.js.map +1 -0
- package/dist/src/lib/storage/schema.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/schema.js +22 -1
- package/dist/src/lib/storage/schema.js.map +1 -0
- package/dist/src/lib/storage/types.d.ts.map +1 -0
- package/dist/src/lib/storage/types.js.map +1 -0
- package/dist/src/lib/tool-response.d.ts +84 -0
- package/dist/src/lib/tool-response.d.ts.map +1 -0
- package/dist/src/lib/tool-response.js +91 -0
- package/dist/src/lib/tool-response.js.map +1 -0
- package/dist/src/lib/tool-wrapper.d.ts +45 -0
- package/dist/src/lib/tool-wrapper.d.ts.map +1 -0
- package/dist/src/lib/tool-wrapper.js +73 -0
- package/dist/src/lib/tool-wrapper.js.map +1 -0
- package/dist/{test-helpers.d.ts → src/test-helpers.d.ts} +4 -4
- package/dist/src/test-helpers.d.ts.map +1 -0
- package/dist/{test-helpers.js → src/test-helpers.js} +2 -2
- package/dist/src/test-helpers.js.map +1 -0
- package/dist/src/tools/capture-footprint.d.ts +29 -0
- package/dist/src/tools/capture-footprint.d.ts.map +1 -0
- package/dist/src/tools/capture-footprint.js +94 -0
- package/dist/src/tools/capture-footprint.js.map +1 -0
- package/dist/src/tools/delete-footprints.d.ts +22 -0
- package/dist/src/tools/delete-footprints.d.ts.map +1 -0
- package/dist/src/tools/delete-footprints.js +33 -0
- package/dist/src/tools/delete-footprints.js.map +1 -0
- package/dist/src/tools/export-footprints.d.ts +33 -0
- package/dist/src/tools/export-footprints.d.ts.map +1 -0
- package/dist/src/tools/export-footprints.js +50 -0
- package/dist/src/tools/export-footprints.js.map +1 -0
- package/dist/src/tools/get-footprint.d.ts +51 -0
- package/dist/src/tools/get-footprint.d.ts.map +1 -0
- package/dist/src/tools/get-footprint.js +66 -0
- package/dist/src/tools/get-footprint.js.map +1 -0
- package/dist/src/tools/get-tag-stats.d.ts +30 -0
- package/dist/src/tools/get-tag-stats.d.ts.map +1 -0
- package/dist/src/tools/get-tag-stats.js +33 -0
- package/dist/src/tools/get-tag-stats.js.map +1 -0
- package/dist/src/tools/index.d.ts +16 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +16 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/list-footprints.d.ts +57 -0
- package/dist/src/tools/list-footprints.d.ts.map +1 -0
- package/dist/src/tools/list-footprints.js +57 -0
- package/dist/src/tools/list-footprints.js.map +1 -0
- package/dist/src/tools/remove-tag.d.ts +22 -0
- package/dist/src/tools/remove-tag.d.ts.map +1 -0
- package/dist/src/tools/remove-tag.js +30 -0
- package/dist/src/tools/remove-tag.js.map +1 -0
- package/dist/src/tools/rename-tag.d.ts +24 -0
- package/dist/src/tools/rename-tag.d.ts.map +1 -0
- package/dist/src/tools/rename-tag.js +34 -0
- package/dist/src/tools/rename-tag.js.map +1 -0
- package/dist/src/tools/search-footprints.d.ts +60 -0
- package/dist/src/tools/search-footprints.d.ts.map +1 -0
- package/dist/src/tools/search-footprints.js +78 -0
- package/dist/src/tools/search-footprints.js.map +1 -0
- package/dist/src/tools/suggest-capture.d.ts +21 -0
- package/dist/src/tools/suggest-capture.d.ts.map +1 -0
- package/dist/src/tools/suggest-capture.js +37 -0
- package/dist/src/tools/suggest-capture.js.map +1 -0
- package/dist/src/tools/verify-footprint.d.ts +104 -0
- package/dist/src/tools/verify-footprint.d.ts.map +1 -0
- package/dist/src/tools/verify-footprint.js +102 -0
- package/dist/src/tools/verify-footprint.js.map +1 -0
- package/dist/{types.d.ts → src/types.d.ts} +1 -1
- package/dist/src/types.d.ts.map +1 -0
- package/dist/{lib/storage → src}/types.js.map +1 -1
- package/dist/src/ui/register.d.ts.map +1 -0
- package/dist/src/ui/register.js +94 -0
- package/dist/src/ui/register.js.map +1 -0
- package/dist/tests/error-handling.test.d.ts +2 -0
- package/dist/tests/error-handling.test.d.ts.map +1 -0
- package/dist/tests/error-handling.test.js +114 -0
- package/dist/tests/error-handling.test.js.map +1 -0
- package/dist/tests/fixtures.d.ts +87 -0
- package/dist/tests/fixtures.d.ts.map +1 -0
- package/dist/tests/fixtures.js +130 -0
- package/dist/tests/fixtures.js.map +1 -0
- package/dist/tests/integration.test.d.ts +2 -0
- package/dist/tests/integration.test.d.ts.map +1 -0
- package/dist/tests/integration.test.js +115 -0
- package/dist/tests/integration.test.js.map +1 -0
- package/dist/tests/resources.test.d.ts +2 -0
- package/dist/tests/resources.test.d.ts.map +1 -0
- package/dist/tests/resources.test.js +73 -0
- package/dist/tests/resources.test.js.map +1 -0
- package/dist/tests/setup.d.ts +8 -0
- package/dist/tests/setup.d.ts.map +1 -0
- package/dist/tests/setup.js +8 -0
- package/dist/tests/setup.js.map +1 -0
- package/dist/tests/tools.test.d.ts +2 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +224 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/ui/dashboard.html +1 -1
- package/dist/ui/detail.html +1 -1
- package/dist/ui/export.html +1 -1
- package/dist/ui-tmp/ui/export.html +1 -1
- package/package.json +6 -6
- package/dist/index.d.ts +0 -19
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -694
- package/dist/index.js.map +0 -1
- package/dist/lib/crypto/decrypt.d.ts.map +0 -1
- package/dist/lib/crypto/decrypt.js.map +0 -1
- package/dist/lib/crypto/encrypt.d.ts.map +0 -1
- package/dist/lib/crypto/encrypt.js.map +0 -1
- package/dist/lib/crypto/index.d.ts.map +0 -1
- package/dist/lib/crypto/index.js.map +0 -1
- package/dist/lib/crypto/key-derivation.d.ts.map +0 -1
- package/dist/lib/crypto/key-derivation.js.map +0 -1
- package/dist/lib/crypto/types.d.ts.map +0 -1
- package/dist/lib/crypto/types.js.map +0 -1
- package/dist/lib/storage/database.d.ts.map +0 -1
- package/dist/lib/storage/database.js.map +0 -1
- package/dist/lib/storage/export.d.ts.map +0 -1
- package/dist/lib/storage/export.js.map +0 -1
- package/dist/lib/storage/git.d.ts.map +0 -1
- package/dist/lib/storage/git.js.map +0 -1
- package/dist/lib/storage/index.d.ts.map +0 -1
- package/dist/lib/storage/index.js.map +0 -1
- package/dist/lib/storage/schema.d.ts.map +0 -1
- package/dist/lib/storage/schema.js.map +0 -1
- package/dist/lib/storage/types.d.ts.map +0 -1
- package/dist/test-helpers.d.ts.map +0 -1
- package/dist/test-helpers.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui/register.d.ts.map +0 -1
- package/dist/ui/register.js +0 -154
- package/dist/ui/register.js.map +0 -1
- /package/dist/{lib → src/lib}/crypto/decrypt.d.ts +0 -0
- /package/dist/{lib → src/lib}/crypto/encrypt.d.ts +0 -0
- /package/dist/{lib → src/lib}/crypto/encrypt.js +0 -0
- /package/dist/{lib → src/lib}/crypto/types.d.ts +0 -0
- /package/dist/{lib → src/lib}/crypto/types.js +0 -0
- /package/dist/{lib → src/lib}/storage/export.d.ts +0 -0
- /package/dist/{lib → src/lib}/storage/schema.d.ts +0 -0
- /package/dist/{lib → src/lib}/storage/types.d.ts +0 -0
- /package/dist/{lib → src/lib}/storage/types.js +0 -0
- /package/dist/{types.js → src/types.js} +0 -0
- /package/dist/{ui → src/ui}/register.d.ts +0 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
Model Context Protocol (MCP) server that automatically captures and encrypts LLM conversations as legal evidence.
|
|
7
7
|
|
|
8
|
-
## Why
|
|
8
|
+
## Why Footprint?
|
|
9
9
|
|
|
10
10
|
- **Prove IP Ownership** - Timestamped evidence of LLM-assisted work
|
|
11
11
|
- **Zero Effort** - Automatic capture via MCP protocol
|
|
@@ -21,12 +21,14 @@ npm install -g @pcircle/footprint
|
|
|
21
21
|
## Quick Start
|
|
22
22
|
|
|
23
23
|
1. **Set environment variables:**
|
|
24
|
+
|
|
24
25
|
```bash
|
|
25
|
-
export
|
|
26
|
-
export
|
|
26
|
+
export FOOTPRINT_DB_PATH="./evidence.db"
|
|
27
|
+
export FOOTPRINT_PASSWORD="your-secure-password"
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
2. **Configure Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
31
|
+
|
|
30
32
|
```json
|
|
31
33
|
{
|
|
32
34
|
"mcpServers": {
|
|
@@ -34,8 +36,8 @@ export EVIDENCEMCP_PASSWORD="your-secure-password"
|
|
|
34
36
|
"command": "npx",
|
|
35
37
|
"args": ["footprint"],
|
|
36
38
|
"env": {
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
+
"FOOTPRINT_DB_PATH": "/path/to/evidence.db",
|
|
40
|
+
"FOOTPRINT_PASSWORD": "your-password"
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
}
|
|
@@ -50,20 +52,171 @@ export EVIDENCEMCP_PASSWORD="your-secure-password"
|
|
|
50
52
|
- 🕒 Git commit timestamps
|
|
51
53
|
- 📦 Tamper-proof ZIP exports
|
|
52
54
|
- 🔍 Search and retrieve evidence
|
|
55
|
+
- 🤖 AI-powered capture suggestions
|
|
56
|
+
- ✅ Integrity verification
|
|
57
|
+
- 🏷️ Tag management
|
|
58
|
+
- 📊 Interactive UI dashboard
|
|
59
|
+
|
|
60
|
+
## Architecture
|
|
61
|
+
|
|
62
|
+
The Footprint MCP server follows a modular, layered architecture:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
src/
|
|
66
|
+
├── index.ts # Main MCP server
|
|
67
|
+
├── tools/ # MCP tool handlers (11 tools)
|
|
68
|
+
│ ├── capture-footprint.ts
|
|
69
|
+
│ ├── list-footprints.ts
|
|
70
|
+
│ ├── get-footprint.ts
|
|
71
|
+
│ ├── export-footprints.ts
|
|
72
|
+
│ ├── search-footprints.ts
|
|
73
|
+
│ ├── verify-footprint.ts
|
|
74
|
+
│ ├── suggest-capture.ts
|
|
75
|
+
│ ├── delete-footprints.ts
|
|
76
|
+
│ ├── rename-tag.ts
|
|
77
|
+
│ ├── remove-tag.ts
|
|
78
|
+
│ └── get-tag-stats.ts
|
|
79
|
+
├── analyzers/ # Content analysis modules
|
|
80
|
+
│ └── content-analyzer.ts
|
|
81
|
+
├── lib/
|
|
82
|
+
│ ├── crypto/ # Encryption & key derivation
|
|
83
|
+
│ ├── storage/ # Database & export
|
|
84
|
+
│ ├── tool-wrapper.ts # Error handling wrapper
|
|
85
|
+
│ └── tool-response.ts # Response formatters
|
|
86
|
+
└── ui/ # Interactive dashboards
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Design Principles
|
|
90
|
+
|
|
91
|
+
- **Modular**: Each tool is self-contained with schema, metadata, and handler
|
|
92
|
+
- **Type-Safe**: Full TypeScript with Zod schema validation
|
|
93
|
+
- **Testable**: Dependency injection enables isolated testing
|
|
94
|
+
- **Secure**: Encrypted storage with integrity verification
|
|
95
|
+
- **Maintainable**: Clear separation of concerns across layers
|
|
53
96
|
|
|
54
97
|
## MCP Tools
|
|
55
98
|
|
|
56
|
-
###
|
|
57
|
-
|
|
99
|
+
### Core Tools
|
|
100
|
+
|
|
101
|
+
#### capture-footprint
|
|
102
|
+
|
|
103
|
+
Captures and encrypts an LLM conversation as evidence.
|
|
104
|
+
|
|
105
|
+
**Parameters:**
|
|
106
|
+
|
|
107
|
+
- `conversationId` - Unique identifier for the conversation
|
|
108
|
+
- `llmProvider` - LLM provider name (e.g., "Claude Sonnet 4.5")
|
|
109
|
+
- `content` - Full conversation content
|
|
110
|
+
- `messageCount` - Number of messages in conversation
|
|
111
|
+
- `tags` (optional) - Comma-separated tags
|
|
112
|
+
|
|
113
|
+
#### list-footprints
|
|
114
|
+
|
|
115
|
+
Lists all captured evidence with pagination support.
|
|
58
116
|
|
|
59
|
-
|
|
60
|
-
|
|
117
|
+
**Parameters:**
|
|
118
|
+
|
|
119
|
+
- `limit` (optional) - Maximum results per page
|
|
120
|
+
- `offset` (optional) - Pagination offset
|
|
121
|
+
|
|
122
|
+
#### get-footprint
|
|
61
123
|
|
|
62
|
-
### get-footprint
|
|
63
124
|
Retrieves and decrypts specific evidence by ID.
|
|
64
125
|
|
|
65
|
-
|
|
66
|
-
|
|
126
|
+
**Parameters:**
|
|
127
|
+
|
|
128
|
+
- `id` - Evidence ID
|
|
129
|
+
|
|
130
|
+
#### export-footprints
|
|
131
|
+
|
|
132
|
+
Exports evidence to tamper-proof encrypted ZIP archive.
|
|
133
|
+
|
|
134
|
+
**Parameters:**
|
|
135
|
+
|
|
136
|
+
- `evidenceIds` - Array of evidence IDs to export
|
|
137
|
+
- `includeGitInfo` (optional) - Include git metadata
|
|
138
|
+
|
|
139
|
+
### Search & Discovery
|
|
140
|
+
|
|
141
|
+
#### search-footprints
|
|
142
|
+
|
|
143
|
+
Search and filter evidence by query, tags, or date range.
|
|
144
|
+
|
|
145
|
+
**Parameters:**
|
|
146
|
+
|
|
147
|
+
- `query` (optional) - Search text (matches conversationId, tags)
|
|
148
|
+
- `tags` (optional) - Array of tags to filter by
|
|
149
|
+
- `dateFrom` (optional) - Start date (ISO format)
|
|
150
|
+
- `dateTo` (optional) - End date (ISO format)
|
|
151
|
+
- `limit` (optional) - Maximum results
|
|
152
|
+
- `offset` (optional) - Pagination offset
|
|
153
|
+
|
|
154
|
+
#### suggest-capture
|
|
155
|
+
|
|
156
|
+
Analyze conversation content and suggest whether to capture it as evidence.
|
|
157
|
+
|
|
158
|
+
**Parameters:**
|
|
159
|
+
|
|
160
|
+
- `summary` - Conversation summary or key content to analyze
|
|
161
|
+
|
|
162
|
+
**Returns:**
|
|
163
|
+
|
|
164
|
+
- `shouldCapture` - Whether to capture (based on keyword analysis)
|
|
165
|
+
- `reason` - Human-readable explanation
|
|
166
|
+
- `suggestedTags` - Recommended tags
|
|
167
|
+
- `suggestedConversationId` - Recommended ID
|
|
168
|
+
- `confidence` - Confidence score (0-1)
|
|
169
|
+
|
|
170
|
+
### Verification
|
|
171
|
+
|
|
172
|
+
#### verify-footprint
|
|
173
|
+
|
|
174
|
+
Verify the integrity and authenticity of captured evidence.
|
|
175
|
+
|
|
176
|
+
**Parameters:**
|
|
177
|
+
|
|
178
|
+
- `id` - Evidence ID to verify
|
|
179
|
+
|
|
180
|
+
**Returns:**
|
|
181
|
+
|
|
182
|
+
- `verified` - Overall verification status
|
|
183
|
+
- `checks` - Detailed checks (content integrity, git timestamp, encryption)
|
|
184
|
+
- `legalReadiness` - Whether evidence meets legal standards
|
|
185
|
+
|
|
186
|
+
### Management
|
|
187
|
+
|
|
188
|
+
#### delete-footprints
|
|
189
|
+
|
|
190
|
+
Delete evidence records permanently.
|
|
191
|
+
|
|
192
|
+
**Parameters:**
|
|
193
|
+
|
|
194
|
+
- `evidenceIds` - Array of evidence IDs to delete
|
|
195
|
+
|
|
196
|
+
#### rename-tag
|
|
197
|
+
|
|
198
|
+
Rename a tag across all evidence.
|
|
199
|
+
|
|
200
|
+
**Parameters:**
|
|
201
|
+
|
|
202
|
+
- `oldTag` - Current tag name
|
|
203
|
+
- `newTag` - New tag name
|
|
204
|
+
|
|
205
|
+
#### remove-tag
|
|
206
|
+
|
|
207
|
+
Remove a tag from all evidence.
|
|
208
|
+
|
|
209
|
+
**Parameters:**
|
|
210
|
+
|
|
211
|
+
- `tag` - Tag name to remove
|
|
212
|
+
|
|
213
|
+
#### get-tag-stats
|
|
214
|
+
|
|
215
|
+
Get statistics about tag usage.
|
|
216
|
+
|
|
217
|
+
**Returns:**
|
|
218
|
+
|
|
219
|
+
- Tag names and their usage counts
|
|
67
220
|
|
|
68
221
|
## Security
|
|
69
222
|
|
package/SKILL.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Footprint Agent Skill
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> MCP server for capturing and encrypting AI conversations as verifiable records with Git timestamps.
|
|
4
|
+
|
|
5
|
+
**Package:** `@pcircle/footprint` (v1.1.1)
|
|
6
|
+
**Protocol:** Model Context Protocol (MCP)
|
|
7
|
+
**License:** MIT
|
|
4
8
|
|
|
5
9
|
## Decision Tree: Should I Capture This?
|
|
6
10
|
|
|
@@ -149,7 +153,7 @@ Human: We need to decide on the OAuth implementation...
|
|
|
149
153
|
Assistant: I recommend using PKCE flow...
|
|
150
154
|
```
|
|
151
155
|
|
|
152
|
-
### 4. `search-
|
|
156
|
+
### 4. `search-footprints`
|
|
153
157
|
Find evidence by content or tags.
|
|
154
158
|
|
|
155
159
|
**Input Parameters:**
|
|
@@ -161,7 +165,7 @@ Find evidence by content or tags.
|
|
|
161
165
|
}
|
|
162
166
|
```
|
|
163
167
|
|
|
164
|
-
### 5. `export-
|
|
168
|
+
### 5. `export-footprints`
|
|
165
169
|
Export evidence as encrypted archive.
|
|
166
170
|
|
|
167
171
|
**Input Parameters:**
|
|
@@ -183,6 +187,39 @@ Export evidence as encrypted archive.
|
|
|
183
187
|
}
|
|
184
188
|
```
|
|
185
189
|
|
|
190
|
+
### 6. `verify-footprint`
|
|
191
|
+
Verify evidence integrity (checksum + Git timestamp).
|
|
192
|
+
|
|
193
|
+
**Input Parameters:**
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"id": "550e8400-e29b-41d4-a716-446655440000"
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Expected Output (text):**
|
|
201
|
+
```
|
|
202
|
+
🔐 Evidence Verification Report
|
|
203
|
+
- ID: 550e8400-e29b-41d4-a716-446655440000
|
|
204
|
+
- Content Hash: ✅ Valid (SHA-256 matches)
|
|
205
|
+
- Git Timestamp: ✅ Verified (2026-01-28T14:30:45Z)
|
|
206
|
+
- Encryption: ✅ Decryption successful
|
|
207
|
+
- Status: AUTHENTIC - No tampering detected
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Expected Output (structuredContent):**
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"type": "verification_result",
|
|
214
|
+
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
215
|
+
"contentHashValid": true,
|
|
216
|
+
"gitTimestampVerified": true,
|
|
217
|
+
"decryptionSuccessful": true,
|
|
218
|
+
"status": "authentic",
|
|
219
|
+
"timestamp": "2026-01-28T14:30:45Z"
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
186
223
|
## Best Practices
|
|
187
224
|
|
|
188
225
|
### Naming conversationId
|
|
@@ -216,9 +253,10 @@ Export evidence as encrypted archive.
|
|
|
216
253
|
### When to Use Each Tool
|
|
217
254
|
- **capture-footprint**: Primary tool for saving conversations
|
|
218
255
|
- **list-footprints**: Browse/overview existing evidence
|
|
219
|
-
- **search-
|
|
256
|
+
- **search-footprints**: Find specific content across evidence
|
|
220
257
|
- **get-footprint**: Retrieve full content of specific evidence
|
|
221
|
-
- **export-
|
|
258
|
+
- **export-footprints**: Legal/audit export needs
|
|
259
|
+
- **verify-footprint**: Verify evidence integrity and checksums
|
|
222
260
|
|
|
223
261
|
## Token-Efficient Agent Responses
|
|
224
262
|
|
|
@@ -249,10 +287,10 @@ Tags: {tags}
|
|
|
249
287
|
|
|
250
288
|
| Error | Likely Cause | Recovery Action |
|
|
251
289
|
|-------|--------------|-----------------|
|
|
252
|
-
| "Password required" |
|
|
290
|
+
| "Password required" | FOOTPRINT_PASSWORD not set | 1. Check env config<br>2. Restart MCP server<br>3. Verify password in env |
|
|
253
291
|
| "Evidence not found" | Invalid/wrong ID | 1. Use `list-footprints` to find correct ID<br>2. Search by conversationId<br>3. Check if user meant different evidence |
|
|
254
292
|
| "Decryption failed" | Password changed/wrong | 1. Verify current password matches<br>2. Check if evidence pre-dates password change<br>3. Try with backup password if available |
|
|
255
|
-
| "Database error" | DB path/permissions issues | 1. Check
|
|
293
|
+
| "Database error" | DB path/permissions issues | 1. Check FOOTPRINT_DB_PATH exists<br>2. Verify file permissions<br>3. Create directory if missing |
|
|
256
294
|
| "Git repository error" | Git not initialized | 1. Initialize git in evidence directory<br>2. Set git user.name/user.email<br>3. Make initial commit |
|
|
257
295
|
| "Capture timeout" | Large conversation size | 1. Split into smaller chunks<br>2. Reduce messageCount<br>3. Compress content before capture |
|
|
258
296
|
|
|
@@ -309,11 +347,12 @@ Agent:
|
|
|
309
347
|
|
|
310
348
|
## Security & Verification
|
|
311
349
|
|
|
312
|
-
- **Password**: Set via `
|
|
313
|
-
- **Encryption**:
|
|
350
|
+
- **Password**: Set via `FOOTPRINT_PASSWORD` env var (never ask user in chat)
|
|
351
|
+
- **Encryption**: XChaCha20-Poly1305 (256-bit) with Argon2id key derivation
|
|
314
352
|
- **Git Timestamps**: Cryptographic proof of creation time
|
|
315
353
|
- **SHA-256 Checksums**: Detect any content tampering
|
|
316
354
|
- **Evidence Chain**: Each capture creates immutable Git commit
|
|
355
|
+
- **Storage**: Local SQLite with encrypted BLOBs (no cloud, no tracking)
|
|
317
356
|
|
|
318
357
|
**For legal proceedings:**
|
|
319
358
|
1. Export evidence with `export-evidence`
|
|
@@ -327,23 +366,41 @@ Agent:
|
|
|
327
366
|
This section is for humans setting up the agent environment:
|
|
328
367
|
|
|
329
368
|
```bash
|
|
330
|
-
# Install MCP server
|
|
331
|
-
npm install -g @pcircle/footprint
|
|
369
|
+
# Install MCP server globally
|
|
370
|
+
npm install -g @pcircle/footprint
|
|
332
371
|
|
|
333
|
-
#
|
|
372
|
+
# Or run directly with npx
|
|
373
|
+
npx @pcircle/footprint
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Claude Desktop config location:**
|
|
377
|
+
|
|
378
|
+
| Platform | Config Path |
|
|
379
|
+
|----------|-------------|
|
|
380
|
+
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
381
|
+
| Linux | `~/.config/Claude/claude_desktop_config.json` |
|
|
382
|
+
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
383
|
+
|
|
384
|
+
**Config content:**
|
|
385
|
+
```json
|
|
334
386
|
{
|
|
335
387
|
"mcpServers": {
|
|
336
388
|
"footprint": {
|
|
337
|
-
"command": "
|
|
389
|
+
"command": "npx",
|
|
390
|
+
"args": ["@pcircle/footprint"],
|
|
338
391
|
"env": {
|
|
339
|
-
"
|
|
340
|
-
"
|
|
392
|
+
"FOOTPRINT_DB_PATH": "/path/to/evidence.db",
|
|
393
|
+
"FOOTPRINT_PASSWORD": "your-secure-password-here"
|
|
341
394
|
}
|
|
342
395
|
}
|
|
343
396
|
}
|
|
344
397
|
}
|
|
345
398
|
```
|
|
346
399
|
|
|
400
|
+
**Environment Variables:**
|
|
401
|
+
- `FOOTPRINT_PASSWORD` (required): Encryption passphrase
|
|
402
|
+
- `FOOTPRINT_DB_PATH` (optional): Path to SQLite database (default: `./evidence.db` in current directory)
|
|
403
|
+
|
|
347
404
|
## Performance Notes
|
|
348
405
|
|
|
349
406
|
- **Capture time**: ~1-3 seconds per conversation
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content analyzer for determining if conversation content should be captured as evidence
|
|
3
|
+
* Analyzes keywords, calculates confidence, and generates appropriate metadata
|
|
4
|
+
*/
|
|
5
|
+
export interface AnalysisResult {
|
|
6
|
+
shouldCapture: boolean;
|
|
7
|
+
reason: string;
|
|
8
|
+
suggestedTags: string[];
|
|
9
|
+
suggestedConversationId: string;
|
|
10
|
+
confidence: number;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Analyze conversation content and determine if it should be captured as evidence
|
|
15
|
+
*
|
|
16
|
+
* @param summary - Conversation summary or key content to analyze
|
|
17
|
+
* @returns Analysis result with capture recommendation and metadata
|
|
18
|
+
*/
|
|
19
|
+
export declare function analyzeContent(summary: string): AnalysisResult;
|
|
20
|
+
//# sourceMappingURL=content-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/content-analyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAkLD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAuB9D"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content analyzer for determining if conversation content should be captured as evidence
|
|
3
|
+
* Analyzes keywords, calculates confidence, and generates appropriate metadata
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Keyword categories for detecting important content
|
|
7
|
+
*/
|
|
8
|
+
const KEYWORD_CATEGORIES = {
|
|
9
|
+
ip: [
|
|
10
|
+
"patent",
|
|
11
|
+
"intellectual property",
|
|
12
|
+
"invention",
|
|
13
|
+
"algorithm",
|
|
14
|
+
"proprietary",
|
|
15
|
+
"innovation",
|
|
16
|
+
"design",
|
|
17
|
+
],
|
|
18
|
+
legal: [
|
|
19
|
+
"contract",
|
|
20
|
+
"agreement",
|
|
21
|
+
"legal",
|
|
22
|
+
"copyright",
|
|
23
|
+
"license",
|
|
24
|
+
"terms",
|
|
25
|
+
"clause",
|
|
26
|
+
"liability",
|
|
27
|
+
],
|
|
28
|
+
business: [
|
|
29
|
+
"decision",
|
|
30
|
+
"milestone",
|
|
31
|
+
"deliverable",
|
|
32
|
+
"approval",
|
|
33
|
+
"strategy",
|
|
34
|
+
"roadmap",
|
|
35
|
+
"budget",
|
|
36
|
+
"timeline",
|
|
37
|
+
],
|
|
38
|
+
research: [
|
|
39
|
+
"hypothesis",
|
|
40
|
+
"findings",
|
|
41
|
+
"proof",
|
|
42
|
+
"research",
|
|
43
|
+
"study",
|
|
44
|
+
"experiment",
|
|
45
|
+
"analysis",
|
|
46
|
+
"data",
|
|
47
|
+
],
|
|
48
|
+
compliance: [
|
|
49
|
+
"audit",
|
|
50
|
+
"compliance",
|
|
51
|
+
"evidence",
|
|
52
|
+
"documentation",
|
|
53
|
+
"regulation",
|
|
54
|
+
"policy",
|
|
55
|
+
"requirement",
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Match whole words only to avoid false positives
|
|
60
|
+
* (e.g., "logarithm" should not match "algorithm")
|
|
61
|
+
*/
|
|
62
|
+
function matchesWord(text, word) {
|
|
63
|
+
const regex = new RegExp(`\\b${word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "i");
|
|
64
|
+
return regex.test(text);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Detect matching keyword categories in the text
|
|
68
|
+
*/
|
|
69
|
+
function findKeywordMatches(text) {
|
|
70
|
+
const matches = [];
|
|
71
|
+
for (const [category, keywords] of Object.entries(KEYWORD_CATEGORIES)) {
|
|
72
|
+
const foundKeywords = keywords.filter((keyword) => matchesWord(text, keyword));
|
|
73
|
+
if (foundKeywords.length > 0) {
|
|
74
|
+
const weight = foundKeywords.length / keywords.length;
|
|
75
|
+
matches.push({ category, keywords: foundKeywords, weight });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return matches;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Calculate confidence score based on keyword matches and text characteristics
|
|
82
|
+
*
|
|
83
|
+
* @param matches - Keyword matches found in text
|
|
84
|
+
* @param wordCount - Total word count in text
|
|
85
|
+
* @returns Confidence score between 0 and 1
|
|
86
|
+
*/
|
|
87
|
+
function calculateConfidence(matches, wordCount) {
|
|
88
|
+
if (matches.length === 0) {
|
|
89
|
+
// No keywords found = low importance confidence
|
|
90
|
+
// Longer text without keywords = slightly higher (might have missed something)
|
|
91
|
+
const lengthFactor = Math.min(wordCount / 200, 0.3); // Max 0.3 for very long text
|
|
92
|
+
return 0.1 + lengthFactor; // Range: 0.1 to 0.4
|
|
93
|
+
}
|
|
94
|
+
// More keywords and categories = higher importance confidence
|
|
95
|
+
const totalKeywords = matches.reduce((sum, match) => sum + match.keywords.length, 0);
|
|
96
|
+
const keywordDensity = totalKeywords / Math.max(wordCount, 1);
|
|
97
|
+
const categoryBonus = matches.length * 0.15;
|
|
98
|
+
const keywordBonus = Math.min(totalKeywords * 0.1, 0.4);
|
|
99
|
+
return Math.min(0.95, 0.3 + categoryBonus + keywordBonus + keywordDensity);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Generate human-readable reason for capture recommendation
|
|
103
|
+
*/
|
|
104
|
+
function generateReason(matches) {
|
|
105
|
+
if (matches.length === 0) {
|
|
106
|
+
return "Appears to be casual conversation with no critical business, legal, or IP content";
|
|
107
|
+
}
|
|
108
|
+
const categories = matches.map((m) => m.category === "ip" ? "IP" : m.category);
|
|
109
|
+
if (categories.length === 1) {
|
|
110
|
+
return `Contains ${categories[0]} keywords: ${matches[0].keywords.join(", ")}`;
|
|
111
|
+
}
|
|
112
|
+
return `Contains multiple important categories: ${categories.join(", ")}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate suggested tags from keyword matches
|
|
116
|
+
*/
|
|
117
|
+
function generateTags(matches) {
|
|
118
|
+
if (matches.length === 0) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
return [
|
|
122
|
+
...new Set(matches.flatMap((m) => [m.category, ...m.keywords.slice(0, 2)])),
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Generate conversation ID based on matches and current date
|
|
127
|
+
*/
|
|
128
|
+
function generateConversationId(matches) {
|
|
129
|
+
const currentDate = new Date().toISOString().slice(0, 10);
|
|
130
|
+
if (matches.length === 0) {
|
|
131
|
+
return `conversation-${currentDate}`;
|
|
132
|
+
}
|
|
133
|
+
// Extract key terms for ID generation
|
|
134
|
+
const primaryKeywords = matches[0].keywords.slice(0, 2);
|
|
135
|
+
const cleanKeywords = primaryKeywords
|
|
136
|
+
.map((k) => k.replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, ""))
|
|
137
|
+
.filter((k) => k.length > 0);
|
|
138
|
+
if (cleanKeywords.length > 0) {
|
|
139
|
+
return `${cleanKeywords.join("-")}-${currentDate}`;
|
|
140
|
+
}
|
|
141
|
+
return `${matches[0].category}-discussion-${currentDate}`;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Analyze conversation content and determine if it should be captured as evidence
|
|
145
|
+
*
|
|
146
|
+
* @param summary - Conversation summary or key content to analyze
|
|
147
|
+
* @returns Analysis result with capture recommendation and metadata
|
|
148
|
+
*/
|
|
149
|
+
export function analyzeContent(summary) {
|
|
150
|
+
const normalizedText = summary.toLowerCase();
|
|
151
|
+
const wordCount = normalizedText.split(/\s+/).length;
|
|
152
|
+
// Find keyword matches
|
|
153
|
+
const matches = findKeywordMatches(normalizedText);
|
|
154
|
+
const shouldCapture = matches.length > 0;
|
|
155
|
+
// Calculate confidence
|
|
156
|
+
const confidence = calculateConfidence(matches, wordCount);
|
|
157
|
+
// Generate metadata
|
|
158
|
+
const reason = generateReason(matches);
|
|
159
|
+
const suggestedTags = generateTags(matches);
|
|
160
|
+
const suggestedConversationId = generateConversationId(matches);
|
|
161
|
+
return {
|
|
162
|
+
shouldCapture,
|
|
163
|
+
reason,
|
|
164
|
+
suggestedTags,
|
|
165
|
+
suggestedConversationId,
|
|
166
|
+
confidence: Math.round(confidence * 100) / 100,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=content-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-analyzer.js","sourceRoot":"","sources":["../../../src/analyzers/content-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import type { ServerConfig } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Footprint Server - Captures LLM conversations as encrypted evidence
|
|
5
|
+
* with Git timestamps and export capabilities.
|
|
6
|
+
*/
|
|
7
|
+
export declare class FootprintServer {
|
|
8
|
+
private server;
|
|
9
|
+
private config;
|
|
10
|
+
private db;
|
|
11
|
+
private derivedKey;
|
|
12
|
+
private keyDerivationPromise;
|
|
13
|
+
constructor(config: ServerConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Get or derive encryption key using stored salt (thread-safe)
|
|
16
|
+
* Caches key in memory for performance, with cleanup on shutdown
|
|
17
|
+
* Handles concurrent calls by ensuring only one derivation happens at a time
|
|
18
|
+
*
|
|
19
|
+
* @returns 32-byte encryption key
|
|
20
|
+
* @throws Error if salt storage fails
|
|
21
|
+
*/
|
|
22
|
+
private getDerivedKey;
|
|
23
|
+
/**
|
|
24
|
+
* Securely clear derived key from memory
|
|
25
|
+
* Should be called on server shutdown
|
|
26
|
+
*/
|
|
27
|
+
private clearDerivedKey;
|
|
28
|
+
private registerTools;
|
|
29
|
+
private registerResources;
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Cleanup server resources
|
|
33
|
+
* Clears derived key from memory and closes database
|
|
34
|
+
*/
|
|
35
|
+
close(): void;
|
|
36
|
+
}
|
|
37
|
+
export { FootprintTestHelpers } from "./test-helpers.js";
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAuC/C;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,oBAAoB,CAAoC;gBAEpD,MAAM,EAAE,YAAY;IAuBhC;;;;;;;OAOG;YACW,aAAa;IAsC3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;IA2HrB,OAAO,CAAC,iBAAiB;IAqCnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;;OAGG;IACH,KAAK,IAAI,IAAI;CAId;AA6DD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
|