@node2flow/gemini-file-search-rag-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/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/gemini-client.d.ts +41 -0
- package/dist/gemini-client.d.ts.map +1 -0
- package/dist/gemini-client.js +157 -0
- package/dist/gemini-client.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +190 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +119 -0
- package/dist/server.js.map +1 -0
- package/dist/tools.d.ts +392 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +258 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +11 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +74 -0
- package/dist/worker.js.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Node2Flow
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Gemini RAG MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://smithery.ai/server/node2flow/gemini-file-search-rag)
|
|
4
|
+
[](https://www.npmjs.com/package/@node2flow/gemini-file-search-rag-mcp)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
MCP (Model Context Protocol) server for Google's Gemini File Search (RAG). Manage file search stores, upload documents, and query with RAG through 12 tools.
|
|
8
|
+
|
|
9
|
+
Works with Claude Desktop, Cursor, VS Code, and any MCP client.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### Claude Desktop
|
|
16
|
+
|
|
17
|
+
Add to `claude_desktop_config.json`:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mcpServers": {
|
|
22
|
+
"gemini-rag": {
|
|
23
|
+
"command": "npx",
|
|
24
|
+
"args": ["-y", "@node2flow/gemini-file-search-rag-mcp"],
|
|
25
|
+
"env": {
|
|
26
|
+
"GEMINI_API_KEY": "your-gemini-api-key"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Cursor / VS Code
|
|
34
|
+
|
|
35
|
+
Add to MCP settings:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"gemini-rag": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["-y", "@node2flow/gemini-file-search-rag-mcp"],
|
|
43
|
+
"env": {
|
|
44
|
+
"GEMINI_API_KEY": "your-gemini-api-key"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### HTTP Mode (Streamable HTTP)
|
|
52
|
+
|
|
53
|
+
For remote deployment or shared access:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
GEMINI_API_KEY=your_key npx @node2flow/gemini-file-search-rag-mcp --http
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Server starts on port 3000 (configurable via `PORT` env var). MCP endpoint: `http://localhost:3000/mcp`
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
| Environment Variable | Required | Description |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `GEMINI_API_KEY` | Yes | Google Gemini API key ([get one here](https://aistudio.google.com/apikey)) |
|
|
68
|
+
| `PORT` | No | Port for HTTP server (default: `3000`, only used with `--http`) |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## All Tools (12 tools)
|
|
73
|
+
|
|
74
|
+
### Store Management (4 tools)
|
|
75
|
+
|
|
76
|
+
| Tool | Description |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `gemini_create_store` | Create a new file search store |
|
|
79
|
+
| `gemini_list_stores` | List all file search stores |
|
|
80
|
+
| `gemini_get_store` | Get store details |
|
|
81
|
+
| `gemini_delete_store` | Delete a store (with optional force) |
|
|
82
|
+
|
|
83
|
+
### Upload & Import (2 tools)
|
|
84
|
+
|
|
85
|
+
| Tool | Description |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `gemini_upload_to_store` | Upload content directly to a store (text, base64) |
|
|
88
|
+
| `gemini_import_file_to_store` | Import an existing Gemini file into a store |
|
|
89
|
+
|
|
90
|
+
### Operations (2 tools)
|
|
91
|
+
|
|
92
|
+
| Tool | Description |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `gemini_get_operation` | Check status of a store operation |
|
|
95
|
+
| `gemini_get_upload_operation` | Check status of an upload operation |
|
|
96
|
+
|
|
97
|
+
### Document Management (3 tools)
|
|
98
|
+
|
|
99
|
+
| Tool | Description |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `gemini_list_documents` | List documents in a store |
|
|
102
|
+
| `gemini_get_document` | Get document details |
|
|
103
|
+
| `gemini_delete_document` | Delete a document from a store |
|
|
104
|
+
|
|
105
|
+
### RAG Query (1 tool)
|
|
106
|
+
|
|
107
|
+
| Tool | Description |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `gemini_rag_query` | Query documents using RAG with Gemini models |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Requirements
|
|
114
|
+
|
|
115
|
+
- **Node.js** 18+
|
|
116
|
+
- **Google Gemini API key**
|
|
117
|
+
|
|
118
|
+
### How to Get a Gemini API Key
|
|
119
|
+
|
|
120
|
+
1. Go to [Google AI Studio](https://aistudio.google.com/apikey)
|
|
121
|
+
2. Click "Create API key"
|
|
122
|
+
3. Copy the key and use it as `GEMINI_API_KEY`
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## For Developers
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/node2flow-th/gemini-files-search-rag-mcp-community.git
|
|
130
|
+
cd gemini-files-search-rag-mcp-community
|
|
131
|
+
npm install
|
|
132
|
+
npm run build
|
|
133
|
+
|
|
134
|
+
# Run in stdio mode
|
|
135
|
+
GEMINI_API_KEY=your_key npm start
|
|
136
|
+
|
|
137
|
+
# Run in dev mode (hot reload)
|
|
138
|
+
GEMINI_API_KEY=your_key npm run dev
|
|
139
|
+
|
|
140
|
+
# Run in HTTP mode
|
|
141
|
+
GEMINI_API_KEY=your_key npm start -- --http
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT License - see [LICENSE](LICENSE)
|
|
149
|
+
|
|
150
|
+
Copyright (c) 2026 [Node2Flow](https://node2flow.net)
|
|
151
|
+
|
|
152
|
+
## Links
|
|
153
|
+
|
|
154
|
+
- [npm Package](https://www.npmjs.com/package/@node2flow/gemini-file-search-rag-mcp)
|
|
155
|
+
- [Google AI Studio](https://aistudio.google.com/)
|
|
156
|
+
- [MCP Protocol](https://modelcontextprotocol.io/)
|
|
157
|
+
- [Node2Flow](https://node2flow.net)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini RAG File Search API Client
|
|
3
|
+
* Uses Google Generative Language API with API key authentication
|
|
4
|
+
*/
|
|
5
|
+
import type { GeminiRagConfig, FileSearchStore, FileSearchStoreList, FileSearchDocument, FileSearchDocumentList, GeminiOperation, GenerateContentResponse, CustomMetadata, ChunkingConfig } from './types.js';
|
|
6
|
+
export declare class GeminiRagClient {
|
|
7
|
+
private config;
|
|
8
|
+
private baseUrl;
|
|
9
|
+
private uploadUrl;
|
|
10
|
+
constructor(config: GeminiRagConfig);
|
|
11
|
+
private request;
|
|
12
|
+
createStore(displayName: string): Promise<FileSearchStore>;
|
|
13
|
+
listStores(pageSize?: number, pageToken?: string): Promise<FileSearchStoreList>;
|
|
14
|
+
getStore(storeName: string): Promise<FileSearchStore>;
|
|
15
|
+
deleteStore(storeName: string, force?: boolean): Promise<Record<string, unknown>>;
|
|
16
|
+
uploadToStore(storeName: string, opts: {
|
|
17
|
+
mimeType: string;
|
|
18
|
+
content: string;
|
|
19
|
+
displayName?: string;
|
|
20
|
+
contentEncoding?: 'base64' | 'text';
|
|
21
|
+
customMetadata?: CustomMetadata[];
|
|
22
|
+
chunkingConfig?: ChunkingConfig;
|
|
23
|
+
}): Promise<GeminiOperation>;
|
|
24
|
+
importFileToStore(storeName: string, opts: {
|
|
25
|
+
fileName: string;
|
|
26
|
+
customMetadata?: CustomMetadata[];
|
|
27
|
+
chunkingConfig?: ChunkingConfig;
|
|
28
|
+
}): Promise<GeminiOperation>;
|
|
29
|
+
getOperation(operationName: string): Promise<GeminiOperation>;
|
|
30
|
+
getUploadOperation(operationName: string): Promise<GeminiOperation>;
|
|
31
|
+
listDocuments(storeName: string, pageSize?: number, pageToken?: string): Promise<FileSearchDocumentList>;
|
|
32
|
+
getDocument(documentName: string): Promise<FileSearchDocument>;
|
|
33
|
+
deleteDocument(documentName: string, force?: boolean): Promise<Record<string, unknown>>;
|
|
34
|
+
ragQuery(opts: {
|
|
35
|
+
query: string;
|
|
36
|
+
storeNames: string[];
|
|
37
|
+
model?: string;
|
|
38
|
+
metadataFilter?: string;
|
|
39
|
+
}): Promise<GenerateContentResponse>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=gemini-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-client.d.ts","sourceRoot":"","sources":["../src/gemini-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAsD;IACrE,OAAO,CAAC,SAAS,CAA6D;gBAElE,MAAM,EAAE,eAAe;YAIrB,OAAO;IAuBf,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO1D,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQ/E,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAIrD,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAOjF,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;QACpC,cAAc,CAAC,EAAE,cAAc,EAAE,CAAC;QAClC,cAAc,CAAC,EAAE,cAAc,CAAC;KACjC,GACA,OAAO,CAAC,eAAe,CAAC;IAwDrB,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,cAAc,EAAE,CAAC;QAClC,cAAc,CAAC,EAAE,cAAc,CAAC;KACjC,GACA,OAAO,CAAC,eAAe,CAAC;IAarB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAI7D,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAMnE,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC;IAQ5B,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI9D,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAO7B,QAAQ,CAAC,IAAI,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,uBAAuB,CAAC;CAiBrC"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini RAG File Search API Client
|
|
3
|
+
* Uses Google Generative Language API with API key authentication
|
|
4
|
+
*/
|
|
5
|
+
export class GeminiRagClient {
|
|
6
|
+
config;
|
|
7
|
+
baseUrl = 'https://generativelanguage.googleapis.com/v1beta';
|
|
8
|
+
uploadUrl = 'https://generativelanguage.googleapis.com/upload/v1beta';
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
}
|
|
12
|
+
async request(path, options = {}) {
|
|
13
|
+
const separator = path.includes('?') ? '&' : '?';
|
|
14
|
+
const url = `${this.baseUrl}${path}${separator}key=${this.config.apiKey}`;
|
|
15
|
+
const response = await fetch(url, {
|
|
16
|
+
...options,
|
|
17
|
+
headers: {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
...options.headers,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const error = await response.text();
|
|
24
|
+
throw new Error(`Gemini API Error (${response.status}): ${error}`);
|
|
25
|
+
}
|
|
26
|
+
const text = await response.text();
|
|
27
|
+
return text ? JSON.parse(text) : {};
|
|
28
|
+
}
|
|
29
|
+
// ========== Store Operations ==========
|
|
30
|
+
async createStore(displayName) {
|
|
31
|
+
return this.request('/fileSearchStores', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
body: JSON.stringify({ displayName }),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async listStores(pageSize, pageToken) {
|
|
37
|
+
const query = new URLSearchParams();
|
|
38
|
+
if (pageSize)
|
|
39
|
+
query.set('pageSize', String(pageSize));
|
|
40
|
+
if (pageToken)
|
|
41
|
+
query.set('pageToken', pageToken);
|
|
42
|
+
const qs = query.toString();
|
|
43
|
+
return this.request(`/fileSearchStores${qs ? `?${qs}` : ''}`);
|
|
44
|
+
}
|
|
45
|
+
async getStore(storeName) {
|
|
46
|
+
return this.request(`/${storeName}`);
|
|
47
|
+
}
|
|
48
|
+
async deleteStore(storeName, force) {
|
|
49
|
+
const query = force ? '?force=true' : '';
|
|
50
|
+
return this.request(`/${storeName}${query}`, { method: 'DELETE' });
|
|
51
|
+
}
|
|
52
|
+
// ========== Upload & Import ==========
|
|
53
|
+
async uploadToStore(storeName, opts) {
|
|
54
|
+
const boundary = '---n2f-boundary-' + Date.now();
|
|
55
|
+
// Build metadata part
|
|
56
|
+
const metadata = { mimeType: opts.mimeType };
|
|
57
|
+
if (opts.displayName)
|
|
58
|
+
metadata.displayName = opts.displayName;
|
|
59
|
+
if (opts.customMetadata)
|
|
60
|
+
metadata.customMetadata = opts.customMetadata;
|
|
61
|
+
if (opts.chunkingConfig)
|
|
62
|
+
metadata.chunkingConfig = opts.chunkingConfig;
|
|
63
|
+
// Decode content
|
|
64
|
+
let contentBytes;
|
|
65
|
+
if (opts.contentEncoding === 'base64') {
|
|
66
|
+
const binaryStr = atob(opts.content);
|
|
67
|
+
contentBytes = new Uint8Array(binaryStr.length);
|
|
68
|
+
for (let i = 0; i < binaryStr.length; i++) {
|
|
69
|
+
contentBytes[i] = binaryStr.charCodeAt(i);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
contentBytes = new TextEncoder().encode(opts.content);
|
|
74
|
+
}
|
|
75
|
+
// Build multipart body
|
|
76
|
+
const metadataJson = JSON.stringify(metadata);
|
|
77
|
+
const parts = [
|
|
78
|
+
`--${boundary}\r\n`,
|
|
79
|
+
'Content-Type: application/json\r\n\r\n',
|
|
80
|
+
metadataJson,
|
|
81
|
+
`\r\n--${boundary}\r\n`,
|
|
82
|
+
`Content-Type: ${opts.mimeType}\r\n\r\n`,
|
|
83
|
+
];
|
|
84
|
+
const prefix = new TextEncoder().encode(parts.join(''));
|
|
85
|
+
const suffix = new TextEncoder().encode(`\r\n--${boundary}--`);
|
|
86
|
+
const body = new Uint8Array(prefix.length + contentBytes.length + suffix.length);
|
|
87
|
+
body.set(prefix, 0);
|
|
88
|
+
body.set(contentBytes, prefix.length);
|
|
89
|
+
body.set(suffix, prefix.length + contentBytes.length);
|
|
90
|
+
const url = `${this.uploadUrl}/${storeName}:uploadToFileSearchStore?key=${this.config.apiKey}`;
|
|
91
|
+
const response = await fetch(url, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: {
|
|
94
|
+
'Content-Type': `multipart/related; boundary=${boundary}`,
|
|
95
|
+
},
|
|
96
|
+
body: body,
|
|
97
|
+
});
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
const error = await response.text();
|
|
100
|
+
throw new Error(`Gemini Upload Error (${response.status}): ${error}`);
|
|
101
|
+
}
|
|
102
|
+
return response.json();
|
|
103
|
+
}
|
|
104
|
+
async importFileToStore(storeName, opts) {
|
|
105
|
+
const body = { fileName: opts.fileName };
|
|
106
|
+
if (opts.customMetadata)
|
|
107
|
+
body.customMetadata = opts.customMetadata;
|
|
108
|
+
if (opts.chunkingConfig)
|
|
109
|
+
body.chunkingConfig = opts.chunkingConfig;
|
|
110
|
+
return this.request(`/${storeName}:importFile`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
body: JSON.stringify(body),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// ========== Operations ==========
|
|
116
|
+
async getOperation(operationName) {
|
|
117
|
+
return this.request(`/${operationName}`);
|
|
118
|
+
}
|
|
119
|
+
async getUploadOperation(operationName) {
|
|
120
|
+
return this.request(`/${operationName}`);
|
|
121
|
+
}
|
|
122
|
+
// ========== Document Operations ==========
|
|
123
|
+
async listDocuments(storeName, pageSize, pageToken) {
|
|
124
|
+
const query = new URLSearchParams();
|
|
125
|
+
if (pageSize)
|
|
126
|
+
query.set('pageSize', String(pageSize));
|
|
127
|
+
if (pageToken)
|
|
128
|
+
query.set('pageToken', pageToken);
|
|
129
|
+
const qs = query.toString();
|
|
130
|
+
return this.request(`/${storeName}/documents${qs ? `?${qs}` : ''}`);
|
|
131
|
+
}
|
|
132
|
+
async getDocument(documentName) {
|
|
133
|
+
return this.request(`/${documentName}`);
|
|
134
|
+
}
|
|
135
|
+
async deleteDocument(documentName, force) {
|
|
136
|
+
const query = force ? '?force=true' : '';
|
|
137
|
+
return this.request(`/${documentName}${query}`, { method: 'DELETE' });
|
|
138
|
+
}
|
|
139
|
+
// ========== RAG Query ==========
|
|
140
|
+
async ragQuery(opts) {
|
|
141
|
+
const model = opts.model || 'gemini-2.5-flash-lite';
|
|
142
|
+
const fileSearch = {
|
|
143
|
+
fileSearchStoreNames: opts.storeNames,
|
|
144
|
+
};
|
|
145
|
+
if (opts.metadataFilter) {
|
|
146
|
+
fileSearch.metadataFilter = opts.metadataFilter;
|
|
147
|
+
}
|
|
148
|
+
return this.request(`/models/${model}:generateContent`, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
contents: [{ parts: [{ text: opts.query }] }],
|
|
152
|
+
tools: [{ fileSearch }],
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=gemini-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-client.js","sourceRoot":"","sources":["../src/gemini-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Gemini RAG MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Community edition — connects directly to Google's Gemini API.
|
|
6
|
+
*
|
|
7
|
+
* Usage (stdio - for Claude Desktop / Cursor / VS Code):
|
|
8
|
+
* GEMINI_API_KEY=your_key npx @node2flow/gemini-rag-mcp
|
|
9
|
+
*
|
|
10
|
+
* Usage (HTTP - Streamable HTTP transport):
|
|
11
|
+
* GEMINI_API_KEY=your_key npx @node2flow/gemini-rag-mcp --http
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Smithery expects a default export that returns a Server instance.
|
|
15
|
+
* Config (GEMINI_API_KEY) is provided by users at runtime via Smithery UI.
|
|
16
|
+
*/
|
|
17
|
+
export default function createSmitheryServer(opts?: {
|
|
18
|
+
config?: {
|
|
19
|
+
GEMINI_API_KEY?: string;
|
|
20
|
+
};
|
|
21
|
+
}): import("@modelcontextprotocol/sdk/server").Server<{
|
|
22
|
+
method: string;
|
|
23
|
+
params?: {
|
|
24
|
+
[x: string]: unknown;
|
|
25
|
+
_meta?: {
|
|
26
|
+
[x: string]: unknown;
|
|
27
|
+
progressToken?: string | number | undefined;
|
|
28
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
29
|
+
taskId: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
} | undefined;
|
|
32
|
+
} | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
method: string;
|
|
35
|
+
params?: {
|
|
36
|
+
[x: string]: unknown;
|
|
37
|
+
_meta?: {
|
|
38
|
+
[x: string]: unknown;
|
|
39
|
+
progressToken?: string | number | undefined;
|
|
40
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
41
|
+
taskId: string;
|
|
42
|
+
} | undefined;
|
|
43
|
+
} | undefined;
|
|
44
|
+
} | undefined;
|
|
45
|
+
}, {
|
|
46
|
+
[x: string]: unknown;
|
|
47
|
+
_meta?: {
|
|
48
|
+
[x: string]: unknown;
|
|
49
|
+
progressToken?: string | number | undefined;
|
|
50
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
51
|
+
taskId: string;
|
|
52
|
+
} | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
}>;
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAwLH;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAI3F"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Gemini RAG MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Community edition — connects directly to Google's Gemini API.
|
|
6
|
+
*
|
|
7
|
+
* Usage (stdio - for Claude Desktop / Cursor / VS Code):
|
|
8
|
+
* GEMINI_API_KEY=your_key npx @node2flow/gemini-rag-mcp
|
|
9
|
+
*
|
|
10
|
+
* Usage (HTTP - Streamable HTTP transport):
|
|
11
|
+
* GEMINI_API_KEY=your_key npx @node2flow/gemini-rag-mcp --http
|
|
12
|
+
*/
|
|
13
|
+
import { randomUUID } from 'node:crypto';
|
|
14
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
15
|
+
import { StreamableHTTPServerTransport, } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
16
|
+
import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js';
|
|
17
|
+
import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
|
|
18
|
+
import { createServer } from './server.js';
|
|
19
|
+
import { TOOLS } from './tools.js';
|
|
20
|
+
/**
|
|
21
|
+
* Read config from environment variables
|
|
22
|
+
*/
|
|
23
|
+
function getConfig() {
|
|
24
|
+
const apiKey = process.env.GEMINI_API_KEY;
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return { apiKey };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Start in stdio mode (for Claude Desktop, Cursor, VS Code)
|
|
32
|
+
*/
|
|
33
|
+
async function startStdio() {
|
|
34
|
+
const config = getConfig();
|
|
35
|
+
const server = createServer(config ?? undefined);
|
|
36
|
+
const transport = new StdioServerTransport();
|
|
37
|
+
await server.connect(transport);
|
|
38
|
+
console.error('Gemini RAG MCP Server running on stdio');
|
|
39
|
+
console.error(`API Key: ${config ? '***configured***' : '(not configured yet)'}`);
|
|
40
|
+
console.error(`Tools available: ${TOOLS.length}`);
|
|
41
|
+
console.error('Ready for MCP client\n');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Start in HTTP mode (Streamable HTTP transport)
|
|
45
|
+
*/
|
|
46
|
+
async function startHttp() {
|
|
47
|
+
const port = parseInt(process.env.PORT || '3000', 10);
|
|
48
|
+
const app = createMcpExpressApp({ host: '0.0.0.0' });
|
|
49
|
+
// Map of active transports by session ID
|
|
50
|
+
const transports = {};
|
|
51
|
+
// POST /mcp — handle MCP requests
|
|
52
|
+
app.post('/mcp', async (req, res) => {
|
|
53
|
+
// Read config from query params (Smithery gateway) or env vars
|
|
54
|
+
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
55
|
+
const qKey = url.searchParams.get('GEMINI_API_KEY');
|
|
56
|
+
if (qKey)
|
|
57
|
+
process.env.GEMINI_API_KEY = qKey;
|
|
58
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
59
|
+
try {
|
|
60
|
+
let transport;
|
|
61
|
+
if (sessionId && transports[sessionId]) {
|
|
62
|
+
// Reuse existing transport
|
|
63
|
+
transport = transports[sessionId];
|
|
64
|
+
}
|
|
65
|
+
else if (!sessionId && isInitializeRequest(req.body)) {
|
|
66
|
+
// New initialization request
|
|
67
|
+
transport = new StreamableHTTPServerTransport({
|
|
68
|
+
sessionIdGenerator: () => randomUUID(),
|
|
69
|
+
onsessioninitialized: (sid) => {
|
|
70
|
+
transports[sid] = transport;
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
transport.onclose = () => {
|
|
74
|
+
const sid = transport.sessionId;
|
|
75
|
+
if (sid && transports[sid]) {
|
|
76
|
+
delete transports[sid];
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const config = getConfig();
|
|
80
|
+
const server = createServer(config ?? undefined);
|
|
81
|
+
await server.connect(transport);
|
|
82
|
+
await transport.handleRequest(req, res, req.body);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
res.status(400).json({
|
|
87
|
+
jsonrpc: '2.0',
|
|
88
|
+
error: {
|
|
89
|
+
code: -32000,
|
|
90
|
+
message: 'Bad Request: No valid session ID provided',
|
|
91
|
+
},
|
|
92
|
+
id: null,
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
await transport.handleRequest(req, res, req.body);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error('Error handling MCP request:', error);
|
|
100
|
+
if (!res.headersSent) {
|
|
101
|
+
res.status(500).json({
|
|
102
|
+
jsonrpc: '2.0',
|
|
103
|
+
error: {
|
|
104
|
+
code: -32603,
|
|
105
|
+
message: 'Internal server error',
|
|
106
|
+
},
|
|
107
|
+
id: null,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
// GET /mcp — SSE stream for existing sessions
|
|
113
|
+
app.get('/mcp', async (req, res) => {
|
|
114
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
115
|
+
if (!sessionId || !transports[sessionId]) {
|
|
116
|
+
res.status(400).send('Invalid or missing session ID');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await transports[sessionId].handleRequest(req, res);
|
|
120
|
+
});
|
|
121
|
+
// DELETE /mcp — session termination
|
|
122
|
+
app.delete('/mcp', async (req, res) => {
|
|
123
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
124
|
+
if (!sessionId || !transports[sessionId]) {
|
|
125
|
+
res.status(400).send('Invalid or missing session ID');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
await transports[sessionId].handleRequest(req, res);
|
|
129
|
+
});
|
|
130
|
+
// Health check
|
|
131
|
+
app.get('/', (_req, res) => {
|
|
132
|
+
res.json({
|
|
133
|
+
name: 'gemini-rag-mcp',
|
|
134
|
+
version: '1.0.0',
|
|
135
|
+
status: 'ok',
|
|
136
|
+
tools: TOOLS.length,
|
|
137
|
+
transport: 'streamable-http',
|
|
138
|
+
endpoints: {
|
|
139
|
+
mcp: '/mcp',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
const config = getConfig();
|
|
144
|
+
app.listen(port, () => {
|
|
145
|
+
console.log(`Gemini RAG MCP Server (HTTP) listening on port ${port}`);
|
|
146
|
+
console.log(`API Key: ${config ? '***configured***' : '(not configured yet)'}`);
|
|
147
|
+
console.log(`Tools available: ${TOOLS.length}`);
|
|
148
|
+
console.log(`MCP endpoint: http://localhost:${port}/mcp`);
|
|
149
|
+
});
|
|
150
|
+
process.on('SIGINT', async () => {
|
|
151
|
+
console.log('\nShutting down...');
|
|
152
|
+
for (const sessionId in transports) {
|
|
153
|
+
try {
|
|
154
|
+
await transports[sessionId].close();
|
|
155
|
+
delete transports[sessionId];
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Ignore cleanup errors
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
process.exit(0);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Main entry point
|
|
166
|
+
*/
|
|
167
|
+
async function main() {
|
|
168
|
+
const useHttp = process.argv.includes('--http');
|
|
169
|
+
if (useHttp) {
|
|
170
|
+
await startHttp();
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
await startStdio();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Smithery expects a default export that returns a Server instance.
|
|
178
|
+
* Config (GEMINI_API_KEY) is provided by users at runtime via Smithery UI.
|
|
179
|
+
*/
|
|
180
|
+
export default function createSmitheryServer(opts) {
|
|
181
|
+
if (opts?.config?.GEMINI_API_KEY)
|
|
182
|
+
process.env.GEMINI_API_KEY = opts.config.GEMINI_API_KEY;
|
|
183
|
+
const config = getConfig();
|
|
184
|
+
return createServer(config ?? undefined);
|
|
185
|
+
}
|
|
186
|
+
main().catch((error) => {
|
|
187
|
+
console.error('Fatal error:', error);
|
|
188
|
+
process.exit(1);
|
|
189
|
+
});
|
|
190
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared MCP Server creation logic
|
|
3
|
+
* Used by both Node.js entry (index.ts) and CF Worker entry (worker.ts)
|
|
4
|
+
*/
|
|
5
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
6
|
+
import { GeminiRagClient } from './gemini-client.js';
|
|
7
|
+
/**
|
|
8
|
+
* Handle MCP tool calls by routing to GeminiRagClient methods
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleToolCall(toolName: string, args: any, client: GeminiRagClient): Promise<any>;
|
|
11
|
+
/**
|
|
12
|
+
* Create a configured MCP Server instance
|
|
13
|
+
* Config is optional — tools/list works without config, tool calls require it
|
|
14
|
+
*/
|
|
15
|
+
export declare function createServer(config?: {
|
|
16
|
+
apiKey: string;
|
|
17
|
+
}): Server;
|
|
18
|
+
//# sourceMappingURL=server.d.ts.map
|