-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.js
More file actions
114 lines (92 loc) · 3.25 KB
/
bootstrap.js
File metadata and controls
114 lines (92 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/**
* Thoth plugin bootstrap
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.2.0
* @version 0.2.0
*/
/**
* Store for all registered MCP servers
*/
Plugin.mcp_servers = new Map();
/**
* Create and register an MCP server
*
* @param {Object} options
* @param {string} options.name Server identifier (required)
* @param {string} options.path URL path to mount on
* @param {boolean} options.require_api_key Require API key auth
* @param {boolean} options.allow_anonymous Allow anonymous access
* @param {number} options.session_timeout Session timeout in ms
* @param {Array} options.tool_classes Tool class names to include
* @param {Array} options.tool_names Specific tool names to include
* @param {boolean} options.include_core_tools Include core tools always
*
* @return {Thoth.Mcp.Server}
*/
Plugin.createMcpServer = function createMcpServer(options) {
if (!options?.name) {
throw new Error('MCP server requires a name');
}
if (this.mcp_servers.has(options.name)) {
throw new Error('MCP server with name "' + options.name + '" already exists');
}
let server = new Classes.Thoth.Mcp.Server(options.name, options);
this.mcp_servers.set(options.name, server);
return server;
};
/**
* Get an MCP server by name
*
* @param {string} name
*
* @return {Thoth.Mcp.Server|null}
*/
Plugin.getMcpServer = function getMcpServer(name) {
return this.mcp_servers.get(name) || null;
};
/**
* Get all registered MCP servers
*
* @return {Map<string, Thoth.Mcp.Server>}
*/
Plugin.getAllMcpServers = function getAllMcpServers() {
return this.mcp_servers;
};
// =============================================================================
// Create MCP servers from configuration
// =============================================================================
STAGES.getStage('routes').addPostTask(async () => {
// Set up MCP devmode endpoints if ai-devmode is enabled
if (alchemy.ai_devmode_enabled) {
require('./scripts/setup_mcp_devmode.js')();
}
// Get MCP server config - check plugin default_settings first, then alchemy settings
let plugin = alchemy.plugins.thoth;
let mcp_servers_config = plugin?.default_settings?.mcp_servers;
// If not found in default_settings, try the settings system
if (!mcp_servers_config) {
mcp_servers_config = alchemy.getSetting('plugins.thoth.mcp_servers');
}
if (!mcp_servers_config || Object.keys(mcp_servers_config).length === 0) {
log.info('MCP bootstrap: No MCP servers configured');
return;
}
log.info('MCP bootstrap: Found', Object.keys(mcp_servers_config).length, 'servers to create');
for (let [name, config] of Object.entries(mcp_servers_config)) {
try {
log.info('MCP bootstrap: Creating server:', name, 'with config:', config);
// Add name to config if not present
config.name = name;
// Create the server
let server = Plugin.createMcpServer(config);
// Create routes
server.createRoutes();
// Initialize the server
await server.initialize();
log.info('MCP bootstrap: Created MCP server:', name, 'at path:', server.path);
} catch (err) {
log.error('MCP bootstrap: Failed to create MCP server "' + name + '":', err);
}
}
});