MCPcopy Index your code
hub / github.com/bytebase/dbhub / createCustomToolHandler

Function createCustomToolHandler

src/tools/custom-tool-handler.ts:156–247  ·  view source on GitHub ↗
(toolConfig: ToolConfig)

Source from the content-addressed store, hash-verified

154 * @returns Handler function compatible with MCP server.registerTool
155 */
156export function createCustomToolHandler(toolConfig: ToolConfig) {
157 // Build Zod schema shape for MCP registration
158 const zodSchemaShape = buildZodSchemaFromParameters(toolConfig.parameters);
159 // Wrap in z.object() for validation
160 const zodSchema = z.object(zodSchemaShape);
161
162 return async (args: any, extra: any) => {
163 const startTime = Date.now();
164 let success = true;
165 let errorMessage: string | undefined;
166 let paramValues: any[] = [];
167
168 try {
169 // 1. Validate arguments against Zod schema
170 const validatedArgs = zodSchema.parse(args);
171
172 // 2. Ensure source is connected (handles lazy connections)
173 await ConnectorManager.ensureConnected(toolConfig.source);
174
175 // 3. Get connector for the specified source
176 const connector = ConnectorManager.getCurrentConnector(toolConfig.source);
177
178 // 4. Build execute options from tool configuration
179 const executeOptions = {
180 readonly: toolConfig.readonly,
181 maxRows: toolConfig.max_rows,
182 };
183
184 // 5. Check if SQL is allowed based on readonly mode
185 const isReadonly = executeOptions.readonly === true;
186 if (isReadonly && !isAllowedInReadonlyMode(toolConfig.statement, connector.id)) {
187 errorMessage = createReadonlyViolationMessage(toolConfig.name, toolConfig.source, connector.id);
188 success = false;
189 return createToolErrorResponse(errorMessage, "READONLY_VIOLATION");
190 }
191
192 // 6. Map parameters to array format for SQL execution
193 paramValues = mapArgumentsToArray(
194 toolConfig.parameters,
195 validatedArgs
196 );
197
198 // 7. Execute SQL with parameters
199 const result = await connector.executeSQL(
200 toolConfig.statement,
201 executeOptions,
202 paramValues
203 );
204
205 // 8. Build response data
206 const responseData = {
207 rows: result.rows,
208 count: result.rowCount,
209 source_id: toolConfig.source,
210 };
211
212 return createToolSuccessResponse(responseData);
213 } catch (error) {

Callers 2

registerCustomToolFunction · 0.85

Calls 11

createToolErrorResponseFunction · 0.85
mapArgumentsToArrayFunction · 0.85
trackToolRequestFunction · 0.85
ensureConnectedMethod · 0.80
getCurrentConnectorMethod · 0.80
parseMethod · 0.65
executeSQLMethod · 0.65

Tested by

no test coverage detected