@recall_v3/mcp-server 0.1.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.
Files changed (50) hide show
  1. package/dist/api/client.d.ts +111 -0
  2. package/dist/api/client.d.ts.map +1 -0
  3. package/dist/api/client.js +244 -0
  4. package/dist/config/index.d.ts +89 -0
  5. package/dist/config/index.d.ts.map +1 -0
  6. package/dist/config/index.js +256 -0
  7. package/dist/crypto/index.d.ts +56 -0
  8. package/dist/crypto/index.d.ts.map +1 -0
  9. package/dist/crypto/index.js +224 -0
  10. package/dist/index.d.ts +10 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +189 -0
  13. package/dist/tools/getContext.d.ts +18 -0
  14. package/dist/tools/getContext.d.ts.map +1 -0
  15. package/dist/tools/getContext.js +87 -0
  16. package/dist/tools/getHistory.d.ts +18 -0
  17. package/dist/tools/getHistory.d.ts.map +1 -0
  18. package/dist/tools/getHistory.js +97 -0
  19. package/dist/tools/getTranscripts.d.ts +19 -0
  20. package/dist/tools/getTranscripts.d.ts.map +1 -0
  21. package/dist/tools/getTranscripts.js +129 -0
  22. package/dist/tools/index.d.ts +13 -0
  23. package/dist/tools/index.d.ts.map +1 -0
  24. package/dist/tools/index.js +37 -0
  25. package/dist/tools/logDecision.d.ts +19 -0
  26. package/dist/tools/logDecision.d.ts.map +1 -0
  27. package/dist/tools/logDecision.js +92 -0
  28. package/dist/tools/saveSession.d.ts +26 -0
  29. package/dist/tools/saveSession.d.ts.map +1 -0
  30. package/dist/tools/saveSession.js +115 -0
  31. package/dist/tools/types.d.ts +32 -0
  32. package/dist/tools/types.d.ts.map +1 -0
  33. package/dist/tools/types.js +33 -0
  34. package/dist/tools/utils.d.ts +52 -0
  35. package/dist/tools/utils.d.ts.map +1 -0
  36. package/dist/tools/utils.js +238 -0
  37. package/package.json +46 -0
  38. package/src/api/client.ts +295 -0
  39. package/src/config/index.ts +247 -0
  40. package/src/crypto/index.ts +207 -0
  41. package/src/index.ts +232 -0
  42. package/src/tools/getContext.ts +106 -0
  43. package/src/tools/getHistory.ts +118 -0
  44. package/src/tools/getTranscripts.ts +150 -0
  45. package/src/tools/index.ts +13 -0
  46. package/src/tools/logDecision.ts +118 -0
  47. package/src/tools/saveSession.ts +159 -0
  48. package/src/tools/types.ts +47 -0
  49. package/src/tools/utils.ts +226 -0
  50. package/tsconfig.json +14 -0
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ /**
3
+ * Recall Configuration Management
4
+ *
5
+ * Manages the local config file at ~/.recall/config.json.
6
+ * Handles secure storage of API tokens and team keys.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.getConfigDir = getConfigDir;
43
+ exports.getConfigPath = getConfigPath;
44
+ exports.loadConfig = loadConfig;
45
+ exports.saveConfig = saveConfig;
46
+ exports.getApiBaseUrl = getApiBaseUrl;
47
+ exports.getApiToken = getApiToken;
48
+ exports.setApiToken = setApiToken;
49
+ exports.getActiveTeamId = getActiveTeamId;
50
+ exports.setActiveTeamId = setActiveTeamId;
51
+ exports.setDefaultTeamId = setDefaultTeamId;
52
+ exports.getTeamKey = getTeamKey;
53
+ exports.setTeamKey = setTeamKey;
54
+ exports.setUserInfo = setUserInfo;
55
+ exports.setLastSyncAt = setLastSyncAt;
56
+ exports.isAuthenticated = isAuthenticated;
57
+ exports.clearAuth = clearAuth;
58
+ exports.getExtendedConfig = getExtendedConfig;
59
+ const fs = __importStar(require("node:fs"));
60
+ const path = __importStar(require("node:path"));
61
+ const os = __importStar(require("node:os"));
62
+ // Current config file version
63
+ const CONFIG_VERSION = 1;
64
+ // Default API base URL (v3)
65
+ const DEFAULT_API_BASE_URL = 'https://api-v3.recall.team';
66
+ /**
67
+ * Get the path to the Recall config directory
68
+ */
69
+ function getConfigDir() {
70
+ return path.join(os.homedir(), '.recall');
71
+ }
72
+ /**
73
+ * Get the path to the config file
74
+ */
75
+ function getConfigPath() {
76
+ return path.join(getConfigDir(), 'config.json');
77
+ }
78
+ /**
79
+ * Ensure the config directory exists with secure permissions
80
+ */
81
+ function ensureConfigDir() {
82
+ const configDir = getConfigDir();
83
+ if (!fs.existsSync(configDir)) {
84
+ fs.mkdirSync(configDir, { mode: 0o700, recursive: true });
85
+ }
86
+ }
87
+ /**
88
+ * Create a default empty config
89
+ */
90
+ function createDefaultConfig() {
91
+ return {
92
+ token: '',
93
+ defaultTeamId: null,
94
+ activeTeamId: null,
95
+ teamKeys: {},
96
+ user: null,
97
+ lastSyncAt: null,
98
+ version: CONFIG_VERSION,
99
+ };
100
+ }
101
+ /**
102
+ * Migrate old config format to new if necessary
103
+ */
104
+ function migrateConfig(config) {
105
+ const migrated = { ...createDefaultConfig(), ...config };
106
+ // Future migration logic would go here
107
+ // For now, just ensure version is set
108
+ migrated.version = CONFIG_VERSION;
109
+ return migrated;
110
+ }
111
+ /**
112
+ * Load configuration from disk
113
+ * Returns a default config if the file doesn't exist
114
+ */
115
+ function loadConfig() {
116
+ const configPath = getConfigPath();
117
+ if (!fs.existsSync(configPath)) {
118
+ return createDefaultConfig();
119
+ }
120
+ try {
121
+ const raw = fs.readFileSync(configPath, 'utf-8');
122
+ const parsed = JSON.parse(raw);
123
+ // Migrate if necessary
124
+ if (!parsed.version || parsed.version < CONFIG_VERSION) {
125
+ const migrated = migrateConfig(parsed);
126
+ saveConfig(migrated);
127
+ return migrated;
128
+ }
129
+ return migrateConfig(parsed);
130
+ }
131
+ catch (error) {
132
+ // If config is corrupted, return default
133
+ console.error('Warning: Could not load Recall config, using defaults');
134
+ return createDefaultConfig();
135
+ }
136
+ }
137
+ /**
138
+ * Save configuration to disk with secure permissions (0600)
139
+ */
140
+ function saveConfig(config) {
141
+ ensureConfigDir();
142
+ const current = loadConfig();
143
+ const merged = {
144
+ ...current,
145
+ ...config,
146
+ version: CONFIG_VERSION,
147
+ };
148
+ const configPath = getConfigPath();
149
+ const json = JSON.stringify(merged, null, 2);
150
+ // Write with secure permissions (0600 = owner read/write only)
151
+ fs.writeFileSync(configPath, json, { mode: 0o600 });
152
+ }
153
+ /**
154
+ * Get the API base URL from config or environment
155
+ */
156
+ function getApiBaseUrl() {
157
+ // Environment variable takes precedence (for development)
158
+ const envUrl = process.env.RECALL_API_URL;
159
+ if (envUrl) {
160
+ return envUrl;
161
+ }
162
+ return DEFAULT_API_BASE_URL;
163
+ }
164
+ /**
165
+ * Get the API token from config or environment
166
+ */
167
+ function getApiToken() {
168
+ // Environment variable takes precedence
169
+ const envToken = process.env.RECALL_API_TOKEN;
170
+ if (envToken) {
171
+ return envToken;
172
+ }
173
+ const config = loadConfig();
174
+ return config.token || null;
175
+ }
176
+ /**
177
+ * Store the API token securely
178
+ */
179
+ function setApiToken(token) {
180
+ saveConfig({ token });
181
+ }
182
+ /**
183
+ * Get the active team ID
184
+ */
185
+ function getActiveTeamId() {
186
+ const config = loadConfig();
187
+ return config.activeTeamId ?? config.defaultTeamId ?? null;
188
+ }
189
+ /**
190
+ * Set the active team ID for this session
191
+ */
192
+ function setActiveTeamId(teamId) {
193
+ saveConfig({ activeTeamId: teamId });
194
+ }
195
+ /**
196
+ * Set the default team ID
197
+ */
198
+ function setDefaultTeamId(teamId) {
199
+ saveConfig({ defaultTeamId: teamId, activeTeamId: teamId });
200
+ }
201
+ /**
202
+ * Get a cached team encryption key
203
+ */
204
+ function getTeamKey(teamId) {
205
+ const config = loadConfig();
206
+ return config.teamKeys[teamId] ?? null;
207
+ }
208
+ /**
209
+ * Cache a team encryption key
210
+ */
211
+ function setTeamKey(teamId, key) {
212
+ const config = loadConfig();
213
+ const teamKeys = { ...config.teamKeys, [teamId]: key };
214
+ saveConfig({ teamKeys });
215
+ }
216
+ /**
217
+ * Update cached user info
218
+ */
219
+ function setUserInfo(user) {
220
+ saveConfig({ user });
221
+ }
222
+ /**
223
+ * Update last sync timestamp
224
+ */
225
+ function setLastSyncAt(timestamp) {
226
+ saveConfig({ lastSyncAt: timestamp });
227
+ }
228
+ /**
229
+ * Check if the user is authenticated (has a token)
230
+ */
231
+ function isAuthenticated() {
232
+ return !!getApiToken();
233
+ }
234
+ /**
235
+ * Clear all authentication data (logout)
236
+ */
237
+ function clearAuth() {
238
+ saveConfig({
239
+ token: '',
240
+ activeTeamId: null,
241
+ teamKeys: {},
242
+ user: null,
243
+ lastSyncAt: null,
244
+ });
245
+ }
246
+ /**
247
+ * Get the full extended config
248
+ */
249
+ function getExtendedConfig() {
250
+ const config = loadConfig();
251
+ return {
252
+ ...config,
253
+ apiBaseUrl: getApiBaseUrl(),
254
+ isAuthenticated: isAuthenticated(),
255
+ };
256
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Recall Encryption Utilities
3
+ *
4
+ * AES-256-GCM encryption/decryption compatible with Web Crypto API.
5
+ * Uses Node.js crypto module for server-side operations.
6
+ */
7
+ import type { EncryptedPayload } from '@recall_v3/shared';
8
+ /**
9
+ * Generate a cryptographically secure random IV
10
+ */
11
+ export declare function generateIV(): Uint8Array;
12
+ /**
13
+ * Generate a new AES-256 encryption key
14
+ * Returns base64-encoded key
15
+ */
16
+ export declare function generateKey(): string;
17
+ /**
18
+ * Encrypt plaintext using AES-256-GCM
19
+ *
20
+ * @param plaintext - The string to encrypt
21
+ * @param keyBase64 - Base64-encoded 256-bit key
22
+ * @returns EncryptedPayload with base64-encoded ciphertext, iv, and tag
23
+ */
24
+ export declare function encrypt(plaintext: string, keyBase64: string): EncryptedPayload;
25
+ /**
26
+ * Decrypt an encrypted payload using AES-256-GCM
27
+ *
28
+ * @param payload - EncryptedPayload with base64-encoded values
29
+ * @param keyBase64 - Base64-encoded 256-bit key
30
+ * @returns Decrypted plaintext string
31
+ */
32
+ export declare function decrypt(payload: EncryptedPayload, keyBase64: string): string;
33
+ /**
34
+ * Parse an encrypted string into an EncryptedPayload
35
+ * The format is: base64(iv):base64(tag):base64(ciphertext)
36
+ * This is an alternative compact format for storage
37
+ */
38
+ export declare function parseEncryptedString(encrypted: string): EncryptedPayload;
39
+ /**
40
+ * Serialize an EncryptedPayload to a compact string
41
+ * Format: base64(iv):base64(tag):base64(ciphertext)
42
+ */
43
+ export declare function serializeEncrypted(payload: EncryptedPayload): string;
44
+ /**
45
+ * Check if a string looks like an encrypted payload
46
+ */
47
+ export declare function isEncryptedString(str: string): boolean;
48
+ /**
49
+ * Decrypt content that might be in either format (JSON or compact string)
50
+ */
51
+ export declare function decryptContent(encrypted: string, keyBase64: string): string;
52
+ /**
53
+ * Encrypt content and return as JSON string
54
+ */
55
+ export declare function encryptContent(plaintext: string, keyBase64: string): string;
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAO1D;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAEvC;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,CA+B9E;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA0C5E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAWxE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA8BtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAY3E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG3E"}
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ /**
3
+ * Recall Encryption Utilities
4
+ *
5
+ * AES-256-GCM encryption/decryption compatible with Web Crypto API.
6
+ * Uses Node.js crypto module for server-side operations.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.generateIV = generateIV;
43
+ exports.generateKey = generateKey;
44
+ exports.encrypt = encrypt;
45
+ exports.decrypt = decrypt;
46
+ exports.parseEncryptedString = parseEncryptedString;
47
+ exports.serializeEncrypted = serializeEncrypted;
48
+ exports.isEncryptedString = isEncryptedString;
49
+ exports.decryptContent = decryptContent;
50
+ exports.encryptContent = encryptContent;
51
+ const crypto = __importStar(require("node:crypto"));
52
+ // AES-256-GCM constants
53
+ const ALGORITHM = 'aes-256-gcm';
54
+ const IV_LENGTH = 12; // 96 bits for GCM
55
+ const TAG_LENGTH = 16; // 128 bits for GCM auth tag
56
+ /**
57
+ * Generate a cryptographically secure random IV
58
+ */
59
+ function generateIV() {
60
+ return crypto.randomBytes(IV_LENGTH);
61
+ }
62
+ /**
63
+ * Generate a new AES-256 encryption key
64
+ * Returns base64-encoded key
65
+ */
66
+ function generateKey() {
67
+ const key = crypto.randomBytes(32); // 256 bits
68
+ return key.toString('base64');
69
+ }
70
+ /**
71
+ * Encrypt plaintext using AES-256-GCM
72
+ *
73
+ * @param plaintext - The string to encrypt
74
+ * @param keyBase64 - Base64-encoded 256-bit key
75
+ * @returns EncryptedPayload with base64-encoded ciphertext, iv, and tag
76
+ */
77
+ function encrypt(plaintext, keyBase64) {
78
+ // Decode the key
79
+ const key = Buffer.from(keyBase64, 'base64');
80
+ if (key.length !== 32) {
81
+ throw new Error(`Invalid key length: expected 32 bytes, got ${key.length}`);
82
+ }
83
+ // Generate a random IV
84
+ const iv = generateIV();
85
+ // Create cipher
86
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv, {
87
+ authTagLength: TAG_LENGTH,
88
+ });
89
+ // Encrypt
90
+ const encrypted = Buffer.concat([
91
+ cipher.update(plaintext, 'utf8'),
92
+ cipher.final(),
93
+ ]);
94
+ // Get auth tag
95
+ const tag = cipher.getAuthTag();
96
+ // Return base64-encoded values
97
+ return {
98
+ ciphertext: encrypted.toString('base64'),
99
+ iv: Buffer.from(iv).toString('base64'),
100
+ tag: tag.toString('base64'),
101
+ };
102
+ }
103
+ /**
104
+ * Decrypt an encrypted payload using AES-256-GCM
105
+ *
106
+ * @param payload - EncryptedPayload with base64-encoded values
107
+ * @param keyBase64 - Base64-encoded 256-bit key
108
+ * @returns Decrypted plaintext string
109
+ */
110
+ function decrypt(payload, keyBase64) {
111
+ // Decode all components
112
+ const key = Buffer.from(keyBase64, 'base64');
113
+ const iv = Buffer.from(payload.iv, 'base64');
114
+ const ciphertext = Buffer.from(payload.ciphertext, 'base64');
115
+ const tag = Buffer.from(payload.tag, 'base64');
116
+ if (key.length !== 32) {
117
+ throw new Error(`Invalid key length: expected 32 bytes, got ${key.length}`);
118
+ }
119
+ if (iv.length !== IV_LENGTH) {
120
+ throw new Error(`Invalid IV length: expected ${IV_LENGTH} bytes, got ${iv.length}`);
121
+ }
122
+ if (tag.length !== TAG_LENGTH) {
123
+ throw new Error(`Invalid tag length: expected ${TAG_LENGTH} bytes, got ${tag.length}`);
124
+ }
125
+ // Create decipher
126
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv, {
127
+ authTagLength: TAG_LENGTH,
128
+ });
129
+ // Set auth tag
130
+ decipher.setAuthTag(tag);
131
+ // Decrypt
132
+ try {
133
+ const decrypted = Buffer.concat([
134
+ decipher.update(ciphertext),
135
+ decipher.final(),
136
+ ]);
137
+ return decrypted.toString('utf8');
138
+ }
139
+ catch (error) {
140
+ // GCM authentication failure
141
+ if (error instanceof Error && error.message.includes('Unsupported state')) {
142
+ throw new Error('Decryption failed: authentication tag mismatch');
143
+ }
144
+ throw error;
145
+ }
146
+ }
147
+ /**
148
+ * Parse an encrypted string into an EncryptedPayload
149
+ * The format is: base64(iv):base64(tag):base64(ciphertext)
150
+ * This is an alternative compact format for storage
151
+ */
152
+ function parseEncryptedString(encrypted) {
153
+ const parts = encrypted.split(':');
154
+ if (parts.length !== 3) {
155
+ throw new Error('Invalid encrypted string format');
156
+ }
157
+ return {
158
+ iv: parts[0],
159
+ tag: parts[1],
160
+ ciphertext: parts[2],
161
+ };
162
+ }
163
+ /**
164
+ * Serialize an EncryptedPayload to a compact string
165
+ * Format: base64(iv):base64(tag):base64(ciphertext)
166
+ */
167
+ function serializeEncrypted(payload) {
168
+ return `${payload.iv}:${payload.tag}:${payload.ciphertext}`;
169
+ }
170
+ /**
171
+ * Check if a string looks like an encrypted payload
172
+ */
173
+ function isEncryptedString(str) {
174
+ // Check for compact format (iv:tag:ciphertext)
175
+ if (str.includes(':')) {
176
+ const parts = str.split(':');
177
+ if (parts.length === 3) {
178
+ // Each part should be valid base64
179
+ return parts.every(part => {
180
+ try {
181
+ Buffer.from(part, 'base64');
182
+ return true;
183
+ }
184
+ catch {
185
+ return false;
186
+ }
187
+ });
188
+ }
189
+ }
190
+ // Check for JSON format
191
+ try {
192
+ const parsed = JSON.parse(str);
193
+ return (typeof parsed === 'object' &&
194
+ parsed !== null &&
195
+ 'ciphertext' in parsed &&
196
+ 'iv' in parsed &&
197
+ 'tag' in parsed);
198
+ }
199
+ catch {
200
+ return false;
201
+ }
202
+ }
203
+ /**
204
+ * Decrypt content that might be in either format (JSON or compact string)
205
+ */
206
+ function decryptContent(encrypted, keyBase64) {
207
+ let payload;
208
+ // Try JSON format first
209
+ try {
210
+ payload = JSON.parse(encrypted);
211
+ }
212
+ catch {
213
+ // Try compact string format
214
+ payload = parseEncryptedString(encrypted);
215
+ }
216
+ return decrypt(payload, keyBase64);
217
+ }
218
+ /**
219
+ * Encrypt content and return as JSON string
220
+ */
221
+ function encryptContent(plaintext, keyBase64) {
222
+ const payload = encrypt(plaintext, keyBase64);
223
+ return JSON.stringify(payload);
224
+ }
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Recall MCP Server v3
4
+ * Local MCP server for AI coding assistants
5
+ *
6
+ * This package provides the local MCP server that connects
7
+ * to the Recall API for team memory synchronization.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"}