feat(esmole): server wiring and stdio entry
This commit is contained in:
1 parent
49fb98c18b
commit
5aad5f9304
3 files changed
+195
-1
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import { registerConnectionTools } from '@dbmole/core'
|
||||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
||||
import * as z from 'zod'
|
||||
import type { EsBackend } from './es/backend.js'
|
||||
import { ping } from './esBackend.js'
|
||||
import { esFormatError } from './esError.js'
|
||||
import type { EsManager } from './manager.js'
|
||||
import type { EsRegistry } from './registry.js'
|
||||
import {
|
||||
type ConnectionConfig,
|
||||
connectionConfigSchema,
|
||||
defaultPort,
|
||||
type EsResolvedConnection,
|
||||
sshConfigSchema
|
||||
} from './schema.js'
|
||||
import { registerEsTools } from './tools/index.js'
|
||||
|
||||
export const SERVER_VERSION = '0.1.0'
|
||||
|
||||
const patchSchema = z
|
||||
.object({
|
||||
name: z
|
||||
.string()
|
||||
.regex(/^[a-zA-Z0-9_-]+$/)
|
||||
.optional(),
|
||||
host: z.string().min(1).optional(),
|
||||
port: z.number().int().positive().nullable().optional(),
|
||||
user: z.string().min(1).nullable().optional(),
|
||||
password: z.string().nullable().optional(),
|
||||
apiKey: z.string().min(1).nullable().optional(),
|
||||
scheme: z.enum(['http', 'https']).optional(),
|
||||
verifyTls: z.boolean().optional(),
|
||||
readonly: z.boolean().optional(),
|
||||
ssh: sshConfigSchema.nullable().optional()
|
||||
})
|
||||
.strict()
|
||||
|
||||
const publicView = (resolved: EsResolvedConnection) => ({
|
||||
name: resolved.config.name,
|
||||
type: resolved.config.type,
|
||||
scheme: resolved.config.scheme,
|
||||
host: resolved.config.host,
|
||||
port: resolved.config.port ?? defaultPort(),
|
||||
auth: resolved.config.apiKey ? 'apiKey' : 'basic',
|
||||
verifyTls: resolved.config.verifyTls,
|
||||
readonly: resolved.config.readonly,
|
||||
source: resolved.source,
|
||||
ssh: Boolean(resolved.config.ssh)
|
||||
})
|
||||
|
||||
export const createServer = (registry: EsRegistry, manager: EsManager): McpServer => {
|
||||
const server = new McpServer({ name: 'esmole-mcp', version: SERVER_VERSION })
|
||||
registerConnectionTools<ConnectionConfig, EsBackend>(server, {
|
||||
registry,
|
||||
manager,
|
||||
fullSchema: connectionConfigSchema,
|
||||
patchSchema,
|
||||
publicView,
|
||||
formatError: esFormatError,
|
||||
ping,
|
||||
descriptions: {
|
||||
list: 'List configured Elasticsearch connections with their source layer (env/config/store). Secrets are omitted.',
|
||||
add: 'Add a named Elasticsearch connection to the persistent store. Auth via user/password or apiKey; optional ssh tunnel, readonly flag, scheme and verifyTls.',
|
||||
update: 'Patch a stored ES connection by name. Set a field to null to remove it. Only store-sourced connections can be edited.',
|
||||
remove: 'Remove a stored ES connection by name and drop its cached client/tunnel.',
|
||||
test: 'Verify an ES connection works end to end (including ssh tunnel). Reports server version and latency.'
|
||||
}
|
||||
})
|
||||
registerEsTools(server, manager)
|
||||
return server
|
||||
}
|
||||
Reference in new issue
Block a user