lance-context 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.
- package/LICENSE +674 -0
- package/README.md +139 -0
- package/dist/embeddings/index.d.ts +10 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +37 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/jina.d.ts +18 -0
- package/dist/embeddings/jina.d.ts.map +1 -0
- package/dist/embeddings/jina.js +69 -0
- package/dist/embeddings/jina.js.map +1 -0
- package/dist/embeddings/ollama.d.ts +17 -0
- package/dist/embeddings/ollama.d.ts.map +1 -0
- package/dist/embeddings/ollama.js +50 -0
- package/dist/embeddings/ollama.js.map +1 -0
- package/dist/embeddings/types.d.ts +18 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +6 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +168 -0
- package/dist/index.js.map +1 -0
- package/dist/search/indexer.d.ts +39 -0
- package/dist/search/indexer.d.ts.map +1 -0
- package/dist/search/indexer.js +173 -0
- package/dist/search/indexer.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# lance-context
|
|
2
|
+
|
|
3
|
+
An MCP plugin that adds semantic code search to Claude Code and other AI coding agents, giving them deep context from your entire codebase.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Semantic Code Search**: Natural language queries locate relevant code across your entire codebase
|
|
8
|
+
- **Multiple Embedding Backends**: Jina v3 API, local sentence-transformers, or Ollama
|
|
9
|
+
- **LanceDB Vector Storage**: Fast, efficient vector search with hybrid BM25 + dense matching
|
|
10
|
+
- **MCP Compatible**: Works with Claude Code, Cursor, and other MCP-compatible tools
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
### For Claude Code
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
claude mcp add lance-context -- npx lance-context
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or with a specific project path:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
claude mcp add lance-context -- npx lance-context --project /path/to/your/project
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Manual Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g lance-context
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
33
|
+
|
|
34
|
+
### Embedding Backends
|
|
35
|
+
|
|
36
|
+
lance-context automatically selects the best available backend:
|
|
37
|
+
|
|
38
|
+
1. **Jina v3** (highest quality, free tier available)
|
|
39
|
+
```bash
|
|
40
|
+
export JINA_API_KEY=your-api-key
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. **Ollama** (local, privacy-preserving)
|
|
44
|
+
```bash
|
|
45
|
+
# Make sure Ollama is running with nomic-embed-text
|
|
46
|
+
ollama pull nomic-embed-text
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
Once installed, you'll have access to these tools:
|
|
52
|
+
|
|
53
|
+
### `index_codebase`
|
|
54
|
+
|
|
55
|
+
Index your codebase for semantic search:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
> index_codebase
|
|
59
|
+
Indexed 150 files, created 800 chunks.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
With custom patterns:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
> index_codebase(patterns: ["**/*.py"], excludePatterns: ["**/tests/**"])
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `search_code`
|
|
69
|
+
|
|
70
|
+
Search using natural language:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
> search_code(query: "authentication middleware")
|
|
74
|
+
|
|
75
|
+
## Result 1: src/middleware/auth.ts:1-50
|
|
76
|
+
...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `get_index_status`
|
|
80
|
+
|
|
81
|
+
Check index status:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
> get_index_status
|
|
85
|
+
{
|
|
86
|
+
"indexed": true,
|
|
87
|
+
"fileCount": 150,
|
|
88
|
+
"chunkCount": 800,
|
|
89
|
+
"lastUpdated": "2024-12-27T12:00:00Z"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `clear_index`
|
|
94
|
+
|
|
95
|
+
Clear the index:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
> clear_index
|
|
99
|
+
Index cleared.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## How It Works
|
|
103
|
+
|
|
104
|
+
1. **Indexing**: Code files are chunked into ~100-line segments with overlap
|
|
105
|
+
2. **Embedding**: Each chunk is converted to a vector using your chosen backend
|
|
106
|
+
3. **Storage**: Vectors are stored in LanceDB (`.lance-context/` directory)
|
|
107
|
+
4. **Search**: Natural language queries are embedded and matched against stored vectors
|
|
108
|
+
|
|
109
|
+
## Environment Variables
|
|
110
|
+
|
|
111
|
+
| Variable | Description | Default |
|
|
112
|
+
|----------|-------------|---------|
|
|
113
|
+
| `JINA_API_KEY` | Jina AI API key for embeddings | - |
|
|
114
|
+
| `OLLAMA_URL` | Ollama server URL | `http://localhost:11434` |
|
|
115
|
+
| `LANCE_CONTEXT_PROJECT` | Project path to index | Current directory |
|
|
116
|
+
|
|
117
|
+
## Supported Languages
|
|
118
|
+
|
|
119
|
+
TypeScript, JavaScript, Python, Go, Rust, Java, Ruby, PHP, C/C++, C#, Swift, Kotlin, and more.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
GPL-3.0 - See [LICENSE](LICENSE) for details.
|
|
124
|
+
|
|
125
|
+
## Contributing
|
|
126
|
+
|
|
127
|
+
Contributions welcome! Please read our contributing guidelines before submitting PRs.
|
|
128
|
+
|
|
129
|
+
## Related Projects
|
|
130
|
+
|
|
131
|
+
- [claude-context](https://github.com/zilliztech/claude-context) - Similar tool using Zilliz Cloud
|
|
132
|
+
- [Serena](https://github.com/oraios/serena) - Symbol-level code navigation
|
|
133
|
+
|
|
134
|
+
## Credits
|
|
135
|
+
|
|
136
|
+
Built with:
|
|
137
|
+
- [LanceDB](https://lancedb.github.io/lancedb/) - Vector database
|
|
138
|
+
- [MCP SDK](https://github.com/modelcontextprotocol/sdk) - Model Context Protocol
|
|
139
|
+
- [Jina AI](https://jina.ai/) - Embedding API
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EmbeddingBackend, EmbeddingConfig } from './types.js';
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export { OllamaBackend } from './ollama.js';
|
|
4
|
+
export { JinaBackend } from './jina.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create an embedding backend based on configuration
|
|
7
|
+
* Falls back through backends: jina -> local -> ollama
|
|
8
|
+
*/
|
|
9
|
+
export declare function createEmbeddingBackend(config?: Partial<EmbeddingConfig>): Promise<EmbeddingBackend>;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/embeddings/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIpE,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAgC3B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { OllamaBackend } from './ollama.js';
|
|
2
|
+
import { JinaBackend } from './jina.js';
|
|
3
|
+
export * from './types.js';
|
|
4
|
+
export { OllamaBackend } from './ollama.js';
|
|
5
|
+
export { JinaBackend } from './jina.js';
|
|
6
|
+
/**
|
|
7
|
+
* Create an embedding backend based on configuration
|
|
8
|
+
* Falls back through backends: jina -> local -> ollama
|
|
9
|
+
*/
|
|
10
|
+
export async function createEmbeddingBackend(config) {
|
|
11
|
+
const backends = [];
|
|
12
|
+
// Priority 1: Jina (if API key available)
|
|
13
|
+
const jinaKey = config?.apiKey || process.env.JINA_API_KEY;
|
|
14
|
+
if (jinaKey) {
|
|
15
|
+
backends.push(() => new JinaBackend({ backend: 'jina', apiKey: jinaKey, ...config }));
|
|
16
|
+
}
|
|
17
|
+
// Priority 2: Ollama (local fallback)
|
|
18
|
+
backends.push(() => new OllamaBackend({
|
|
19
|
+
backend: 'ollama',
|
|
20
|
+
baseUrl: config?.baseUrl || process.env.OLLAMA_URL || 'http://localhost:11434',
|
|
21
|
+
model: config?.model || 'nomic-embed-text',
|
|
22
|
+
}));
|
|
23
|
+
// Try each backend until one works
|
|
24
|
+
for (const createBackend of backends) {
|
|
25
|
+
try {
|
|
26
|
+
const backend = createBackend();
|
|
27
|
+
await backend.initialize();
|
|
28
|
+
console.error(`[lance-context] Using ${backend.name} embedding backend`);
|
|
29
|
+
return backend;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error(`[lance-context] Backend failed: ${error}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw new Error('No embedding backend available. Install Ollama or set JINA_API_KEY.');
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/embeddings/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAiC;IAEjC,MAAM,QAAQ,GAAkC,EAAE,CAAC;IAEnD,0CAA0C;IAC1C,MAAM,OAAO,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC3D,IAAI,OAAO,EAAE,CAAC;QACZ,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,sCAAsC;IACtC,QAAQ,CAAC,IAAI,CACX,GAAG,EAAE,CACH,IAAI,aAAa,CAAC;QAChB,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,wBAAwB;QAC9E,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,kBAAkB;KAC3C,CAAC,CACL,CAAC;IAEF,mCAAmC;IACnC,KAAK,MAAM,aAAa,IAAI,QAAQ,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;YAChC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,yBAAyB,OAAO,CAAC,IAAI,oBAAoB,CAAC,CAAC;YACzE,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EmbeddingBackend, EmbeddingConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Jina AI embedding backend
|
|
4
|
+
* Uses Jina's free API tier for high-quality embeddings
|
|
5
|
+
*/
|
|
6
|
+
export declare class JinaBackend implements EmbeddingBackend {
|
|
7
|
+
name: string;
|
|
8
|
+
private model;
|
|
9
|
+
private apiKey;
|
|
10
|
+
private baseUrl;
|
|
11
|
+
private dimensions;
|
|
12
|
+
constructor(config: EmbeddingConfig);
|
|
13
|
+
initialize(): Promise<void>;
|
|
14
|
+
embed(text: string): Promise<number[]>;
|
|
15
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
16
|
+
getDimensions(): number;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=jina.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jina.d.ts","sourceRoot":"","sources":["../../src/embeddings/jina.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpE;;;GAGG;AACH,qBAAa,WAAY,YAAW,gBAAgB;IAClD,IAAI,SAAU;IACd,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,UAAU,CAAQ;gBAEd,MAAM,EAAE,eAAe;IAQ7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAsBtC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAsBtD,aAAa,IAAI,MAAM;CAGxB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jina AI embedding backend
|
|
3
|
+
* Uses Jina's free API tier for high-quality embeddings
|
|
4
|
+
*/
|
|
5
|
+
export class JinaBackend {
|
|
6
|
+
name = 'jina';
|
|
7
|
+
model;
|
|
8
|
+
apiKey;
|
|
9
|
+
baseUrl = 'https://api.jina.ai/v1/embeddings';
|
|
10
|
+
dimensions = 1024; // jina-embeddings-v3 default
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.model = config.model || 'jina-embeddings-v3';
|
|
13
|
+
if (!config.apiKey) {
|
|
14
|
+
throw new Error('Jina API key is required. Set JINA_API_KEY environment variable.');
|
|
15
|
+
}
|
|
16
|
+
this.apiKey = config.apiKey;
|
|
17
|
+
}
|
|
18
|
+
async initialize() {
|
|
19
|
+
// Test API key with a small request
|
|
20
|
+
try {
|
|
21
|
+
await this.embed('test');
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
throw new Error(`Failed to initialize Jina backend: ${error}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async embed(text) {
|
|
28
|
+
const response = await fetch(this.baseUrl, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: {
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
model: this.model,
|
|
36
|
+
input: [text],
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const error = await response.text();
|
|
41
|
+
throw new Error(`Jina API error: ${response.status} - ${error}`);
|
|
42
|
+
}
|
|
43
|
+
const data = (await response.json());
|
|
44
|
+
return data.data[0].embedding;
|
|
45
|
+
}
|
|
46
|
+
async embedBatch(texts) {
|
|
47
|
+
const response = await fetch(this.baseUrl, {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
52
|
+
},
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
model: this.model,
|
|
55
|
+
input: texts,
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const error = await response.text();
|
|
60
|
+
throw new Error(`Jina API error: ${response.status} - ${error}`);
|
|
61
|
+
}
|
|
62
|
+
const data = (await response.json());
|
|
63
|
+
return data.data.map((d) => d.embedding);
|
|
64
|
+
}
|
|
65
|
+
getDimensions() {
|
|
66
|
+
return this.dimensions;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=jina.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jina.js","sourceRoot":"","sources":["../../src/embeddings/jina.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACtB,IAAI,GAAG,MAAM,CAAC;IACN,KAAK,CAAS;IACd,MAAM,CAAS;IACf,OAAO,GAAG,mCAAmC,CAAC;IAC9C,UAAU,GAAG,IAAI,CAAC,CAAC,6BAA6B;IAExD,YAAY,MAAuB;QACjC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,UAAU;QACd,oCAAoC;QACpC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,CAAC,IAAI,CAAC;aACd,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,MAAM,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA6C,CAAC;QACjF,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,KAAK;aACb,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,MAAM,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA6C,CAAC;QACjF,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EmbeddingBackend, EmbeddingConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Ollama embedding backend
|
|
4
|
+
* Uses local Ollama server for embeddings
|
|
5
|
+
*/
|
|
6
|
+
export declare class OllamaBackend implements EmbeddingBackend {
|
|
7
|
+
name: string;
|
|
8
|
+
private model;
|
|
9
|
+
private baseUrl;
|
|
10
|
+
private dimensions;
|
|
11
|
+
constructor(config: EmbeddingConfig);
|
|
12
|
+
initialize(): Promise<void>;
|
|
13
|
+
embed(text: string): Promise<number[]>;
|
|
14
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
15
|
+
getDimensions(): number;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=ollama.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/embeddings/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpE;;;GAGG;AACH,qBAAa,aAAc,YAAW,gBAAgB;IACpD,IAAI,SAAY;IAChB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAO;gBAEb,MAAM,EAAE,eAAe;IAK7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBtC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAMtD,aAAa,IAAI,MAAM;CAGxB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama embedding backend
|
|
3
|
+
* Uses local Ollama server for embeddings
|
|
4
|
+
*/
|
|
5
|
+
export class OllamaBackend {
|
|
6
|
+
name = 'ollama';
|
|
7
|
+
model;
|
|
8
|
+
baseUrl;
|
|
9
|
+
dimensions = 768; // nomic-embed-text default
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.model = config.model || 'nomic-embed-text';
|
|
12
|
+
this.baseUrl = config.baseUrl || 'http://localhost:11434';
|
|
13
|
+
}
|
|
14
|
+
async initialize() {
|
|
15
|
+
// Test connection
|
|
16
|
+
try {
|
|
17
|
+
const response = await fetch(`${this.baseUrl}/api/tags`);
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
throw new Error(`Ollama server returned ${response.status}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new Error(`Failed to connect to Ollama at ${this.baseUrl}: ${error}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async embed(text) {
|
|
27
|
+
const response = await fetch(`${this.baseUrl}/api/embeddings`, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: { 'Content-Type': 'application/json' },
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
model: this.model,
|
|
32
|
+
prompt: text,
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new Error(`Ollama embedding failed: ${response.status}`);
|
|
37
|
+
}
|
|
38
|
+
const data = (await response.json());
|
|
39
|
+
return data.embedding;
|
|
40
|
+
}
|
|
41
|
+
async embedBatch(texts) {
|
|
42
|
+
// Ollama doesn't have native batch, so we parallelize
|
|
43
|
+
const embeddings = await Promise.all(texts.map((t) => this.embed(t)));
|
|
44
|
+
return embeddings;
|
|
45
|
+
}
|
|
46
|
+
getDimensions() {
|
|
47
|
+
return this.dimensions;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/embeddings/ollama.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB,IAAI,GAAG,QAAQ,CAAC;IACR,KAAK,CAAS;IACd,OAAO,CAAS;IAChB,UAAU,GAAG,GAAG,CAAC,CAAC,2BAA2B;IAErD,YAAY,MAAuB;QACjC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,kBAAkB,CAAC;QAChD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,wBAAwB,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,UAAU;QACd,kBAAkB;QAClB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;YACzD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,iBAAiB,EAAE;YAC7D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI;aACb,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;QAChE,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,sDAAsD;QACtD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding backend interface
|
|
3
|
+
*/
|
|
4
|
+
export interface EmbeddingBackend {
|
|
5
|
+
name: string;
|
|
6
|
+
initialize(): Promise<void>;
|
|
7
|
+
embed(text: string): Promise<number[]>;
|
|
8
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
9
|
+
getDimensions(): number;
|
|
10
|
+
}
|
|
11
|
+
export interface EmbeddingConfig {
|
|
12
|
+
backend: 'jina' | 'local' | 'ollama';
|
|
13
|
+
model?: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const DEFAULT_CONFIG: EmbeddingConfig;
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/embeddings/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,aAAa,IAAI,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,eAI5B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/embeddings/types.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,wBAAwB;CAClC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { createEmbeddingBackend } from './embeddings/index.js';
|
|
6
|
+
import { CodeIndexer } from './search/indexer.js';
|
|
7
|
+
const PROJECT_PATH = process.env.LANCE_CONTEXT_PROJECT || process.cwd();
|
|
8
|
+
let indexer = null;
|
|
9
|
+
async function getIndexer() {
|
|
10
|
+
if (!indexer) {
|
|
11
|
+
const backend = await createEmbeddingBackend();
|
|
12
|
+
indexer = new CodeIndexer(PROJECT_PATH, backend);
|
|
13
|
+
await indexer.initialize();
|
|
14
|
+
}
|
|
15
|
+
return indexer;
|
|
16
|
+
}
|
|
17
|
+
const server = new Server({
|
|
18
|
+
name: 'lance-context',
|
|
19
|
+
version: '0.1.0',
|
|
20
|
+
}, {
|
|
21
|
+
capabilities: {
|
|
22
|
+
tools: {},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
// List available tools
|
|
26
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
27
|
+
return {
|
|
28
|
+
tools: [
|
|
29
|
+
{
|
|
30
|
+
name: 'index_codebase',
|
|
31
|
+
description: 'Index the codebase for semantic search. Creates vector embeddings of all code files.',
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
patterns: {
|
|
36
|
+
type: 'array',
|
|
37
|
+
items: { type: 'string' },
|
|
38
|
+
description: 'Glob patterns for files to index (default: common code files)',
|
|
39
|
+
},
|
|
40
|
+
excludePatterns: {
|
|
41
|
+
type: 'array',
|
|
42
|
+
items: { type: 'string' },
|
|
43
|
+
description: 'Glob patterns for files to exclude (default: node_modules, dist, .git)',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'search_code',
|
|
50
|
+
description: 'Search the codebase using natural language. Returns relevant code snippets.',
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
query: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Natural language query to search for',
|
|
57
|
+
},
|
|
58
|
+
limit: {
|
|
59
|
+
type: 'number',
|
|
60
|
+
description: 'Maximum number of results (default: 10)',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
required: ['query'],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'get_index_status',
|
|
68
|
+
description: 'Get the current status of the code index.',
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: {},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'clear_index',
|
|
76
|
+
description: 'Clear the code index.',
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: {},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
// Handle tool calls
|
|
86
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
87
|
+
const { name, arguments: args } = request.params;
|
|
88
|
+
try {
|
|
89
|
+
const idx = await getIndexer();
|
|
90
|
+
switch (name) {
|
|
91
|
+
case 'index_codebase': {
|
|
92
|
+
const patterns = args?.patterns || undefined;
|
|
93
|
+
const excludePatterns = args?.excludePatterns || undefined;
|
|
94
|
+
const result = await idx.indexCodebase(patterns, excludePatterns);
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: 'text',
|
|
99
|
+
text: `Indexed ${result.filesIndexed} files, created ${result.chunksCreated} chunks.`,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
case 'search_code': {
|
|
105
|
+
const query = args?.query;
|
|
106
|
+
const limit = args?.limit || 10;
|
|
107
|
+
const results = await idx.search(query, limit);
|
|
108
|
+
const formatted = results
|
|
109
|
+
.map((r, i) => `## Result ${i + 1}: ${r.filePath}:${r.startLine}-${r.endLine}\n\`\`\`${r.language}\n${r.content}\n\`\`\``)
|
|
110
|
+
.join('\n\n');
|
|
111
|
+
return {
|
|
112
|
+
content: [
|
|
113
|
+
{
|
|
114
|
+
type: 'text',
|
|
115
|
+
text: formatted || 'No results found.',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
case 'get_index_status': {
|
|
121
|
+
const status = await idx.getStatus();
|
|
122
|
+
return {
|
|
123
|
+
content: [
|
|
124
|
+
{
|
|
125
|
+
type: 'text',
|
|
126
|
+
text: JSON.stringify(status, null, 2),
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
case 'clear_index': {
|
|
132
|
+
await idx.clearIndex();
|
|
133
|
+
return {
|
|
134
|
+
content: [
|
|
135
|
+
{
|
|
136
|
+
type: 'text',
|
|
137
|
+
text: 'Index cleared.',
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
default:
|
|
143
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
return {
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: 'text',
|
|
151
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
isError: true,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// Start server
|
|
159
|
+
async function main() {
|
|
160
|
+
const transport = new StdioServerTransport();
|
|
161
|
+
await server.connect(transport);
|
|
162
|
+
console.error('[lance-context] MCP server started');
|
|
163
|
+
}
|
|
164
|
+
main().catch((error) => {
|
|
165
|
+
console.error('[lance-context] Fatal error:', error);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
});
|
|
168
|
+
//# 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,39 @@
|
|
|
1
|
+
import type { EmbeddingBackend } from '../embeddings/index.js';
|
|
2
|
+
export interface CodeChunk {
|
|
3
|
+
id: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
content: string;
|
|
6
|
+
startLine: number;
|
|
7
|
+
endLine: number;
|
|
8
|
+
language: string;
|
|
9
|
+
embedding?: number[];
|
|
10
|
+
}
|
|
11
|
+
export interface IndexStatus {
|
|
12
|
+
indexed: boolean;
|
|
13
|
+
fileCount: number;
|
|
14
|
+
chunkCount: number;
|
|
15
|
+
lastUpdated: string | null;
|
|
16
|
+
indexPath: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Code indexer using LanceDB for vector storage
|
|
20
|
+
*/
|
|
21
|
+
export declare class CodeIndexer {
|
|
22
|
+
private db;
|
|
23
|
+
private table;
|
|
24
|
+
private embeddingBackend;
|
|
25
|
+
private indexPath;
|
|
26
|
+
private projectPath;
|
|
27
|
+
constructor(projectPath: string, embeddingBackend: EmbeddingBackend);
|
|
28
|
+
initialize(): Promise<void>;
|
|
29
|
+
getStatus(): Promise<IndexStatus>;
|
|
30
|
+
indexCodebase(patterns?: string[], excludePatterns?: string[]): Promise<{
|
|
31
|
+
filesIndexed: number;
|
|
32
|
+
chunksCreated: number;
|
|
33
|
+
}>;
|
|
34
|
+
private chunkFile;
|
|
35
|
+
private getLanguage;
|
|
36
|
+
search(query: string, limit?: number): Promise<CodeChunk[]>;
|
|
37
|
+
clearIndex(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=indexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../../src/search/indexer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB;IAM7D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC;IA0BjC,aAAa,CACjB,QAAQ,GAAE,MAAM,EAAoF,EACpG,eAAe,GAAE,MAAM,EAAsE,GAC5F,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;YA+D7C,SAAS;IA2BvB,OAAO,CAAC,WAAW;IA2Bb,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAsB/D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAOlC"}
|