AI and agents

MCP, A2A and ZAANIX AI

The MCP server (stdio, SSE, Streamable HTTP), the REST/OpenAPI façade, registered agents with per-framework snippets, human-in-the-loop approval, and the AI built into every page.

ZAANIX treats agents as first-class users. One tool registry backs three surfaces, so they can never drift:

  • MCP server — stdio, legacy SSE and Streamable HTTP; 94 tools (and the agent's own), with resources and guided prompts.
  • REST façade — GET /api/agent/v1/tools (names, descriptions, JSON-schema inputs) and POST /api/agent/v1/tools/<tool> (returns {text, structured, is_error}; invalid arguments → 400).
  • OpenAPI 3.0 — GET /api/agent/openapi.json, generated on the fly for Bedrock Agents action groups and AgentCore Gateway targets.

Transports#

ModeHow
stdiozaanix mcp --token zx_… [--workspace <id>] (or ZAANIX_API_TOKEN) — stdout is JSON-RPC only, logs go to stderr
SSE (2024-11-05)GET /mcp/sse + POST /mcp/messages?sessionId=… with Authorization: Bearer zx_…
Streamable HTTP (2025-03-26)POST/GET/DELETE /mcp with Authorization: Bearer zx_… and mcp-session-id

Tokens need the mcp scope (plus write for mutations and admin for administrative SQL). A token may be pinned to one workspace; otherwise pass workspace_id to tools or ?workspace_id= on connect.

claude mcp add --transport http zaanix http://localhost:4200/mcp --header "Authorization: Bearer zx_…"

Tools#

ToolPurpose
execute_query(sql, workspace_id?, page_size?, page?, dry_run?)Runs SQL; returns a Markdown table + typed JSON (columns, rows, total_rows, truncated, rows_changed). Hard cap 200 rows per call, long strings truncated. Mutations need dry_run=false. Read-only results are served from the result cache.
profile_dataset(table_or_path, workspace_id?)SUMMARIZE stats: types, min/max, approx distinct, null %, quartiles, row count, footprint.
explain_query(sql, workspace_id?, analyze?)Physical plan as JSON tree + ASCII with cardinality estimates; analyze=true adds measured timings (read-only SQL only).
list_accessible_data(workspace_id?)Workspaces (own and shared), tables/views with columns, every data file / Delta / Iceberg table in the jail, and attached lakehouse catalogs.
save_dataset(sql, output_format, target_filename, workspace_id?, dry_run?)COPY (sql) TO parquet/csv/json inside the jail (exports/ by default).
browse_storage(provider?, path?, connection_id?, bucket?, catalog?, schema?)One level of the data directory, cloud connections → buckets → objects, or lakehouse connections → schemas → tables.
inspect_schema(file_path_or_table, connection_id?)Columns/types/nullability for tables, files, remote objects, .duckdb files, attached lakehouse tables or a SELECT — no scan.
lakehouse_query(connection_id, sql, page_size?, dry_run?)SQL on a Databricks SQL warehouse; non-read statements need dry_run=false after approval.
list_dashboards(workspace_id?)Dashboards with their widgets and layouts.
create_dashboard_widget(dashboard_id | dashboard_name, title, sql, widget_type, chart_config?, refresh_interval_sec?)Builds dashboards autonomously; the SQL is validated read-only and dry-run first.
create_mosaic_dashboard(spec | spec_text, name?, description?, dashboard_id?, validate_only?, workspace_id?)Creates or updates an interactive Mosaic dashboard from a declarative spec (YAML/JSON). Validated structurally and every dataset/table bound with EXPLAIN before saving; errors come back as a list to fix.
list_data_sources(workspace_id?)Every connection with health (connector connections included), the syncs of a workspace, the source-type catalog.
browse_connector(connection_id, path?)Walks a warehouse, SaaS or Google connection one level at a time; leaves carry the resource for create_data_sync.
connector_query(connection_id, sql, limit?)Read-only SQL on Snowflake, BigQuery, Redshift or ClickHouse; rows capped.
create_data_sync(name, source, target_table, …, transform_sql?, schedule?, run_now?)Scheduled load of a table / connector resource / URL / SELECT into a workspace table with an optional {{raw}} transformation, validated first.
update_data_sync(sync_id, transform_sql?, schedule?, mode?, enabled?, run_now?)Attach a transformation, change the schedule, pause/resume.
run_data_sync(sync_id)Run now; rows, duration, error, recent runs.
list_apps · create_app(name, source, …) · update_app · run_app · stop_app · get_app_logs · preview_app · publish_appStreamlit data apps: generated from a dashboard, saved queries or code (validated first), run, previewed with a screenshot, published after human approval.

The table above is the core. The other tools, by area (the Tools tab of the Agents page and GET /api/agent/v1/tools list all 90 with their inputs):

AreaTools
Dashboardsbuild_dashboard (a whole dashboard from a checked plan), get_dashboard, update_widget, remove_widget, snapshot_dashboard
Notebooks and querieslist_notebooks, get_notebook, create_notebook, run_notebook, list_saved_queries, get_saved_query, save_query, query_history
Explore and preparesearch_workspace, search_catalog, diff_tables, find_joins, prepare_data
dbt and metricslist_dbt_projects, get_dbt_project, create_dbt_project, write_dbt_files, create_dbt_model, run_dbt, get_dbt_run, list_metrics, query_metrics, define_metric
Quality and monitoringlist_quality_suites, suggest_quality_checks, create_quality_suite, run_quality_suite, list_watches, create_watch, check_watch, detect_anomalies, list_insights, create_metric_monitor
Governanceget_lineage, annotate_table, scan_pii, tag_pii, protect_pii
Delivery and publishinglist_alerts, create_alert, run_alert, list_endpoints, publish_endpoint, list_reverse_syncs, create_reverse_sync, run_reverse_sync, list_streams
Collaborationlist_comments, add_comment, list_templates, install_template
Agentslist_agents, ask_agent (ZAANIX agents and remote A2A agents)
The workspaceworkspace_health, list_backups, backup_workspace, create_stream, git_status, git_commit, get_usage

Anything that changes data, publishes or reaches outside waits for approval (below).

Resources — duckdb://workspaces, duckdb://schemas/{workspace_id} (DDL + column map + files), duckdb://system/resources (CPUs, RAM, DuckDB ceiling, spill disk, active engines), duckdb://guides/mosaic-spec (how to write a Mosaic dashboard spec).

Prompts — data_quality_audit(table_or_path), sql_optimization(sql), build_mosaic_dashboard(table_or_path, goal?) and build_data_pipeline(source, goal?) encode complete agent workflows over the tools above.

Human-in-the-loop#

Any mutating statement from an MCP / API-token actor returns an approval_required challenge — the verbs, per-statement previews and how to proceed — instead of executing. The agent shows it to the human; if approved, it calls the tool again with the identical SQL and dry_run: false. Members of a shared workspace with viewer access cannot mutate even then.

Registered agents#

The Agents page (MCP clients) registers the agents that call ZAANIX and gives each one a dedicated, workspace-scoped token (read + mcp, optionally write — mutations are still held for approval). Every tool call is attributed to the agent (call/error counters, "last seen", the live inspector shows the agent name and whether it came over MCP or REST). Copy-paste snippets are generated per framework with the token substituted:

FrameworkIntegration
Strands AgentsMCPClient(lambda: streamablehttp_client(url, headers=…)) → Agent(tools=…)
LangGraph / LangChainlangchain-mcp-adapters MultiServerMCPClient → create_react_agent / create_agent
CrewAIMCPServerAdapter({url, transport: "streamable-http", headers})
AgentCore RuntimeBedrockAgentCoreApp entrypoint deployable with the starter toolkit; ZAANIX can invoke it back (InvokeAgentRuntime) from Settings › Developers › Connected agents, or as the AI model
AgentCore GatewayZAANIX as an MCP server target or an OpenAPI target (API-key credential provider holding the ZAANIX token)
Bedrock Agents (Classic)Action group from the generated OpenAPI document + a Lambda forwarder to the REST façade
Custom / HTTPcurl, Python requests, or any MCP client config

Endpoints: GET/POST /api/agents, GET/PATCH/DELETE /api/agents/:id, POST /api/agents/:id/rotate-token, GET /api/agents/:id/snippets, POST /api/agents/:id/test, POST /api/agents/:id/invoke (SSE), GET /api/agents/discover?kind=…, GET /api/agents/frameworks.

AI in every page#

There is no chat drawer: the AI works where you are, through the same runtime as ZAANIX Agent, and every AI control is hidden when no model is set.

WhereWhat
Any object's "..."Ask about this: a mission scoped to the table, dashboard, notebook, query or app on screen, in a side panel
SQL workbench⌘I writes SQL from a sentence; Fix rewrites a failing query; Explain reads a result
Notebook cellsWrite this cell and Explain
Table pagesDescribe drafts notes for the table and its columns; Suggest checks proposes checks tried on the data
Dashboards, metrics, pipelines, appsBuild with AI, questions answered from metrics, Draft with AI for transformations and apps

Settings › AI › Model is the console: pick a provider (Claude, ChatGPT, Gemini, DeepSeek, OpenRouter, Kimi, Groq, Mistral, Grok, Ollama, any OpenAI-compatible endpoint, Amazon Bedrock, Bedrock Agent, AgentCore), paste a key, test, save — stored encrypted, never shown again. People can keep their own key there where administrators allow it. Everything runs within the agent policy (access, daily budget, hourly rate) and is counted under Settings › AI › Usage.

ZAANIX agents and the marketplace#

Agents → ZAANIX agents runs agents ZAANIX hosts itself: instructions, a task for scheduled runs, the tools they may use (read-only), a limit on tool calls, a schedule and channels for their reports. The marketplace installs ready-made ones in one click:

AgentDoesDefault schedule
Anomaly investigatorfinds unusual metrics and breaks each change downevery morning
Weekly business reviewlast week's headline metrics against the week before and the 4-week averageMondays
Data quality auditorfailing checks, important tables without checks, the checks to addevery morning
Pipeline watcherfailed syncs, dbt runs, quality checks, alerts and reverse syncsevery morning
Catalog writertable and column descriptions drafted from profileswhen asked
dbt reviewerfailing and slow models, models without tests or docsMondays
Data analystanswers questions with the metrics or SQLwhen asked

Agent2Agent (A2A)#

ZAANIX speaks A2A (protocol 0.3) both ways. A ZAANIX agent with Other agents can call it gets a public Agent Card and a JSON-RPC endpoint (message/send, message/stream, tasks/get, tasks/cancel); each call runs as the caller, read-only, under their access policies. Under Agents you can ask, add a remote agent by its card's URL; list_agents and ask_agent let ZAANIX's AI and agents hand it a question. Calls go through the same egress guard as webhooks.

ZAANIX Agent#

For people rather than programs, ZAANIX Agent is a separate web app on top of these tools: missions, a context panel, approvals with an autonomy dial, and briefs — working as the signed-in person.