Altinity / Altinity/altinity-mcp

Dynamic write tools: parse COMMENT-JSON descriptors the way view tools do

Open
#154 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
38
Forks
8
Avg merge
6d 14h
Merged PRs (30d)
8

Description

Summary

Dynamic read tools (view_regexp) get first-class descriptor handling: a JSON COMMENT on the view is parsed into the MCP tool's title, description, and per-param docs (parseDynamicToolComment / applyCommentParamOverrides, covered by server_dynamic_tools_test.go).

Dynamic write tools (table_regexp + mode: insert) handle the same convention only halfway: with a JSON COMMENT on the target table,

  • the params docs from the JSON are applied to the tool's input schema (each column parameter shows its description from the JSON params map), but
  • the tool description is the raw, unparsed JSON text verbatim — braces, quotes, "annotations" block and all.

Feature request: run the same COMMENT-JSON parse on the write-tool path, with the same fallback (invalid JSON → raw text as description) so plain-text comments keep working.

Observed behavior

Table (26.3, Null engine — the standard raw-write-target shape):

CREATE TABLE mcp.entries_raw (source_db String, facts String)
ENGINE = Null
COMMENT '{
  "title": "Save Memory",
  "description": "Save this session verified findings ... (long usage contract)",
  "params": {
    "source_db": "Which dataset these facts describe, e.g. eth. ...",
    "facts": "JSON array of fact objects (see description for the object shape). ..."
  },
  "annotations": {"openWorldHint": false}
}';

Tools rule:

- type: write
  name: save_memory
  table_regexp: "^mcp\\.entries_raw$"
  mode: insert

Reflected tool as seen by a real MCP client (claude.ai connector, multicluster deployment):

  • save_memory.description = the entire raw JSON string above, newlines included;
  • save_memory input schema params source_db / facts = the parsed descriptions from the JSON params map (so part of the pipeline clearly runs).

A sibling view with the identical COMMENT convention on the same deployment reflects cleanly: parsed description, parsed param docs, no JSON wrapper.

Why this matters (reasoning)

  1. For write tools, the description is the usage contract. A read tool that's slightly under-described degrades gracefully — the model can inspect the result shape. A write tool can't be probed safely: everything the agent must know before calling (payload object shape, id/slug conventions, update-vs-create semantics, atomicity of batches, what's rejected and why) has to travel in the description. In our deployment (save_memory for a shared agent-memory store, companion to #151) that contract is ~1,400 chars of load-bearing text.
  2. It's the only guaranteed channel to connector-only clients. Server instructions isn't configurable today, and third-party clients (claude.ai, ChatGPT) show exactly what the tool list carries. The COMMENT is the right place to author this — it lives next to the schema, versions with DDL, and needs no Go/helm change — which is precisely the design point of the dynamic-tool COMMENT convention for views.
  3. Consistency of the convention. The same JSON COMMENT document is fully honored on a view and half-honored on a table. Authors discover this only after deploying and inspecting a live client's tool list; the halfway state (params parsed, description raw) reads like a bug rather than a choice.
  4. Raw JSON in the description has real costs: it's re-sent to the model in every session's tool list (token overhead for the wrapper/escapes), it's harder for models to read than prose, and it renders as visibly broken in client tool-list UIs.

Suggested behavior

In the write-tool registration path, treat the target table's COMMENT exactly like a view comment:

  • valid descriptor JSON → title / description / params overrides (params keyed by column name, as already happens);
  • anything else → current behavior (raw comment text as description).

Backward compatible: existing plain-text table comments render unchanged; existing JSON comments start rendering as intended.

Environment

altinity-mcp multicluster (image fix-cimd-grant-types-99f0e05-arm64), ClickHouse 26.3.17.4, tools observed through the claude.ai connector. Related: #151 (dynamic SQL-view schema tools — the read-side counterpart of this deployment).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with parseDynamicToolComment, applyCommentParamOverrides, and server_dynamic_tools_test.go, then trace the dynamic write-tool registration path for table_regexp with mode: insert. Add coverage showing valid table COMMENT JSON supplies the parsed description while preserving title and parameter overrides, and invalid JSON or plain text remains the raw description.

Written by the indexing model from the issue text.

Assessment

Tech stack
clickhouse, go
Domain
api, backend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.