cc-forever-mcp 1.0.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/dist/chunker.d.ts +13 -0
- package/dist/chunker.d.ts.map +1 -0
- package/dist/chunker.js +53 -0
- package/dist/chunker.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +98 -0
- package/dist/config.js.map +1 -0
- package/dist/embedder.d.ts +18 -0
- package/dist/embedder.d.ts.map +1 -0
- package/dist/embedder.js +58 -0
- package/dist/embedder.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +300 -0
- package/dist/index.js.map +1 -0
- package/dist/vectorstore.d.ts +37 -0
- package/dist/vectorstore.d.ts.map +1 -0
- package/dist/vectorstore.js +89 -0
- package/dist/vectorstore.js.map +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation chunker - Parse Human/Assistant pairs
|
|
3
|
+
*/
|
|
4
|
+
interface Chunk {
|
|
5
|
+
text: string;
|
|
6
|
+
question: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parse conversation into Q&A pairs
|
|
10
|
+
*/
|
|
11
|
+
export declare function chunkConversation(content: string): Chunk[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=chunker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,CAmD1D"}
|
package/dist/chunker.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation chunker - Parse Human/Assistant pairs
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Parse conversation into Q&A pairs
|
|
6
|
+
*/
|
|
7
|
+
export function chunkConversation(content) {
|
|
8
|
+
const chunks = [];
|
|
9
|
+
const lines = content.split('\n');
|
|
10
|
+
let currentRole = null;
|
|
11
|
+
let currentContent = [];
|
|
12
|
+
let humanQuestion = '';
|
|
13
|
+
const rolePattern = /^(Human|User|Assistant|Claude):\s*/i;
|
|
14
|
+
for (const line of lines) {
|
|
15
|
+
const match = line.match(rolePattern);
|
|
16
|
+
if (match) {
|
|
17
|
+
const role = match[1].toLowerCase();
|
|
18
|
+
const newRole = role === 'human' || role === 'user' ? 'human' : 'assistant';
|
|
19
|
+
const textAfterRole = line.slice(match[0].length);
|
|
20
|
+
// Save previous content
|
|
21
|
+
if (currentRole === 'human' && currentContent.length > 0) {
|
|
22
|
+
humanQuestion = currentContent.join('\n').trim();
|
|
23
|
+
}
|
|
24
|
+
else if (currentRole === 'assistant' && humanQuestion && currentContent.length > 0) {
|
|
25
|
+
const answer = currentContent.join('\n').trim();
|
|
26
|
+
if (answer) {
|
|
27
|
+
chunks.push({
|
|
28
|
+
text: `Human: ${humanQuestion}\nAssistant: ${answer}`,
|
|
29
|
+
question: humanQuestion.slice(0, 200),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
humanQuestion = '';
|
|
33
|
+
}
|
|
34
|
+
currentRole = newRole;
|
|
35
|
+
currentContent = textAfterRole ? [textAfterRole] : [];
|
|
36
|
+
}
|
|
37
|
+
else if (currentRole) {
|
|
38
|
+
currentContent.push(line);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Handle last pair
|
|
42
|
+
if (currentRole === 'assistant' && humanQuestion && currentContent.length > 0) {
|
|
43
|
+
const answer = currentContent.join('\n').trim();
|
|
44
|
+
if (answer) {
|
|
45
|
+
chunks.push({
|
|
46
|
+
text: `Human: ${humanQuestion}\nAssistant: ${answer}`,
|
|
47
|
+
question: humanQuestion.slice(0, 200),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return chunks;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=chunker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAY,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEjC,IAAI,WAAW,GAAiC,IAAI,CAAA;IACpD,IAAI,cAAc,GAAa,EAAE,CAAA;IACjC,IAAI,aAAa,GAAG,EAAE,CAAA;IAEtB,MAAM,WAAW,GAAG,qCAAqC,CAAA;IAEzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAErC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;YACnC,MAAM,OAAO,GAAG,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAA;YAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YAEjD,wBAAwB;YACxB,IAAI,WAAW,KAAK,OAAO,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzD,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;YAClD,CAAC;iBAAM,IAAI,WAAW,KAAK,WAAW,IAAI,aAAa,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrF,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC/C,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,UAAU,aAAa,gBAAgB,MAAM,EAAE;wBACrD,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;qBACtC,CAAC,CAAA;gBACJ,CAAC;gBACD,aAAa,GAAG,EAAE,CAAA;YACpB,CAAC;YAED,WAAW,GAAG,OAAO,CAAA;YACrB,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACvD,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,WAAW,KAAK,WAAW,IAAI,aAAa,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9E,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;QAC/C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,UAAU,aAAa,gBAAgB,MAAM,EAAE;gBACrD,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aACtC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loader
|
|
3
|
+
*/
|
|
4
|
+
export interface Config {
|
|
5
|
+
embeddings?: {
|
|
6
|
+
path?: string;
|
|
7
|
+
};
|
|
8
|
+
data_dir?: string;
|
|
9
|
+
auto_index?: boolean;
|
|
10
|
+
source?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Load config with priority:
|
|
14
|
+
* 1. Project-level: ./.forever/config.yml
|
|
15
|
+
* 2. User-level: ~/.forever/config.yml
|
|
16
|
+
* 3. Default settings
|
|
17
|
+
*
|
|
18
|
+
* data_dir is automatically set to the directory containing the config file
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadConfig(): Config;
|
|
21
|
+
/**
|
|
22
|
+
* Get data directory path
|
|
23
|
+
*/
|
|
24
|
+
export declare function getDataDir(config: Config): string;
|
|
25
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,MAAM;IACrB,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,MAAM,CA6BnC;AA+CD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASjD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loader
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import * as os from 'node:os';
|
|
7
|
+
/**
|
|
8
|
+
* Load config with priority:
|
|
9
|
+
* 1. Project-level: ./.forever/config.yml
|
|
10
|
+
* 2. User-level: ~/.forever/config.yml
|
|
11
|
+
* 3. Default settings
|
|
12
|
+
*
|
|
13
|
+
* data_dir is automatically set to the directory containing the config file
|
|
14
|
+
*/
|
|
15
|
+
export function loadConfig() {
|
|
16
|
+
// Priority 1: Project-level
|
|
17
|
+
const projectDir = path.join(process.cwd(), '.forever');
|
|
18
|
+
const projectConfig = path.join(projectDir, 'config.yml');
|
|
19
|
+
if (fs.existsSync(projectConfig)) {
|
|
20
|
+
return {
|
|
21
|
+
...parseYaml(projectConfig),
|
|
22
|
+
data_dir: projectDir,
|
|
23
|
+
source: projectConfig,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// Priority 2: User-level
|
|
27
|
+
const userDir = path.join(os.homedir(), '.forever');
|
|
28
|
+
const userConfig = path.join(userDir, 'config.yml');
|
|
29
|
+
if (fs.existsSync(userConfig)) {
|
|
30
|
+
return {
|
|
31
|
+
...parseYaml(userConfig),
|
|
32
|
+
data_dir: userDir,
|
|
33
|
+
source: userConfig,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// Priority 3: Default (user-level)
|
|
37
|
+
return {
|
|
38
|
+
embeddings: { path: 'Xenova/all-MiniLM-L6-v2' },
|
|
39
|
+
data_dir: path.join(os.homedir(), '.forever'),
|
|
40
|
+
source: 'default',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Simple YAML parser (handles basic key: value pairs)
|
|
45
|
+
*/
|
|
46
|
+
function parseYaml(filePath) {
|
|
47
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
48
|
+
const config = {};
|
|
49
|
+
let currentSection = '';
|
|
50
|
+
for (const line of content.split('\n')) {
|
|
51
|
+
const trimmed = line.trim();
|
|
52
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
53
|
+
continue;
|
|
54
|
+
// Check indentation for nested values
|
|
55
|
+
const indent = line.length - line.trimStart().length;
|
|
56
|
+
if (indent === 0 && trimmed.includes(':')) {
|
|
57
|
+
const [key, ...valueParts] = trimmed.split(':');
|
|
58
|
+
const value = valueParts.join(':').trim();
|
|
59
|
+
if (value) {
|
|
60
|
+
config[key.trim()] = parseValue(value);
|
|
61
|
+
currentSection = '';
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
currentSection = key.trim();
|
|
65
|
+
config[currentSection] = {};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (indent > 0 && currentSection && trimmed.includes(':')) {
|
|
69
|
+
const [key, ...valueParts] = trimmed.split(':');
|
|
70
|
+
const value = valueParts.join(':').trim();
|
|
71
|
+
config[currentSection][key.trim()] = parseValue(value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return config;
|
|
75
|
+
}
|
|
76
|
+
function parseValue(value) {
|
|
77
|
+
if (value.toLowerCase() === 'true')
|
|
78
|
+
return true;
|
|
79
|
+
if (value.toLowerCase() === 'false')
|
|
80
|
+
return false;
|
|
81
|
+
if (/^\d+$/.test(value))
|
|
82
|
+
return parseInt(value, 10);
|
|
83
|
+
if (/^\d+\.\d+$/.test(value))
|
|
84
|
+
return parseFloat(value);
|
|
85
|
+
return value.replace(/^["']|["']$/g, '');
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get data directory path
|
|
89
|
+
*/
|
|
90
|
+
export function getDataDir(config) {
|
|
91
|
+
const dir = config.data_dir || path.join(os.homedir(), '.forever');
|
|
92
|
+
const expanded = dir.startsWith('~') ? dir.replace('~', os.homedir()) : dir;
|
|
93
|
+
if (!fs.existsSync(expanded)) {
|
|
94
|
+
fs.mkdirSync(expanded, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
return expanded;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedder implementation with Transformers.js
|
|
3
|
+
*/
|
|
4
|
+
export interface EmbedderConfig {
|
|
5
|
+
modelPath: string;
|
|
6
|
+
batchSize: number;
|
|
7
|
+
cacheDir: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class Embedder {
|
|
10
|
+
private model;
|
|
11
|
+
private initPromise;
|
|
12
|
+
private readonly config;
|
|
13
|
+
constructor(config: EmbedderConfig);
|
|
14
|
+
initialize(): Promise<void>;
|
|
15
|
+
private ensureInitialized;
|
|
16
|
+
embed(text: string): Promise<number[]>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=embedder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedder.d.ts","sourceRoot":"","sources":["../src/embedder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAMD,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,MAAM,EAAE,cAAc;IAI5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAanB,iBAAiB;IAkBzB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAoB7C"}
|
package/dist/embedder.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedder implementation with Transformers.js
|
|
3
|
+
*/
|
|
4
|
+
import { env, pipeline } from '@huggingface/transformers';
|
|
5
|
+
// ============================================
|
|
6
|
+
// Embedder Class
|
|
7
|
+
// ============================================
|
|
8
|
+
export class Embedder {
|
|
9
|
+
model = null;
|
|
10
|
+
initPromise = null;
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
async initialize() {
|
|
16
|
+
if (this.model)
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
env.cacheDir = this.config.cacheDir;
|
|
20
|
+
console.error(`Embedder: Loading model "${this.config.modelPath}"...`);
|
|
21
|
+
this.model = await pipeline('feature-extraction', this.config.modelPath);
|
|
22
|
+
console.error('Embedder: Model loaded successfully');
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error(`Failed to initialize Embedder: ${error.message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async ensureInitialized() {
|
|
29
|
+
if (this.model)
|
|
30
|
+
return;
|
|
31
|
+
if (this.initPromise) {
|
|
32
|
+
await this.initPromise;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.error('Embedder: First use detected. Loading model (may take 1-2 minutes on first run)...');
|
|
36
|
+
this.initPromise = this.initialize().catch((error) => {
|
|
37
|
+
this.initPromise = null;
|
|
38
|
+
throw error;
|
|
39
|
+
});
|
|
40
|
+
await this.initPromise;
|
|
41
|
+
}
|
|
42
|
+
async embed(text) {
|
|
43
|
+
await this.ensureInitialized();
|
|
44
|
+
if (text.length === 0) {
|
|
45
|
+
throw new Error('Cannot generate embedding for empty text');
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const options = { pooling: 'mean', normalize: true };
|
|
49
|
+
const modelCall = this.model;
|
|
50
|
+
const output = await modelCall(text, options);
|
|
51
|
+
return Array.from(output.data);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throw new Error(`Failed to generate embedding: ${error.message}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=embedder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedder.js","sourceRoot":"","sources":["../src/embedder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AAYzD,+CAA+C;AAC/C,iBAAiB;AACjB,+CAA+C;AAE/C,MAAM,OAAO,QAAQ;IACX,KAAK,GAAY,IAAI,CAAA;IACrB,WAAW,GAAyB,IAAI,CAAA;IAC/B,MAAM,CAAgB;IAEvC,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QAEtB,IAAI,CAAC;YACH,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAA;YACnC,OAAO,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,MAAM,CAAC,SAAS,MAAM,CAAC,CAAA;YACtE,IAAI,CAAC,KAAK,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACxE,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAA;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,kCAAmC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QAEtB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,WAAW,CAAA;YACtB,OAAM;QACR,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAA;QAEnG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACnD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;YACvB,MAAM,KAAK,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,WAAW,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAA;QAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;QAC7D,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;YACpD,MAAM,SAAS,GAAG,IAAI,CAAC,KAGa,CAAA;YACpC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAA;QAC9E,CAAC;IACH,CAAC;CAEF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CC-Forever MCP Server
|
|
4
|
+
* Persistent conversation memory with semantic search
|
|
5
|
+
*
|
|
6
|
+
* Uses LanceDB + Transformers.js for lightweight local embeddings
|
|
7
|
+
*/
|
|
8
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
9
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { VectorStore } from './vectorstore.js';
|
|
12
|
+
import { Embedder } from './embedder.js';
|
|
13
|
+
import { chunkConversation } from './chunker.js';
|
|
14
|
+
import { loadConfig, getDataDir } from './config.js';
|
|
15
|
+
// ============================================
|
|
16
|
+
// Main Server
|
|
17
|
+
// ============================================
|
|
18
|
+
class CCForeverServer {
|
|
19
|
+
server;
|
|
20
|
+
vectorStore = null;
|
|
21
|
+
embedder = null;
|
|
22
|
+
config = null;
|
|
23
|
+
initialized = false;
|
|
24
|
+
constructor() {
|
|
25
|
+
this.server = new Server({ name: 'cc-forever-mcp', version: '1.0.0' }, { capabilities: { tools: {} } });
|
|
26
|
+
this.setupHandlers();
|
|
27
|
+
}
|
|
28
|
+
setupHandlers() {
|
|
29
|
+
// List tools
|
|
30
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
31
|
+
tools: [
|
|
32
|
+
{
|
|
33
|
+
name: 'store_memory',
|
|
34
|
+
description: "Store Q&A conversation pairs in the memory index. Content MUST include both Human question AND Assistant answer. Example format: 'Human: How do I use OAuth?\\nAssistant: OAuth is an authentication protocol...'",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
content: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
description: "Conversation in 'Human: <question>\\nAssistant: <answer>' format. MUST include both Human and Assistant parts.",
|
|
41
|
+
},
|
|
42
|
+
project: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'Project name (optional)',
|
|
45
|
+
},
|
|
46
|
+
tags: {
|
|
47
|
+
type: 'array',
|
|
48
|
+
items: { type: 'string' },
|
|
49
|
+
description: 'Tags (optional)',
|
|
50
|
+
},
|
|
51
|
+
chunk: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
description: 'Whether to chunk into Q&A pairs (default: true)',
|
|
54
|
+
default: true,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ['content'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'retrieve_memory',
|
|
62
|
+
description: 'Search past conversations using semantic search',
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: {
|
|
66
|
+
query: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'Search query',
|
|
69
|
+
},
|
|
70
|
+
n_results: {
|
|
71
|
+
type: 'integer',
|
|
72
|
+
description: 'Number of results to return (default: 5)',
|
|
73
|
+
default: 5,
|
|
74
|
+
},
|
|
75
|
+
threshold: {
|
|
76
|
+
type: 'number',
|
|
77
|
+
description: 'Similarity threshold 0-1 (default: 0.3)',
|
|
78
|
+
default: 0.3,
|
|
79
|
+
},
|
|
80
|
+
project: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: 'Filter by project name (optional)',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
required: ['query'],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'get_stats',
|
|
90
|
+
description: 'Get index statistics and configuration info',
|
|
91
|
+
inputSchema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
}));
|
|
98
|
+
// Call tool
|
|
99
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
100
|
+
const { name, arguments: args } = request.params;
|
|
101
|
+
try {
|
|
102
|
+
// Lazy initialization
|
|
103
|
+
if (!this.initialized) {
|
|
104
|
+
await this.initialize();
|
|
105
|
+
}
|
|
106
|
+
switch (name) {
|
|
107
|
+
case 'store_memory':
|
|
108
|
+
return await this.storeMemory(args);
|
|
109
|
+
case 'retrieve_memory':
|
|
110
|
+
return await this.retrieveMemory(args);
|
|
111
|
+
case 'get_stats':
|
|
112
|
+
return await this.getStats();
|
|
113
|
+
default:
|
|
114
|
+
return {
|
|
115
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, error: `Unknown tool: ${name}` }) }],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
content: [
|
|
122
|
+
{
|
|
123
|
+
type: 'text',
|
|
124
|
+
text: JSON.stringify({
|
|
125
|
+
success: false,
|
|
126
|
+
error: `Tool execution failed: ${error.message}`,
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
async initialize() {
|
|
135
|
+
this.config = loadConfig();
|
|
136
|
+
const dataDir = getDataDir(this.config);
|
|
137
|
+
const modelPath = this.config.embeddings?.path || 'Xenova/all-MiniLM-L6-v2';
|
|
138
|
+
const cacheDir = `${dataDir}/models`;
|
|
139
|
+
this.embedder = new Embedder({
|
|
140
|
+
modelPath,
|
|
141
|
+
batchSize: 8,
|
|
142
|
+
cacheDir,
|
|
143
|
+
});
|
|
144
|
+
// Download model on initialization
|
|
145
|
+
console.error('CC-Forever: Downloading embedding model (this may take a moment)...');
|
|
146
|
+
await this.embedder.initialize();
|
|
147
|
+
this.vectorStore = new VectorStore({
|
|
148
|
+
dbPath: `${dataDir}/lancedb`,
|
|
149
|
+
tableName: 'memories',
|
|
150
|
+
});
|
|
151
|
+
await this.vectorStore.initialize();
|
|
152
|
+
this.initialized = true;
|
|
153
|
+
console.error('CC-Forever MCP Server initialized');
|
|
154
|
+
}
|
|
155
|
+
async storeMemory(args) {
|
|
156
|
+
const { content, project, tags, chunk = true } = args;
|
|
157
|
+
// Validation
|
|
158
|
+
if (!content || !content.trim()) {
|
|
159
|
+
return {
|
|
160
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Content cannot be empty' }) }],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
if (content.length > 100000) {
|
|
164
|
+
return {
|
|
165
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Content too large (max 100KB)' }) }],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const timestamp = new Date().toISOString();
|
|
169
|
+
const chunks = chunk ? chunkConversation(content) : [{ text: content, question: content.slice(0, 200) }];
|
|
170
|
+
if (chunks.length === 0) {
|
|
171
|
+
return {
|
|
172
|
+
content: [
|
|
173
|
+
{
|
|
174
|
+
type: 'text',
|
|
175
|
+
text: JSON.stringify({
|
|
176
|
+
success: false,
|
|
177
|
+
error: "No valid Q&A pairs found in content. Format: 'Human: <question>\\nAssistant: <answer>'",
|
|
178
|
+
}),
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Generate embeddings and store
|
|
184
|
+
const documents = [];
|
|
185
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
186
|
+
const c = chunks[i];
|
|
187
|
+
const vector = await this.embedder.embed(c.text);
|
|
188
|
+
documents.push({
|
|
189
|
+
id: `${timestamp}-${i}`,
|
|
190
|
+
text: c.text,
|
|
191
|
+
question: c.question,
|
|
192
|
+
vector,
|
|
193
|
+
project: project || 'default',
|
|
194
|
+
tags: tags?.join(',') || 'conversation',
|
|
195
|
+
timestamp,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
await this.vectorStore.insertChunks(documents);
|
|
199
|
+
return {
|
|
200
|
+
content: [
|
|
201
|
+
{
|
|
202
|
+
type: 'text',
|
|
203
|
+
text: JSON.stringify({
|
|
204
|
+
success: true,
|
|
205
|
+
chunks_stored: chunks.length,
|
|
206
|
+
timestamp,
|
|
207
|
+
}),
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
async retrieveMemory(args) {
|
|
213
|
+
let { query, n_results = 5, threshold = 0.3, project } = args;
|
|
214
|
+
// Validation
|
|
215
|
+
if (!query || !query.trim()) {
|
|
216
|
+
return {
|
|
217
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Query cannot be empty' }) }],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
if (query.length > 10000) {
|
|
221
|
+
return {
|
|
222
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Query too long (max 10KB)' }) }],
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
// Sanitize
|
|
226
|
+
n_results = Math.min(Math.max(n_results, 1), 100);
|
|
227
|
+
threshold = Math.max(0, Math.min(threshold, 1));
|
|
228
|
+
const queryVector = await this.embedder.embed(query);
|
|
229
|
+
const results = await this.vectorStore.search(queryVector, n_results * 2);
|
|
230
|
+
// Filter and format
|
|
231
|
+
const formatted = results
|
|
232
|
+
.filter((r) => {
|
|
233
|
+
// Convert distance to similarity (1 - distance for dot product)
|
|
234
|
+
const similarity = 1 - r.score;
|
|
235
|
+
if (similarity < threshold)
|
|
236
|
+
return false;
|
|
237
|
+
if (project && r.project !== project)
|
|
238
|
+
return false;
|
|
239
|
+
return true;
|
|
240
|
+
})
|
|
241
|
+
.slice(0, n_results)
|
|
242
|
+
.map((r) => ({
|
|
243
|
+
score: Math.round((1 - r.score) * 10000) / 10000,
|
|
244
|
+
question: r.question,
|
|
245
|
+
text: r.text,
|
|
246
|
+
timestamp: r.timestamp,
|
|
247
|
+
project: r.project,
|
|
248
|
+
tags: r.tags,
|
|
249
|
+
}));
|
|
250
|
+
return {
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
253
|
+
type: 'text',
|
|
254
|
+
text: JSON.stringify({
|
|
255
|
+
results: formatted,
|
|
256
|
+
query,
|
|
257
|
+
total_found: formatted.length,
|
|
258
|
+
}),
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
async getStats() {
|
|
264
|
+
const status = await this.vectorStore.getStatus();
|
|
265
|
+
return {
|
|
266
|
+
content: [
|
|
267
|
+
{
|
|
268
|
+
type: 'text',
|
|
269
|
+
text: JSON.stringify({
|
|
270
|
+
success: true,
|
|
271
|
+
total_chunks: status.chunkCount,
|
|
272
|
+
model: this.config?.embeddings?.path || 'Xenova/all-MiniLM-L6-v2',
|
|
273
|
+
data_dir: getDataDir(this.config),
|
|
274
|
+
config_source: this.config?.source || 'default',
|
|
275
|
+
}),
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
async run() {
|
|
281
|
+
const transport = new StdioServerTransport();
|
|
282
|
+
await this.server.connect(transport);
|
|
283
|
+
console.error('CC-Forever MCP Server running on stdio');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// ============================================
|
|
287
|
+
// Entry Point
|
|
288
|
+
// ============================================
|
|
289
|
+
async function main() {
|
|
290
|
+
try {
|
|
291
|
+
const server = new CCForeverServer();
|
|
292
|
+
await server.run();
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
console.error('Failed to start CC-Forever MCP Server:', error);
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
main();
|
|
300
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VectorStore implementation with LanceDB
|
|
3
|
+
*/
|
|
4
|
+
export interface VectorStoreConfig {
|
|
5
|
+
dbPath: string;
|
|
6
|
+
tableName: string;
|
|
7
|
+
}
|
|
8
|
+
export interface MemoryChunk {
|
|
9
|
+
id: string;
|
|
10
|
+
text: string;
|
|
11
|
+
question: string;
|
|
12
|
+
vector: number[];
|
|
13
|
+
project: string;
|
|
14
|
+
tags: string;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SearchResult {
|
|
18
|
+
text: string;
|
|
19
|
+
question: string;
|
|
20
|
+
score: number;
|
|
21
|
+
project: string;
|
|
22
|
+
tags: string;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class VectorStore {
|
|
26
|
+
private db;
|
|
27
|
+
private table;
|
|
28
|
+
private readonly config;
|
|
29
|
+
constructor(config: VectorStoreConfig);
|
|
30
|
+
initialize(): Promise<void>;
|
|
31
|
+
insertChunks(chunks: MemoryChunk[]): Promise<void>;
|
|
32
|
+
search(queryVector: number[], limit?: number): Promise<SearchResult[]>;
|
|
33
|
+
getStatus(): Promise<{
|
|
34
|
+
chunkCount: number;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=vectorstore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectorstore.d.ts","sourceRoot":"","sources":["../src/vectorstore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,MAAM,EAAE,iBAAiB;IAI/B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBlD,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAyBlE,SAAS,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAYnD"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VectorStore implementation with LanceDB
|
|
3
|
+
*/
|
|
4
|
+
import { connect } from '@lancedb/lancedb';
|
|
5
|
+
// ============================================
|
|
6
|
+
// VectorStore Class
|
|
7
|
+
// ============================================
|
|
8
|
+
export class VectorStore {
|
|
9
|
+
db = null;
|
|
10
|
+
table = null;
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
async initialize() {
|
|
16
|
+
try {
|
|
17
|
+
this.db = await connect(this.config.dbPath);
|
|
18
|
+
const tableNames = await this.db.tableNames();
|
|
19
|
+
if (tableNames.includes(this.config.tableName)) {
|
|
20
|
+
this.table = await this.db.openTable(this.config.tableName);
|
|
21
|
+
console.error(`VectorStore: Opened existing table "${this.config.tableName}"`);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.error(`VectorStore: Table "${this.config.tableName}" will be created on first insertion`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new Error(`Failed to initialize VectorStore: ${error.message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async insertChunks(chunks) {
|
|
32
|
+
if (chunks.length === 0)
|
|
33
|
+
return;
|
|
34
|
+
try {
|
|
35
|
+
if (!this.table) {
|
|
36
|
+
if (!this.db) {
|
|
37
|
+
throw new Error('VectorStore is not initialized');
|
|
38
|
+
}
|
|
39
|
+
const records = chunks.map((chunk) => chunk);
|
|
40
|
+
this.table = await this.db.createTable(this.config.tableName, records);
|
|
41
|
+
console.error(`VectorStore: Created table "${this.config.tableName}"`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const records = chunks.map((chunk) => chunk);
|
|
45
|
+
await this.table.add(records);
|
|
46
|
+
}
|
|
47
|
+
console.error(`VectorStore: Inserted ${chunks.length} chunks`);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new Error(`Failed to insert chunks: ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async search(queryVector, limit = 10) {
|
|
54
|
+
if (!this.table) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const results = await this.table
|
|
59
|
+
.vectorSearch(queryVector)
|
|
60
|
+
.distanceType('dot')
|
|
61
|
+
.limit(limit)
|
|
62
|
+
.toArray();
|
|
63
|
+
return results.map((r) => ({
|
|
64
|
+
text: r.text,
|
|
65
|
+
question: r.question,
|
|
66
|
+
score: r._distance ?? 0,
|
|
67
|
+
project: r.project,
|
|
68
|
+
tags: r.tags,
|
|
69
|
+
timestamp: r.timestamp,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new Error(`Failed to search: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async getStatus() {
|
|
77
|
+
if (!this.table) {
|
|
78
|
+
return { chunkCount: 0 };
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const allRecords = await this.table.query().toArray();
|
|
82
|
+
return { chunkCount: allRecords.length };
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return { chunkCount: 0 };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=vectorstore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectorstore.js","sourceRoot":"","sources":["../src/vectorstore.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-forever-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CC-Forever MCP Server - Persistent conversation memory with semantic search",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cc-forever-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"prepare": "npm run build",
|
|
16
|
+
"start": "node dist/index.js",
|
|
17
|
+
"dev": "tsx src/index.ts"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@huggingface/transformers": "^3.7.6",
|
|
21
|
+
"@lancedb/lancedb": "^0.22.2",
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.25.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^20.0.0",
|
|
26
|
+
"tsx": "^4.19.4",
|
|
27
|
+
"typescript": "^5.0.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=20"
|
|
31
|
+
}
|
|
32
|
+
}
|