indelible-mcp 3.1.0 → 3.2.1
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 +158 -82
- package/index.js +404 -0
- package/lib/api.js +243 -0
- package/{src/lib → lib}/config.js +101 -80
- package/{src/lib → lib}/crypto.js +94 -66
- package/lib/spv.js +527 -0
- package/package.json +35 -39
- package/tools/backfill_index.js +92 -0
- package/{src/tools → tools}/diary_chat.js +36 -5
- package/{src/tools → tools}/diary_connect.js +5 -5
- package/{src/tools → tools}/diary_save.js +24 -45
- package/{src/tools → tools}/load_context.js +352 -296
- package/tools/load_file.js +178 -0
- package/tools/load_project.js +181 -0
- package/{src/tools → tools}/load_style.js +1 -0
- package/tools/save_file.js +269 -0
- package/tools/save_project.js +210 -0
- package/tools/save_session.js +878 -0
- package/tools/save_style.js +190 -0
- package/{src/tools → tools}/setup_wallet.js +119 -131
- package/src/index.js +0 -627
- package/src/lib/api-client.js +0 -160
- package/src/lib/spv.js +0 -328
- package/src/lib/transcript.js +0 -111
- package/src/tools/load_file.js +0 -110
- package/src/tools/load_project.js +0 -133
- package/src/tools/save_file.js +0 -159
- package/src/tools/save_project.js +0 -163
- package/src/tools/save_session.js +0 -442
- package/src/tools/save_style.js +0 -105
- /package/{src/tools → tools}/update_vault_index.js +0 -0
package/README.md
CHANGED
|
@@ -1,82 +1,158 @@
|
|
|
1
|
-
# Indelible MCP Server
|
|
2
|
-
|
|
3
|
-
Blockchain-backed memory for Claude Code. Save your AI conversations permanently on BSV.
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g indelible-mcp
|
|
9
|
-
indelible-mcp
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
indelible
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
1
|
+
# Indelible MCP Server
|
|
2
|
+
|
|
3
|
+
Blockchain-backed memory for Claude Code. Save your AI conversations permanently on BSV.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g indelible-mcp
|
|
9
|
+
indelible-mcp --show-config
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Copy the config output and paste it into your Claude Code settings, then restart Claude Code.
|
|
13
|
+
|
|
14
|
+
## Setup
|
|
15
|
+
|
|
16
|
+
### 1. Sign Up at indelible.one
|
|
17
|
+
|
|
18
|
+
Sign in with Google at [indelible.one](https://indelible.one). Your BSV private key (WIF) is generated automatically and shown in Settings.
|
|
19
|
+
|
|
20
|
+
### 2. Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g indelible-mcp
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 3. Import Your Key
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
indelible-mcp setup --wif=YOUR_KEY
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Paste the WIF from your indelible.one Settings page. This saves it to `~/.indelible/config.json`.
|
|
33
|
+
|
|
34
|
+
**Your key never leaves your machine.**
|
|
35
|
+
|
|
36
|
+
### 4. Configure Claude Code
|
|
37
|
+
|
|
38
|
+
Run:
|
|
39
|
+
```bash
|
|
40
|
+
indelible-mcp --show-config
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Add the output to your Claude Code settings:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"indelible": {
|
|
49
|
+
"command": "indelible-mcp"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 5. Restart Claude Code
|
|
56
|
+
|
|
57
|
+
Close and reopen VS Code (or your Claude Code client).
|
|
58
|
+
|
|
59
|
+
### 6. Fund Your Wallet
|
|
60
|
+
|
|
61
|
+
Send a small amount of BSV (~$0.01) to your address for transaction fees.
|
|
62
|
+
|
|
63
|
+
## Tools
|
|
64
|
+
|
|
65
|
+
### `setup_wallet`
|
|
66
|
+
Import your BSV wallet from indelible.one. Only needed once.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
"Import my wallet" or indelible-mcp setup --wif=YOUR_KEY
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `save_session`
|
|
73
|
+
Save the current conversation to the blockchain.
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
"Save this session to blockchain"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `load_context`
|
|
80
|
+
Load previous sessions from the blockchain. Automatically includes your active AI style if one is saved.
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
"Load my previous context"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `save_file`
|
|
87
|
+
Save a single file to the blockchain, encrypted with your key.
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
"Save this file to the blockchain"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `load_file`
|
|
94
|
+
Load a file from the blockchain by transaction ID.
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
"Load file from tx abc123..."
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### `save_project`
|
|
101
|
+
Save an entire project directory to the blockchain.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
"Save this project to the blockchain"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `load_project`
|
|
108
|
+
Load a project from the blockchain by transaction ID.
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
"Load project from tx abc123..."
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### `save_style`
|
|
115
|
+
Save an AI interaction style (rules/preferences) to blockchain.
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
"Save my AI style to blockchain"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `load_style`
|
|
122
|
+
Load an AI interaction style from blockchain. Called automatically by `load_context`.
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
"Load my AI style"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### `update_vault_index`
|
|
129
|
+
Update the on-chain vault index with metadata for all saved files and projects.
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
"Update my vault index"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## How It Works
|
|
136
|
+
|
|
137
|
+
1. Your conversations are encrypted with AES-256-GCM using your WIF-derived key
|
|
138
|
+
2. Encrypted data is stored on the BSV blockchain via OP_RETURN
|
|
139
|
+
3. Only you can decrypt your data (using your WIF)
|
|
140
|
+
4. Sessions are chained together for continuity
|
|
141
|
+
|
|
142
|
+
## View Your Data
|
|
143
|
+
|
|
144
|
+
Visit [indelible.one](https://indelible.one) and sign in with Google to see all your saved sessions and code.
|
|
145
|
+
|
|
146
|
+
## Cost
|
|
147
|
+
|
|
148
|
+
~1 satoshi per byte. A typical session costs less than $0.01.
|
|
149
|
+
|
|
150
|
+
## Changelog
|
|
151
|
+
|
|
152
|
+
### 3.2.1
|
|
153
|
+
- Security fix: removed remote fallback paths
|
|
154
|
+
- All operations now route exclusively through SPV bridge
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Indelible MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Provides blockchain-backed memory for Claude Code sessions.
|
|
6
|
+
* Communicates via stdio using JSON-RPC (MCP protocol).
|
|
7
|
+
*
|
|
8
|
+
* Tools:
|
|
9
|
+
* - setup_wallet: Generate BSV keypair, save to ~/.indelible/config.json
|
|
10
|
+
* - save_session: Read transcript, encrypt, commit to chain
|
|
11
|
+
* - load_context: Fetch latest checkpoint, decrypt, return summary
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Handle CLI flags before loading MCP
|
|
15
|
+
if (process.argv.includes('--show-config')) {
|
|
16
|
+
console.log(`
|
|
17
|
+
Add this to your Claude Code settings.json:
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"indelible": {
|
|
22
|
+
"command": "indelible-mcp"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Then restart Claude Code and say "set up my wallet" to get started.
|
|
28
|
+
`)
|
|
29
|
+
process.exit(0)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
33
|
+
console.log(`
|
|
34
|
+
Indelible MCP Server - Blockchain memory for Claude Code
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
indelible-mcp Start MCP server (used by Claude Code)
|
|
38
|
+
indelible-mcp --show-config Show Claude Code configuration
|
|
39
|
+
indelible-mcp --help Show this help message
|
|
40
|
+
|
|
41
|
+
After installing, run 'indelible-mcp --show-config' and paste
|
|
42
|
+
the output into your Claude Code settings.
|
|
43
|
+
|
|
44
|
+
Learn more: https://indelible.one
|
|
45
|
+
`)
|
|
46
|
+
process.exit(0)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
import { createInterface } from 'readline'
|
|
50
|
+
import { setupWallet } from './tools/setup_wallet.js'
|
|
51
|
+
import { saveSession } from './tools/save_session.js'
|
|
52
|
+
import { loadContext } from './tools/load_context.js'
|
|
53
|
+
import { saveFile } from './tools/save_file.js'
|
|
54
|
+
import { loadFile } from './tools/load_file.js'
|
|
55
|
+
import { saveProject } from './tools/save_project.js'
|
|
56
|
+
import { loadProject } from './tools/load_project.js'
|
|
57
|
+
import { saveStyle } from './tools/save_style.js'
|
|
58
|
+
import { loadStyle } from './tools/load_style.js'
|
|
59
|
+
import { updateVaultIndex } from './tools/update_vault_index.js'
|
|
60
|
+
import { diaryConnect } from './tools/diary_connect.js'
|
|
61
|
+
import { diaryChat } from './tools/diary_chat.js'
|
|
62
|
+
import { diarySave } from './tools/diary_save.js'
|
|
63
|
+
|
|
64
|
+
// MCP Server metadata
|
|
65
|
+
const SERVER_INFO = {
|
|
66
|
+
name: 'indelible-mcp',
|
|
67
|
+
version: '3.1.0',
|
|
68
|
+
description: 'Blockchain-backed memory for Claude Code'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Available tools
|
|
72
|
+
const TOOLS = [
|
|
73
|
+
{
|
|
74
|
+
name: 'setup_wallet',
|
|
75
|
+
description: 'Generate a new BSV wallet for Indelible AI. Creates keypair and saves to ~/.indelible/config.json. Only run once per machine.',
|
|
76
|
+
inputSchema: {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
api_url: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
description: 'Indelible API URL (default: https://indelible.one)'
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
required: []
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'save_session',
|
|
89
|
+
description: 'Save the current Claude Code session to the blockchain. Encrypts transcript and commits to BSV chain.',
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
transcript_path: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'Path to the JSONL transcript file'
|
|
96
|
+
},
|
|
97
|
+
summary: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'Brief summary of what was accomplished in this session'
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
required: ['transcript_path']
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'load_context',
|
|
107
|
+
description: 'Load previous session context from the blockchain. Returns summary of past sessions to restore memory.',
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
num_sessions: {
|
|
112
|
+
type: 'number',
|
|
113
|
+
description: 'Number of recent sessions to load (default: 3)'
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
required: []
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'save_file',
|
|
121
|
+
description: 'Save a file to the BSV blockchain. Encrypts content with your wallet key and stores permanently on-chain. Supports chunking for large files.',
|
|
122
|
+
inputSchema: {
|
|
123
|
+
type: 'object',
|
|
124
|
+
properties: {
|
|
125
|
+
file_path: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
description: 'Absolute path to the file to save'
|
|
128
|
+
},
|
|
129
|
+
relative_path: {
|
|
130
|
+
type: 'string',
|
|
131
|
+
description: 'Path relative to project root (for display/restore). Defaults to file_path.'
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
required: ['file_path']
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'load_file',
|
|
139
|
+
description: 'Load a file from the BSV blockchain by its transaction ID. Decrypts and returns the file contents, with optional write to disk.',
|
|
140
|
+
inputSchema: {
|
|
141
|
+
type: 'object',
|
|
142
|
+
properties: {
|
|
143
|
+
tx_id: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Transaction ID of the saved file (from save_file result)'
|
|
146
|
+
},
|
|
147
|
+
output_path: {
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Optional: write the restored file to this path on disk'
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
required: ['tx_id']
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'save_project',
|
|
157
|
+
description: 'Save an entire project directory to the BSV blockchain. Walks the directory (respecting .gitignore), encrypts all files client-side, and bundles into a single OP_RETURN transaction.',
|
|
158
|
+
inputSchema: {
|
|
159
|
+
type: 'object',
|
|
160
|
+
properties: {
|
|
161
|
+
dir_path: {
|
|
162
|
+
type: 'string',
|
|
163
|
+
description: 'Absolute path to the project directory'
|
|
164
|
+
},
|
|
165
|
+
name: {
|
|
166
|
+
type: 'string',
|
|
167
|
+
description: 'Project name (default: directory name)'
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
required: ['dir_path']
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'load_project',
|
|
175
|
+
description: 'Load an entire project from the BSV blockchain by its manifest transaction ID. Downloads, decrypts, and optionally restores all files to disk.',
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: {
|
|
179
|
+
tx_id: {
|
|
180
|
+
type: 'string',
|
|
181
|
+
description: 'Transaction ID of the project bundle (from save_project result)'
|
|
182
|
+
},
|
|
183
|
+
output_dir: {
|
|
184
|
+
type: 'string',
|
|
185
|
+
description: 'Optional: restore all project files to this directory'
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
required: ['tx_id']
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'save_style',
|
|
193
|
+
description: 'Save an AI interaction style (rules/preferences) to blockchain. Encrypted with your key.',
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: 'object',
|
|
196
|
+
properties: {
|
|
197
|
+
rules_text: { type: 'string', description: 'The full rules/style text (markdown)' },
|
|
198
|
+
style_name: { type: 'string', description: 'Short name for this style' },
|
|
199
|
+
description: { type: 'string', description: 'One-line description' }
|
|
200
|
+
},
|
|
201
|
+
required: ['rules_text', 'style_name']
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'load_style',
|
|
206
|
+
description: 'Load an AI interaction style from blockchain. Returns rules text and metadata.',
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
txid: { type: 'string', description: 'Transaction ID of the style. If omitted, loads last saved style.' }
|
|
211
|
+
},
|
|
212
|
+
required: []
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'update_vault_index',
|
|
217
|
+
description: 'Update the on-chain vault index with metadata for all saved files and projects.',
|
|
218
|
+
inputSchema: {
|
|
219
|
+
type: 'object',
|
|
220
|
+
properties: {},
|
|
221
|
+
required: []
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: 'diary_connect',
|
|
226
|
+
description: 'Connect Diary AI companion (Codex/ChatGPT). Stores your OpenAI API key and model preference so diary_chat can reach your AI.',
|
|
227
|
+
inputSchema: {
|
|
228
|
+
type: 'object',
|
|
229
|
+
properties: {
|
|
230
|
+
api_key: { type: 'string', description: 'OpenAI API key (sk-...)' },
|
|
231
|
+
model: { type: 'string', description: 'Model ID (default: gpt-4o). Options: gpt-5.2, gpt-5, gpt-5-nano, gpt-4o, gpt-4o-mini, o1' },
|
|
232
|
+
name: { type: 'string', description: 'Display name for the AI companion (default: Codex)' }
|
|
233
|
+
},
|
|
234
|
+
required: ['api_key']
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: 'diary_chat',
|
|
239
|
+
description: 'Send a message to Diary AI (Codex/ChatGPT). Returns the response formatted with a name badge. Use this when the user says "ask codex", "what does codex think", or wants the AI companion\'s input.',
|
|
240
|
+
inputSchema: {
|
|
241
|
+
type: 'object',
|
|
242
|
+
properties: {
|
|
243
|
+
message: { type: 'string', description: 'The question or message to send to the AI companion' },
|
|
244
|
+
context: { type: 'string', description: 'Optional context about current work to help the AI understand the situation' },
|
|
245
|
+
system_prompt: { type: 'string', description: 'Optional system prompt override' }
|
|
246
|
+
},
|
|
247
|
+
required: ['message']
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'diary_save',
|
|
252
|
+
description: 'Save a Diary AI (Codex) exchange to the blockchain. Uses the same WIF as Claude sessions. Tagged with source so both AIs share one memory chain.',
|
|
253
|
+
inputSchema: {
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: {
|
|
256
|
+
messages: {
|
|
257
|
+
type: 'array',
|
|
258
|
+
description: 'Array of message objects: [{ role: "user"|"assistant", content: "..." }]',
|
|
259
|
+
items: {
|
|
260
|
+
type: 'object',
|
|
261
|
+
properties: {
|
|
262
|
+
role: { type: 'string' },
|
|
263
|
+
content: { type: 'string' }
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
summary: { type: 'string', description: 'Brief summary of the exchange' }
|
|
268
|
+
},
|
|
269
|
+
required: ['messages']
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
]
|
|
273
|
+
|
|
274
|
+
// Handle MCP requests
|
|
275
|
+
async function handleRequest(request) {
|
|
276
|
+
const { method, params, id } = request
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
switch (method) {
|
|
280
|
+
case 'initialize':
|
|
281
|
+
return {
|
|
282
|
+
jsonrpc: '2.0',
|
|
283
|
+
id,
|
|
284
|
+
result: {
|
|
285
|
+
protocolVersion: '2024-11-05',
|
|
286
|
+
serverInfo: SERVER_INFO,
|
|
287
|
+
capabilities: {
|
|
288
|
+
tools: {}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
case 'tools/list':
|
|
294
|
+
return {
|
|
295
|
+
jsonrpc: '2.0',
|
|
296
|
+
id,
|
|
297
|
+
result: { tools: TOOLS }
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
case 'tools/call':
|
|
301
|
+
const { name, arguments: args } = params
|
|
302
|
+
let result
|
|
303
|
+
|
|
304
|
+
switch (name) {
|
|
305
|
+
case 'setup_wallet':
|
|
306
|
+
result = await setupWallet(args?.api_url)
|
|
307
|
+
break
|
|
308
|
+
case 'save_session':
|
|
309
|
+
result = await saveSession(args?.transcript_path, args?.summary)
|
|
310
|
+
break
|
|
311
|
+
case 'load_context':
|
|
312
|
+
result = await loadContext(args?.num_sessions)
|
|
313
|
+
break
|
|
314
|
+
case 'save_file':
|
|
315
|
+
result = await saveFile(args.file_path, { relativePath: args.relative_path })
|
|
316
|
+
break
|
|
317
|
+
case 'load_file':
|
|
318
|
+
result = await loadFile(args.tx_id, { outputPath: args.output_path })
|
|
319
|
+
break
|
|
320
|
+
case 'save_project':
|
|
321
|
+
result = await saveProject(args.dir_path, { name: args.name })
|
|
322
|
+
break
|
|
323
|
+
case 'load_project':
|
|
324
|
+
result = await loadProject(args.tx_id, { outputDir: args.output_dir })
|
|
325
|
+
break
|
|
326
|
+
case 'save_style':
|
|
327
|
+
result = await saveStyle(args?.rules_text, args?.style_name, args?.description)
|
|
328
|
+
break
|
|
329
|
+
case 'load_style':
|
|
330
|
+
result = await loadStyle(args?.txid)
|
|
331
|
+
break
|
|
332
|
+
case 'update_vault_index':
|
|
333
|
+
result = await updateVaultIndex()
|
|
334
|
+
break
|
|
335
|
+
case 'diary_connect':
|
|
336
|
+
result = await diaryConnect({ apiKey: args?.api_key, model: args?.model, name: args?.name })
|
|
337
|
+
break
|
|
338
|
+
case 'diary_chat':
|
|
339
|
+
result = await diaryChat({ message: args?.message, context: args?.context, systemPrompt: args?.system_prompt })
|
|
340
|
+
break
|
|
341
|
+
case 'diary_save':
|
|
342
|
+
result = await diarySave({ messages: args?.messages, summary: args?.summary })
|
|
343
|
+
break
|
|
344
|
+
default:
|
|
345
|
+
throw new Error(`Unknown tool: ${name}`)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
jsonrpc: '2.0',
|
|
350
|
+
id,
|
|
351
|
+
result: {
|
|
352
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
case 'notifications/initialized':
|
|
357
|
+
// Client acknowledged initialization - no response needed
|
|
358
|
+
return null
|
|
359
|
+
|
|
360
|
+
default:
|
|
361
|
+
return {
|
|
362
|
+
jsonrpc: '2.0',
|
|
363
|
+
id,
|
|
364
|
+
error: { code: -32601, message: `Method not found: ${method}` }
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
} catch (error) {
|
|
368
|
+
return {
|
|
369
|
+
jsonrpc: '2.0',
|
|
370
|
+
id,
|
|
371
|
+
error: { code: -32000, message: error.message }
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Main: stdio JSON-RPC loop
|
|
377
|
+
async function main() {
|
|
378
|
+
const rl = createInterface({
|
|
379
|
+
input: process.stdin,
|
|
380
|
+
output: process.stdout,
|
|
381
|
+
terminal: false
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
for await (const line of rl) {
|
|
385
|
+
if (!line.trim()) continue
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
const request = JSON.parse(line)
|
|
389
|
+
const response = await handleRequest(request)
|
|
390
|
+
|
|
391
|
+
if (response) {
|
|
392
|
+
console.log(JSON.stringify(response))
|
|
393
|
+
}
|
|
394
|
+
} catch (error) {
|
|
395
|
+
console.log(JSON.stringify({
|
|
396
|
+
jsonrpc: '2.0',
|
|
397
|
+
id: null,
|
|
398
|
+
error: { code: -32700, message: 'Parse error' }
|
|
399
|
+
}))
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
main().catch(console.error)
|