@houtini/gemini-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/.env.example +10 -0
- package/LICENSE +21 -0
- package/README.md +442 -0
- package/claude_desktop_config_example.json +12 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +22 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +81 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +24 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +3 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/services/base-service.d.ts +8 -0
- package/dist/services/base-service.d.ts.map +1 -0
- package/dist/services/base-service.js +30 -0
- package/dist/services/base-service.js.map +1 -0
- package/dist/services/gemini/index.d.ts +15 -0
- package/dist/services/gemini/index.d.ts.map +1 -0
- package/dist/services/gemini/index.js +182 -0
- package/dist/services/gemini/index.js.map +1 -0
- package/dist/services/gemini/types.d.ts +29 -0
- package/dist/services/gemini/types.d.ts.map +1 -0
- package/dist/services/gemini/types.js +3 -0
- package/dist/services/gemini/types.js.map +1 -0
- package/dist/tools/gemini-chat.d.ts +9 -0
- package/dist/tools/gemini-chat.d.ts.map +1 -0
- package/dist/tools/gemini-chat.js +82 -0
- package/dist/tools/gemini-chat.js.map +1 -0
- package/dist/tools/gemini-list-models.d.ts +9 -0
- package/dist/tools/gemini-list-models.d.ts.map +1 -0
- package/dist/tools/gemini-list-models.js +42 -0
- package/dist/tools/gemini-list-models.js.map +1 -0
- package/dist/utils/error-handler.d.ts +17 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +61 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +59 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +94 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.GeminiMcpServer = void 0;
|
|
8
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
9
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
10
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
11
|
+
const config_1 = require("./config");
|
|
12
|
+
const gemini_1 = require("./services/gemini");
|
|
13
|
+
const gemini_chat_1 = require("./tools/gemini-chat");
|
|
14
|
+
const gemini_list_models_1 = require("./tools/gemini-list-models");
|
|
15
|
+
const logger_1 = __importDefault(require("./utils/logger"));
|
|
16
|
+
const error_handler_1 = require("./utils/error-handler");
|
|
17
|
+
class GeminiMcpServer {
|
|
18
|
+
server;
|
|
19
|
+
geminiService;
|
|
20
|
+
tools;
|
|
21
|
+
constructor() {
|
|
22
|
+
// Validate configuration on startup
|
|
23
|
+
try {
|
|
24
|
+
(0, config_1.validateConfig)();
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
logger_1.default.error('Configuration validation failed', { error });
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
// Initialize services
|
|
31
|
+
this.geminiService = new gemini_1.GeminiService(config_1.config.gemini);
|
|
32
|
+
// Initialize server
|
|
33
|
+
this.server = new index_js_1.Server({
|
|
34
|
+
name: config_1.config.server.name,
|
|
35
|
+
version: config_1.config.server.version,
|
|
36
|
+
}, {
|
|
37
|
+
capabilities: {
|
|
38
|
+
tools: {},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
// Initialize tools
|
|
42
|
+
this.tools = new Map();
|
|
43
|
+
this.initializeTools();
|
|
44
|
+
this.setupHandlers();
|
|
45
|
+
logger_1.default.info('Gemini MCP Server initialized', {
|
|
46
|
+
serverName: config_1.config.server.name,
|
|
47
|
+
version: config_1.config.server.version
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
initializeTools() {
|
|
51
|
+
const geminiChatTool = new gemini_chat_1.GeminiChatTool(this.geminiService);
|
|
52
|
+
const geminiListModelsTool = new gemini_list_models_1.GeminiListModelsTool(this.geminiService);
|
|
53
|
+
this.tools.set('gemini_chat', geminiChatTool);
|
|
54
|
+
this.tools.set('gemini_list_models', geminiListModelsTool);
|
|
55
|
+
logger_1.default.info('Tools initialized', {
|
|
56
|
+
toolCount: this.tools.size,
|
|
57
|
+
tools: Array.from(this.tools.keys())
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
setupHandlers() {
|
|
61
|
+
// Handle tool listing
|
|
62
|
+
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
63
|
+
logger_1.default.info('Handling list_tools request');
|
|
64
|
+
const tools = Array.from(this.tools.values()).map(tool => tool.getDefinition());
|
|
65
|
+
return {
|
|
66
|
+
tools
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
// Handle tool calls
|
|
70
|
+
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
71
|
+
const { name, arguments: args } = request.params;
|
|
72
|
+
logger_1.default.info('Handling call_tool request', {
|
|
73
|
+
toolName: name,
|
|
74
|
+
hasArgs: !!args
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const tool = this.tools.get(name);
|
|
78
|
+
if (!tool) {
|
|
79
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
80
|
+
}
|
|
81
|
+
const result = await tool.execute(args);
|
|
82
|
+
return {
|
|
83
|
+
content: result
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
logger_1.default.error('Tool execution failed', {
|
|
88
|
+
toolName: name,
|
|
89
|
+
error: error.message
|
|
90
|
+
});
|
|
91
|
+
const mcpError = (0, error_handler_1.handleError)(error, `tool:${name}`);
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: 'text',
|
|
96
|
+
text: mcpError.message
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
isError: true
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async start() {
|
|
105
|
+
try {
|
|
106
|
+
// Validate Gemini service configuration
|
|
107
|
+
const isValid = await this.geminiService.validateConfig();
|
|
108
|
+
if (!isValid) {
|
|
109
|
+
throw new Error('Gemini API key validation failed');
|
|
110
|
+
}
|
|
111
|
+
logger_1.default.info('Starting Gemini MCP Server...');
|
|
112
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
113
|
+
await this.server.connect(transport);
|
|
114
|
+
logger_1.default.info('Gemini MCP Server started successfully', {
|
|
115
|
+
transport: 'stdio',
|
|
116
|
+
toolsAvailable: Array.from(this.tools.keys())
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
logger_1.default.error('Failed to start Gemini MCP Server', { error });
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.GeminiMcpServer = GeminiMcpServer;
|
|
126
|
+
// Handle process cleanup
|
|
127
|
+
process.on('SIGINT', () => {
|
|
128
|
+
logger_1.default.info('Received SIGINT, shutting down gracefully...');
|
|
129
|
+
process.exit(0);
|
|
130
|
+
});
|
|
131
|
+
process.on('SIGTERM', () => {
|
|
132
|
+
logger_1.default.info('Received SIGTERM, shutting down gracefully...');
|
|
133
|
+
process.exit(0);
|
|
134
|
+
});
|
|
135
|
+
process.on('uncaughtException', (error) => {
|
|
136
|
+
logger_1.default.error('Uncaught exception', { error });
|
|
137
|
+
process.exit(1);
|
|
138
|
+
});
|
|
139
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
140
|
+
logger_1.default.error('Unhandled promise rejection', { reason, promise });
|
|
141
|
+
process.exit(1);
|
|
142
|
+
});
|
|
143
|
+
// Start the server
|
|
144
|
+
async function main() {
|
|
145
|
+
const server = new GeminiMcpServer();
|
|
146
|
+
await server.start();
|
|
147
|
+
}
|
|
148
|
+
if (require.main === module) {
|
|
149
|
+
main().catch(error => {
|
|
150
|
+
logger_1.default.error('Server startup failed', { error });
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
//# 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,8 @@
|
|
|
1
|
+
export declare abstract class BaseService {
|
|
2
|
+
protected logger: import("winston").Logger;
|
|
3
|
+
protected handleError(error: Error, context?: string): Promise<never>;
|
|
4
|
+
protected logInfo(message: string, metadata?: any): void;
|
|
5
|
+
protected logWarning(message: string, metadata?: any): void;
|
|
6
|
+
protected logError(message: string, error?: Error): void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=base-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-service.d.ts","sourceRoot":"","sources":["../../src/services/base-service.ts"],"names":[],"mappings":"AAEA,8BAAsB,WAAW;IAC/B,SAAS,CAAC,MAAM,2BAAU;cAEV,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAY3E,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAIxD,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAI3D,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;CAGzD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BaseService = void 0;
|
|
7
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
8
|
+
class BaseService {
|
|
9
|
+
logger = logger_1.default;
|
|
10
|
+
async handleError(error, context) {
|
|
11
|
+
const contextMessage = context ? `[${context}] ` : '';
|
|
12
|
+
const message = `${contextMessage}${error.message}`;
|
|
13
|
+
this.logger.error(message, {
|
|
14
|
+
error: error.stack,
|
|
15
|
+
context
|
|
16
|
+
});
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
logInfo(message, metadata) {
|
|
20
|
+
this.logger.info(message, metadata);
|
|
21
|
+
}
|
|
22
|
+
logWarning(message, metadata) {
|
|
23
|
+
this.logger.warn(message, metadata);
|
|
24
|
+
}
|
|
25
|
+
logError(message, error) {
|
|
26
|
+
this.logger.error(message, { error: error?.stack });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.BaseService = BaseService;
|
|
30
|
+
//# sourceMappingURL=base-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-service.js","sourceRoot":"","sources":["../../src/services/base-service.ts"],"names":[],"mappings":";;;;;;AAAA,6DAAqC;AAErC,MAAsB,WAAW;IACrB,MAAM,GAAG,gBAAM,CAAC;IAEhB,KAAK,CAAC,WAAW,CAAC,KAAY,EAAE,OAAgB;QACxD,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,OAAO,GAAG,GAAG,cAAc,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAEpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;YACzB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,OAAO;SACR,CAAC,CAAC;QAEH,MAAM,KAAK,CAAC;IACd,CAAC;IAES,OAAO,CAAC,OAAe,EAAE,QAAc;QAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IAES,UAAU,CAAC,OAAe,EAAE,QAAc;QAClD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IAES,QAAQ,CAAC,OAAe,EAAE,KAAa;QAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;CACF;AA1BD,kCA0BC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseService } from '../base-service';
|
|
2
|
+
import { GeminiConfig } from '../../config/types';
|
|
3
|
+
import { ChatRequest, ChatResponse, ListModelsResponse } from './types';
|
|
4
|
+
export declare class GeminiService extends BaseService {
|
|
5
|
+
private genAI;
|
|
6
|
+
private config;
|
|
7
|
+
private readonly availableModels;
|
|
8
|
+
constructor(config: GeminiConfig);
|
|
9
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
10
|
+
listModels(): Promise<ListModelsResponse>;
|
|
11
|
+
validateConfig(): Promise<boolean>;
|
|
12
|
+
private mapSafetySettings;
|
|
13
|
+
getAvailableModels(): string[];
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/gemini/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,kBAAkB,EAGnB,MAAM,SAAS,CAAC;AAGjB,qBAAa,aAAc,SAAQ,WAAW;IAC5C,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,MAAM,CAAe;IAG7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CA+B9B;gBAEU,MAAM,EAAE,YAAY;IAY1B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA8FjD,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAazC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAwBxC,OAAO,CAAC,iBAAiB;IAqBzB,kBAAkB,IAAI,MAAM,EAAE;CAG/B"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GeminiService = void 0;
|
|
4
|
+
const generative_ai_1 = require("@google/generative-ai");
|
|
5
|
+
const base_service_1 = require("../base-service");
|
|
6
|
+
const error_handler_1 = require("../../utils/error-handler");
|
|
7
|
+
class GeminiService extends base_service_1.BaseService {
|
|
8
|
+
genAI;
|
|
9
|
+
config;
|
|
10
|
+
// Available models mapping
|
|
11
|
+
availableModels = [
|
|
12
|
+
{
|
|
13
|
+
name: 'gemini-2.5-flash',
|
|
14
|
+
displayName: 'Gemini 2.5 Flash',
|
|
15
|
+
description: 'Latest Gemini 2.5 Flash - Fast, versatile performance'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'gemini-2.0-flash',
|
|
19
|
+
displayName: 'Gemini 2.0 Flash',
|
|
20
|
+
description: 'Gemini 2.0 Flash - Fast, efficient model'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'gemini-1.5-flash',
|
|
24
|
+
displayName: 'Gemini 1.5 Flash',
|
|
25
|
+
description: 'Gemini 1.5 Flash - Fast, efficient model'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'gemini-1.5-pro',
|
|
29
|
+
displayName: 'Gemini 1.5 Pro',
|
|
30
|
+
description: 'Gemini 1.5 Pro - Advanced reasoning'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'gemini-pro',
|
|
34
|
+
displayName: 'Gemini Pro',
|
|
35
|
+
description: 'Gemini Pro - Balanced performance'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'gemini-pro-vision',
|
|
39
|
+
displayName: 'Gemini Pro Vision',
|
|
40
|
+
description: 'Gemini Pro Vision - Multimodal understanding'
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
constructor(config) {
|
|
44
|
+
super();
|
|
45
|
+
this.config = config;
|
|
46
|
+
if (!config.apiKey) {
|
|
47
|
+
throw new error_handler_1.GeminiError('Missing API key for Gemini service');
|
|
48
|
+
}
|
|
49
|
+
this.genAI = new generative_ai_1.GoogleGenerativeAI(config.apiKey);
|
|
50
|
+
this.logInfo('Gemini service initialized');
|
|
51
|
+
}
|
|
52
|
+
async chat(request) {
|
|
53
|
+
try {
|
|
54
|
+
this.logInfo(`Chat request to ${request.model || this.config.defaultModel}`, {
|
|
55
|
+
messageLength: request.message.length,
|
|
56
|
+
hasSystemPrompt: !!request.systemPrompt
|
|
57
|
+
});
|
|
58
|
+
const modelName = request.model || this.config.defaultModel;
|
|
59
|
+
// Configure generation parameters
|
|
60
|
+
const generationConfig = {
|
|
61
|
+
temperature: request.temperature ?? this.config.temperature,
|
|
62
|
+
maxOutputTokens: request.maxTokens ?? this.config.maxTokens
|
|
63
|
+
};
|
|
64
|
+
// Initialize model with safety settings
|
|
65
|
+
const model = this.genAI.getGenerativeModel({
|
|
66
|
+
model: modelName,
|
|
67
|
+
safetySettings: this.mapSafetySettings(),
|
|
68
|
+
generationConfig
|
|
69
|
+
});
|
|
70
|
+
// Prepare prompt
|
|
71
|
+
const prompt = request.systemPrompt
|
|
72
|
+
? `${request.systemPrompt}\n\nUser: ${request.message}\n\nAssistant:`
|
|
73
|
+
: request.message;
|
|
74
|
+
// Generate response
|
|
75
|
+
const result = await model.generateContent(prompt);
|
|
76
|
+
const response = result.response;
|
|
77
|
+
// Check if response was blocked
|
|
78
|
+
if (result.response.promptFeedback?.blockReason) {
|
|
79
|
+
const blockReason = result.response.promptFeedback.blockReason;
|
|
80
|
+
throw new error_handler_1.GeminiError(`Response was blocked by safety filters. Reason: ${blockReason}. ` +
|
|
81
|
+
'Try rephrasing your query or using different parameters.');
|
|
82
|
+
}
|
|
83
|
+
// Extract response text
|
|
84
|
+
let responseText;
|
|
85
|
+
try {
|
|
86
|
+
responseText = response.text();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
// Handle cases where content was filtered
|
|
90
|
+
const candidate = response.candidates?.[0];
|
|
91
|
+
if (candidate?.finishReason) {
|
|
92
|
+
const finishReasonMap = {
|
|
93
|
+
'1': 'STOP - Natural ending',
|
|
94
|
+
'2': 'SAFETY - Content was filtered',
|
|
95
|
+
'3': 'MAX_TOKENS - Hit token limit',
|
|
96
|
+
'4': 'UNSPECIFIED',
|
|
97
|
+
'5': 'OTHER'
|
|
98
|
+
};
|
|
99
|
+
const reason = finishReasonMap[candidate.finishReason.toString()] ||
|
|
100
|
+
`Unknown reason: ${candidate.finishReason}`;
|
|
101
|
+
throw new error_handler_1.GeminiError(`Response was filtered. Finish reason: ${reason}\n\n` +
|
|
102
|
+
'Try:\n1. Rephrasing your query\n2. Using a different model\n3. Adjusting temperature settings');
|
|
103
|
+
}
|
|
104
|
+
throw new error_handler_1.GeminiError('No text content in response. The model may have filtered the content.');
|
|
105
|
+
}
|
|
106
|
+
const chatResponse = {
|
|
107
|
+
content: responseText,
|
|
108
|
+
model: modelName,
|
|
109
|
+
timestamp: new Date().toISOString(),
|
|
110
|
+
finishReason: response.candidates?.[0]?.finishReason?.toString()
|
|
111
|
+
};
|
|
112
|
+
this.logInfo('Chat response generated successfully', {
|
|
113
|
+
model: modelName,
|
|
114
|
+
responseLength: responseText.length,
|
|
115
|
+
finishReason: chatResponse.finishReason
|
|
116
|
+
});
|
|
117
|
+
return chatResponse;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (error instanceof error_handler_1.GeminiError) {
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
this.logError('Chat generation failed', error);
|
|
124
|
+
throw new error_handler_1.GeminiError(`Error generating response: ${error.message}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async listModels() {
|
|
128
|
+
try {
|
|
129
|
+
this.logInfo('Listing available models');
|
|
130
|
+
return {
|
|
131
|
+
models: this.availableModels,
|
|
132
|
+
timestamp: new Date().toISOString()
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return await this.handleError(error, 'listModels');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async validateConfig() {
|
|
140
|
+
try {
|
|
141
|
+
if (!this.config.apiKey) {
|
|
142
|
+
this.logError('API key validation failed: missing key');
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
// Test API access with a minimal request
|
|
146
|
+
const model = this.genAI.getGenerativeModel({
|
|
147
|
+
model: this.config.defaultModel,
|
|
148
|
+
safetySettings: this.mapSafetySettings()
|
|
149
|
+
});
|
|
150
|
+
await model.generateContent('API validation check');
|
|
151
|
+
this.logInfo('Gemini API key validation successful');
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.logError('Configuration validation failed', error);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
mapSafetySettings() {
|
|
160
|
+
const harmBlockThresholdMap = {
|
|
161
|
+
'BLOCK_NONE': generative_ai_1.HarmBlockThreshold.BLOCK_NONE,
|
|
162
|
+
'BLOCK_LOW_AND_ABOVE': generative_ai_1.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
|
|
163
|
+
'BLOCK_MEDIUM_AND_ABOVE': generative_ai_1.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
|
|
164
|
+
'BLOCK_ONLY_HIGH': generative_ai_1.HarmBlockThreshold.BLOCK_ONLY_HIGH
|
|
165
|
+
};
|
|
166
|
+
const harmCategoryMap = {
|
|
167
|
+
'HARM_CATEGORY_HARASSMENT': generative_ai_1.HarmCategory.HARM_CATEGORY_HARASSMENT,
|
|
168
|
+
'HARM_CATEGORY_HATE_SPEECH': generative_ai_1.HarmCategory.HARM_CATEGORY_HATE_SPEECH,
|
|
169
|
+
'HARM_CATEGORY_SEXUALLY_EXPLICIT': generative_ai_1.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
|
|
170
|
+
'HARM_CATEGORY_DANGEROUS_CONTENT': generative_ai_1.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT
|
|
171
|
+
};
|
|
172
|
+
return this.config.safetySettings.map(setting => ({
|
|
173
|
+
category: harmCategoryMap[setting.category],
|
|
174
|
+
threshold: harmBlockThresholdMap[setting.threshold]
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
getAvailableModels() {
|
|
178
|
+
return this.availableModels.map(model => model.name);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.GeminiService = GeminiService;
|
|
182
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/gemini/index.ts"],"names":[],"mappings":";;;AAAA,yDAA6F;AAC7F,kDAA8C;AAS9C,6DAAwD;AAExD,MAAa,aAAc,SAAQ,0BAAW;IACpC,KAAK,CAAqB;IAC1B,MAAM,CAAe;IAE7B,2BAA2B;IACV,eAAe,GAAgB;QAC9C;YACE,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,kBAAkB;YAC/B,WAAW,EAAE,uDAAuD;SACrE;QACD;YACE,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,kBAAkB;YAC/B,WAAW,EAAE,0CAA0C;SACxD;QACD;YACE,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,kBAAkB;YAC/B,WAAW,EAAE,0CAA0C;SACxD;QACD;YACE,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,gBAAgB;YAC7B,WAAW,EAAE,qCAAqC;SACnD;QACD;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,mCAAmC;SACjD;QACD;YACE,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,mBAAmB;YAChC,WAAW,EAAE,8CAA8C;SAC5D;KACF,CAAC;IAEF,YAAY,MAAoB;QAC9B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,2BAAW,CAAC,oCAAoC,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,kCAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,mBAAmB,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE;gBAC3E,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM;gBACrC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY;aACxC,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAE5D,kCAAkC;YAClC,MAAM,gBAAgB,GAA2B;gBAC/C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW;gBAC3D,eAAe,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS;aAC5D,CAAC;YAEF,wCAAwC;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC;gBAC1C,KAAK,EAAE,SAAS;gBAChB,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE;gBACxC,gBAAgB;aACjB,CAAC,CAAC;YAEH,iBAAiB;YACjB,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY;gBACjC,CAAC,CAAC,GAAG,OAAO,CAAC,YAAY,aAAa,OAAO,CAAC,OAAO,gBAAgB;gBACrE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;YAEpB,oBAAoB;YACpB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEjC,gCAAgC;YAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,WAAW,EAAE,CAAC;gBAChD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC;gBAC/D,MAAM,IAAI,2BAAW,CACnB,mDAAmD,WAAW,IAAI;oBAClE,0DAA0D,CAC3D,CAAC;YACJ,CAAC;YAED,wBAAwB;YACxB,IAAI,YAAoB,CAAC;YAEzB,IAAI,CAAC;gBACH,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,0CAA0C;gBAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC3C,IAAI,SAAS,EAAE,YAAY,EAAE,CAAC;oBAC5B,MAAM,eAAe,GAA2B;wBAC9C,GAAG,EAAE,uBAAuB;wBAC5B,GAAG,EAAE,+BAA+B;wBACpC,GAAG,EAAE,8BAA8B;wBACnC,GAAG,EAAE,aAAa;wBAClB,GAAG,EAAE,OAAO;qBACb,CAAC;oBAEF,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;wBACnD,mBAAmB,SAAS,CAAC,YAAY,EAAE,CAAC;oBAE1D,MAAM,IAAI,2BAAW,CACnB,yCAAyC,MAAM,MAAM;wBACrD,+FAA+F,CAChG,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,2BAAW,CAAC,uEAAuE,CAAC,CAAC;YACjG,CAAC;YAED,MAAM,YAAY,GAAiB;gBACjC,OAAO,EAAE,YAAY;gBACrB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,YAAY,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE;aACjE,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,sCAAsC,EAAE;gBACnD,KAAK,EAAE,SAAS;gBAChB,cAAc,EAAE,YAAY,CAAC,MAAM;gBACnC,YAAY,EAAE,YAAY,CAAC,YAAY;aACxC,CAAC,CAAC;YAEH,OAAO,YAAY,CAAC;QAEtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,2BAAW,EAAE,CAAC;gBACjC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,KAAc,CAAC,CAAC;YACxD,MAAM,IAAI,2BAAW,CAAC,8BAA+B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;YAEzC,OAAO;gBACL,MAAM,EAAE,IAAI,CAAC,eAAe;gBAC5B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,KAAc,EAAE,YAAY,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC;gBACxD,OAAO,KAAK,CAAC;YACf,CAAC;YAED,yCAAyC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC;gBAC1C,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;gBAC/B,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE;aACzC,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC;YAEpD,IAAI,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QAEd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC,iCAAiC,EAAE,KAAc,CAAC,CAAC;YACjE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,MAAM,qBAAqB,GAAuC;YAChE,YAAY,EAAE,kCAAkB,CAAC,UAAU;YAC3C,qBAAqB,EAAE,kCAAkB,CAAC,mBAAmB;YAC7D,wBAAwB,EAAE,kCAAkB,CAAC,sBAAsB;YACnE,iBAAiB,EAAE,kCAAkB,CAAC,eAAe;SACtD,CAAC;QAEF,MAAM,eAAe,GAAiC;YACpD,0BAA0B,EAAE,4BAAY,CAAC,wBAAwB;YACjE,2BAA2B,EAAE,4BAAY,CAAC,yBAAyB;YACnE,iCAAiC,EAAE,4BAAY,CAAC,+BAA+B;YAC/E,iCAAiC,EAAE,4BAAY,CAAC,+BAA+B;SAChF,CAAC;QAEF,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAChD,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC3C,SAAS,EAAE,qBAAqB,CAAC,OAAO,CAAC,SAAS,CAAC;SACpD,CAAC,CAAC,CAAC;IACN,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;CACF;AA7MD,sCA6MC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ChatRequest {
|
|
2
|
+
message: string;
|
|
3
|
+
model?: string;
|
|
4
|
+
temperature?: number;
|
|
5
|
+
maxTokens?: number;
|
|
6
|
+
systemPrompt?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ChatResponse {
|
|
9
|
+
content: string;
|
|
10
|
+
model: string;
|
|
11
|
+
timestamp: string;
|
|
12
|
+
finishReason?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ModelInfo {
|
|
15
|
+
name: string;
|
|
16
|
+
displayName: string;
|
|
17
|
+
description: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ListModelsResponse {
|
|
20
|
+
models: ModelInfo[];
|
|
21
|
+
timestamp: string;
|
|
22
|
+
}
|
|
23
|
+
export interface GeminiGenerationConfig {
|
|
24
|
+
temperature?: number;
|
|
25
|
+
maxOutputTokens?: number;
|
|
26
|
+
topP?: number;
|
|
27
|
+
topK?: number;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/gemini/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/gemini/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TextContent, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { GeminiService } from '../services/gemini';
|
|
3
|
+
export declare class GeminiChatTool {
|
|
4
|
+
private geminiService;
|
|
5
|
+
constructor(geminiService: GeminiService);
|
|
6
|
+
getDefinition(): Tool;
|
|
7
|
+
execute(args: any): Promise<TextContent[]>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=gemini-chat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-chat.d.ts","sourceRoot":"","sources":["../../src/tools/gemini-chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,WAAW,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,qBAAa,cAAc;IACb,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEhD,aAAa,IAAI,IAAI;IAyCf,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CA+BjD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GeminiChatTool = void 0;
|
|
7
|
+
const error_handler_1 = require("../utils/error-handler");
|
|
8
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
9
|
+
class GeminiChatTool {
|
|
10
|
+
geminiService;
|
|
11
|
+
constructor(geminiService) {
|
|
12
|
+
this.geminiService = geminiService;
|
|
13
|
+
}
|
|
14
|
+
getDefinition() {
|
|
15
|
+
return {
|
|
16
|
+
name: 'gemini_chat',
|
|
17
|
+
description: 'Chat with Google Gemini models',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
message: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'The message to send'
|
|
24
|
+
},
|
|
25
|
+
model: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
default: 'gemini-2.5-flash',
|
|
28
|
+
enum: this.geminiService.getAvailableModels(),
|
|
29
|
+
description: 'Model to use'
|
|
30
|
+
},
|
|
31
|
+
temperature: {
|
|
32
|
+
type: 'number',
|
|
33
|
+
default: 0.7,
|
|
34
|
+
minimum: 0.0,
|
|
35
|
+
maximum: 1.0,
|
|
36
|
+
description: 'Controls randomness (0.0 to 1.0)'
|
|
37
|
+
},
|
|
38
|
+
max_tokens: {
|
|
39
|
+
type: 'integer',
|
|
40
|
+
default: 2048,
|
|
41
|
+
minimum: 1,
|
|
42
|
+
maximum: 8192,
|
|
43
|
+
description: 'Maximum tokens in response'
|
|
44
|
+
},
|
|
45
|
+
system_prompt: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: 'Optional system instruction'
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
required: ['message']
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async execute(args) {
|
|
55
|
+
try {
|
|
56
|
+
logger_1.default.info('Executing gemini_chat tool', {
|
|
57
|
+
model: args.model,
|
|
58
|
+
messageLength: args.message?.length
|
|
59
|
+
});
|
|
60
|
+
if (!args.message) {
|
|
61
|
+
throw new error_handler_1.McpError('Message is required', 'INVALID_PARAMS');
|
|
62
|
+
}
|
|
63
|
+
const response = await this.geminiService.chat({
|
|
64
|
+
message: args.message,
|
|
65
|
+
model: args.model,
|
|
66
|
+
temperature: args.temperature,
|
|
67
|
+
maxTokens: args.max_tokens,
|
|
68
|
+
systemPrompt: args.system_prompt
|
|
69
|
+
});
|
|
70
|
+
return (0, error_handler_1.createToolResult)(true, response.content);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
logger_1.default.error('gemini_chat tool execution failed', { error });
|
|
74
|
+
if (error instanceof error_handler_1.McpError) {
|
|
75
|
+
return (0, error_handler_1.createToolResult)(false, error.message, error);
|
|
76
|
+
}
|
|
77
|
+
return (0, error_handler_1.createToolResult)(false, `Unexpected error: ${error.message}`, error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.GeminiChatTool = GeminiChatTool;
|
|
82
|
+
//# sourceMappingURL=gemini-chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-chat.js","sourceRoot":"","sources":["../../src/tools/gemini-chat.ts"],"names":[],"mappings":";;;;;;AAEA,0DAAoE;AACpE,6DAAqC;AAErC,MAAa,cAAc;IACL;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,aAAa;QACX,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,gCAAgC;YAC7C,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,OAAO,EAAE;wBACP,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,qBAAqB;qBACnC;oBACD,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,kBAAkB;wBAC3B,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE;wBAC7C,WAAW,EAAE,cAAc;qBAC5B;oBACD,WAAW,EAAE;wBACX,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,GAAG;wBACZ,OAAO,EAAE,GAAG;wBACZ,OAAO,EAAE,GAAG;wBACZ,WAAW,EAAE,kCAAkC;qBAChD;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,IAAI;wBACb,WAAW,EAAE,4BAA4B;qBAC1C;oBACD,aAAa,EAAE;wBACb,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,6BAA6B;qBAC3C;iBACF;gBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;aACtB;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAS;QACrB,IAAI,CAAC;YACH,gBAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;gBACxC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM;aACpC,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,wBAAQ,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAC;YAC9D,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBAC7C,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,IAAI,CAAC,UAAU;gBAC1B,YAAY,EAAE,IAAI,CAAC,aAAa;aACjC,CAAC,CAAC;YAEH,OAAO,IAAA,gCAAgB,EAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAElD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAE7D,IAAI,KAAK,YAAY,wBAAQ,EAAE,CAAC;gBAC9B,OAAO,IAAA,gCAAgB,EAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACvD,CAAC;YAED,OAAO,IAAA,gCAAgB,EAAC,KAAK,EAAE,qBAAsB,KAAe,CAAC,OAAO,EAAE,EAAE,KAAc,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;CACF;AA3ED,wCA2EC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TextContent, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { GeminiService } from '../services/gemini';
|
|
3
|
+
export declare class GeminiListModelsTool {
|
|
4
|
+
private geminiService;
|
|
5
|
+
constructor(geminiService: GeminiService);
|
|
6
|
+
getDefinition(): Tool;
|
|
7
|
+
execute(args: any): Promise<TextContent[]>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=gemini-list-models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-list-models.d.ts","sourceRoot":"","sources":["../../src/tools/gemini-list-models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,qBAAa,oBAAoB;IACnB,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEhD,aAAa,IAAI,IAAI;IAWf,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CAqBjD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GeminiListModelsTool = void 0;
|
|
7
|
+
const error_handler_1 = require("../utils/error-handler");
|
|
8
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
9
|
+
class GeminiListModelsTool {
|
|
10
|
+
geminiService;
|
|
11
|
+
constructor(geminiService) {
|
|
12
|
+
this.geminiService = geminiService;
|
|
13
|
+
}
|
|
14
|
+
getDefinition() {
|
|
15
|
+
return {
|
|
16
|
+
name: 'gemini_list_models',
|
|
17
|
+
description: 'List available Gemini models and their descriptions',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async execute(args) {
|
|
25
|
+
try {
|
|
26
|
+
logger_1.default.info('Executing gemini_list_models tool');
|
|
27
|
+
const response = await this.geminiService.listModels();
|
|
28
|
+
let modelsInfo = 'Available Gemini Models:\n\n';
|
|
29
|
+
for (const model of response.models) {
|
|
30
|
+
modelsInfo += `• **${model.name}**: ${model.description}\n`;
|
|
31
|
+
}
|
|
32
|
+
modelsInfo += `\nLast updated: ${response.timestamp}`;
|
|
33
|
+
return (0, error_handler_1.createToolResult)(true, modelsInfo);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
logger_1.default.error('gemini_list_models tool execution failed', { error });
|
|
37
|
+
return (0, error_handler_1.createToolResult)(false, `Error listing models: ${error.message}`, error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.GeminiListModelsTool = GeminiListModelsTool;
|
|
42
|
+
//# sourceMappingURL=gemini-list-models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-list-models.js","sourceRoot":"","sources":["../../src/tools/gemini-list-models.ts"],"names":[],"mappings":";;;;;;AAEA,0DAA0D;AAC1D,6DAAqC;AAErC,MAAa,oBAAoB;IACX;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,aAAa;QACX,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,qDAAqD;YAClE,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;aACf;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAS;QACrB,IAAI,CAAC;YACH,gBAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAEjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;YAEvD,IAAI,UAAU,GAAG,8BAA8B,CAAC;YAEhD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpC,UAAU,IAAI,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,IAAI,CAAC;YAC9D,CAAC;YAED,UAAU,IAAI,mBAAmB,QAAQ,CAAC,SAAS,EAAE,CAAC;YAEtD,OAAO,IAAA,gCAAgB,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAE5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,OAAO,IAAA,gCAAgB,EAAC,KAAK,EAAE,yBAA0B,KAAe,CAAC,OAAO,EAAE,EAAE,KAAc,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;CACF;AAnCD,oDAmCC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class McpError extends Error {
|
|
2
|
+
code: string;
|
|
3
|
+
statusCode: number;
|
|
4
|
+
constructor(message: string, code?: string, statusCode?: number);
|
|
5
|
+
}
|
|
6
|
+
export declare class GeminiError extends McpError {
|
|
7
|
+
constructor(message: string, code?: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class ConfigurationError extends McpError {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export declare function handleError(error: Error, context?: string): McpError;
|
|
13
|
+
export declare function createToolResult(success: boolean, content: string, error?: Error): {
|
|
14
|
+
type: "text";
|
|
15
|
+
text: string;
|
|
16
|
+
}[];
|
|
17
|
+
//# sourceMappingURL=error-handler.d.ts.map
|