feat(resolvemcp): replace per-model tools with fixed meta tools, guarded filter writes and a function registry

Tools: list_tables, describe_table, select_table, insert_into_table, update_table,
delete_from_table, list_functions, call_function. Visibility follows the model rules.
Filter-based update/delete require filters (never dropped silently), cap the matched rows
(MaxWriteRows), support dry_run, and need a single-use confirm token bound to caller, table,
filters, data and the matched rows. RegisterFunction adds Go-callback and SQL-procedure
functions run in a transaction with BeforeCall/AfterCall hooks. Per-model tools and
resources are removed.

fix(pgsql): UPDATE with SET and a multi-placeholder WHERE renumbered the WHERE parameters
wrongly ($1, $2 became $3, $2); shift them in one pass.
This commit is contained in:
Hein
2026-10-01 13:40:00 +02:00
parent 276c3814d8
commit e49c3a916e
11 changed files with 1562 additions and 370 deletions
+6 -3
View File
@@ -33,6 +33,8 @@ type Handler struct {
version string
oauth2Regs []oauth2Registration
oauthSrv *security.OAuthServer
functions functionRegistry
confirms *confirmStore
}
// NewHandler creates a Handler with the given database, model registry, and config.
@@ -43,9 +45,11 @@ func NewHandler(db common.Database, registry common.ModelRegistry, cfg Config) *
hooks: NewHookRegistry(),
mcpServer: server.NewMCPServer("resolvemcp", "1.0.0"),
config: cfg.withDefaults(),
confirms: newConfirmStore(),
name: "resolvemcp",
version: "1.0.0",
}
registerMetaTools(h)
if cfg.EnableAnnotations {
registerAnnotationTool(h)
}
@@ -165,13 +169,13 @@ func requestBaseURL(r *http.Request) string {
return scheme + "://" + r.Host
}
// RegisterModel registers a model and immediately exposes it as MCP tools and a resource.
// RegisterModel registers a model. It becomes visible to the fixed meta tools (list_tables,
// select_table, ...); no per-model tools are created.
func (h *Handler) RegisterModel(schema, entity string, model interface{}) error {
fullName := buildModelName(schema, entity)
if err := h.registry.RegisterModel(fullName, model); err != nil {
return err
}
registerModelTools(h, schema, entity, model)
return nil
}
@@ -187,7 +191,6 @@ func (h *Handler) RegisterModelWithRules(schema, entity string, model interface{
if err := reg.RegisterModelWithRules(fullName, model, rules); err != nil {
return err
}
registerModelTools(h, schema, entity, model)
return nil
}