Tags: Altinity/altinity-mcp
Tags
Unified tools config with dynamic write tool discovery Introduces a single `server.tools` array that describes both static (execute_query, write_query) and dynamic (regexp-matched) tools in one place. The legacy `server.dynamic_tools` form still works and emits a deprecation warning; rules are converted internally. Tool semantics - execute_query: ALWAYS read-only. New HandleReadOnlyQuery wrapper rejects non-SELECT statements with a clear error pointing at write_query. Annotation is always ReadOnlyHint:true regardless of the server's read-only flag. - write_query: destructive; skipped entirely when read_only=true. - Dynamic read tools (views): preserved; now use GetClickHouseClientFromCtx so forward-OAuth mode works. - Dynamic write tools (tables): new. Discovered from system.tables, filter out MATERIALIZED/ALIAS columns, generate INSERT statements with parameter validation. Only "insert" mode is implemented; "update" and "upsert" are rejected at registration time. EnsureDynamicTools - Lazy: first tools/list with no Bearer returns static tools; the first authenticated tools/call triggers discovery. SDK's AddTool fires notifications/tools/list_changed automatically. - Non-blocking: RWMutex fast path for the steady state; TryLock so concurrent requests during initial discovery don't block on CH round-trips. - Credential-aware: hasDiscoveryCredentials() skips discovery when no JWE/OAuth/static creds exist so the next request can retry. Integrations preserved: tool_input_settings schema is added to both execute_query and write_query and to discovered dynamic tools. Dynamic write handlers call applyToolInputSettings and checkBlockedClauses so those guardrails extend to INSERTs. getArgumentsMap now returns (map, error). Handlers propagate parse errors to clients instead of silently proceeding with empty arguments. Column filtering uses `default_kind` only; avoids `column_type` which doesn't exist in all ClickHouse versions (e.g. 26.1.x Antalya). RegisterTools now takes *config.Config so converted dynamic rules land in cfg.Server.DynamicTools for EnsureDynamicTools to consume. Tests: - TestRegisterTools_Annotations: updated for the split semantics. - TestRegisterToolsAndResources, TestRegisterToolsWithSettings: default config now registers 2 tools; assertions cover both. - TestRegisterTools_UnifiedConfig: covers the new Tools config path, unsupported-mode rejection, and legacy DynamicTools migration. - TestBuildInsertQuery, TestBuildDynamicWriteQuery, TestBuildWriteToolDescription: pure-function write-path coverage (required params, unicode, null bytes, quote escaping). - TestHasDiscoveryCredentials, TestFilterRulesByType: cover new helpers. - TestGetArgumentsMap_ErrorPath: updated for the new (map, error) signature. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Merge feature/input-hardening: query size limit and error truncation Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Fix tools-management issues from app-team review 1. getArgumentsMap now returns (map, error) instead of silently swallowing JSON parse errors. All 5 call sites updated to surface the error to the MCP client instead of producing cryptic downstream errors. 2. Add clickhouse.max_query_length (default 10MB) and max_parameter_size (default 10MB) limits. Oversize inputs rejected before reaching CH. 3. New truncateErrForClient helper caps error messages sent to clients at 2000 chars. Full error still logged server-side. 5 call sites updated. 4. Unit tests for buildInsertQuery (unicode, null bytes, backslash, quote escaping, required-param validation, optional-param omission, no-columns) and buildDynamicWriteQuery (mode dispatch, unsupported mode rejection). New TestRegisterTools_RejectsUnsupportedWriteModes covers config-time rejection of update/upsert modes. 5. EnsureDynamicTools now uses RWMutex fast path + TryLock so concurrent requests don't block during initial slow discovery — they see static tools immediately and get updated via notifications/tools/list_changed when discovery completes. Cleanup: - Remove dead dynamicToolMeta.IsStatic field - Reject update/upsert write modes at config-parse time in RegisterTools instead of at call time (the tool no longer registers if it can't work) - Simplify buildDynamicWriteQuery dispatcher (only insert is valid) - Update TestGetArgumentsMap_ErrorPath to match new error-returning behavior Declined from review spec: - 1MB query limit default (too restrictive for OLAP; using 10MB) - 1000-char error truncation (too aggressive; using 2000) Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
docs: add CHANGELOG entries for v1.3.1–v1.3.4 and v1.4.0 Add missing changelog sections for all releases since v1.3.0: - v1.3.1: lazy loading, param type fix, dep bumps - v1.3.2: JSON comments for dynamic tools - v1.3.3: comment format refactor, dep bumps - v1.3.4: per-connection refresh, signature detection, bug fixes - v1.4.0: OAuth 2.0, tool_input_settings, safety hints, read-only enforcement Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
PreviousNext