{
  "type": "stack",
  "id": "data-analysis-agent",
  "title": "Data analysis agent stack",
  "summary": "An agent that answers questions from your data: it queries DuckDB files, a ClickHouse warehouse or Postgres through read-only MCP servers, runs heavier analysis in a sandbox, reads spreadsheets and PDFs, and is tested and traced so you can trust the numbers.",
  "author": "Agentica Author",
  "tags": [
    "data-analysis",
    "sql",
    "analytics",
    "mcp",
    "duckdb",
    "clickhouse",
    "postgres",
    "read-only"
  ],
  "published": "2026-10-19",
  "last_verified": "2026-10-19",
  "entries": [
    "claude-agent-sdk",
    "motherduck-mcp-server",
    "clickhouse-mcp-server",
    "postgres-mcp-pro",
    "mcp-toolbox-databases",
    "e2b",
    "markitdown",
    "evidently",
    "langfuse",
    "redis-mcp-server",
    "elastic-agent-builder-mcp",
    "pinecone-mcp-server",
    "neon-mcp-server",
    "supabase-mcp",
    "docling"
  ],
  "links": {
    "html": "https://indexagentica.com/stacks/data-analysis-agent/",
    "markdown": "https://indexagentica.com/stacks/data-analysis-agent.md",
    "json": "https://indexagentica.com/api/longform/stacks/data-analysis-agent.json",
    "source": "https://github.com/Drudley/indexagentica/blob/main/content-long/stacks/data-analysis-agent.md"
  },
  "status": "published",
  "stack": {
    "use_case": "Answer business and research questions from tabular data (local files, a cloud warehouse or an operational Postgres) with SQL and Python, show the queries behind every number, and never change the data unless a human allows it.",
    "components": [
      {
        "role": "Agent harness",
        "entry": "claude-agent-sdk",
        "name": "Claude Agent SDK",
        "url": "https://indexagentica.com/entries/claude-agent-sdk/",
        "why": "Claude Code's agent loop as a Python or TypeScript library, with MCP connections, subagents and permission controls over which tools run automatically and which need approval."
      },
      {
        "role": "Local files and lake data",
        "entry": "motherduck-mcp-server",
        "name": "MotherDuck / DuckDB MCP Server",
        "url": "https://indexagentica.com/entries/motherduck-mcp-server/",
        "why": "The open-source local server opens DuckDB files read-only by default, as well as in-memory databases, S3-hosted DuckDB and MotherDuck. The managed remote server at api.motherduck.com/mcp adds OAuth and MotherDuck's Dives, Flights and Guides."
      },
      {
        "role": "Warehouse",
        "entry": "clickhouse-mcp-server",
        "name": "ClickHouse MCP Server",
        "url": "https://indexagentica.com/entries/clickhouse-mcp-server/",
        "why": "ClickHouse's official server runs queries read-only by default. Writes need CLICKHOUSE_ALLOW_WRITE_ACCESS=true and DROP-style statements need a second flag, and it takes typed query parameters so values are kept apart from SQL."
      },
      {
        "role": "Operational Postgres",
        "entry": "postgres-mcp-pro",
        "name": "Postgres MCP Pro",
        "url": "https://indexagentica.com/entries/postgres-mcp-pro/",
        "why": "Restricted mode limits the server to read-only transactions and caps execution time, and EXPLAIN and index-tuning tools help the agent understand why a query is slow before it runs it."
      },
      {
        "role": "Many databases, fixed queries",
        "entry": "mcp-toolbox-databases",
        "name": "MCP Toolbox for Databases",
        "url": "https://indexagentica.com/entries/mcp-toolbox-databases/",
        "why": "When the agent should only run vetted queries, Toolbox lets you define parameterized SQL tools across many engines instead of handing over raw SQL."
      },
      {
        "role": "Analysis sandbox",
        "entry": "e2b",
        "name": "E2B",
        "url": "https://indexagentica.com/entries/e2b/",
        "why": "Runs the agent's pandas, plotting or modeling code in an isolated cloud sandbox instead of on your machine. Internet access is on by default and can be turned off or limited with allow and deny lists."
      },
      {
        "role": "Spreadsheets and documents",
        "entry": "markitdown",
        "name": "MarkItDown",
        "url": "https://indexagentica.com/entries/markitdown/",
        "why": "Converts Excel, PDF, Word and other files to Markdown so the agent can read tables and reports that are not in a database. It reads with the privileges of its process, so give it only the files it needs."
      },
      {
        "role": "Answer testing",
        "entry": "evidently",
        "name": "Evidently",
        "url": "https://indexagentica.com/entries/evidently/",
        "why": "Open-source evals with LLM judges and text checks. Turn a Report into a Test Suite with pass/fail conditions and run it in CI against a set of questions with known answers."
      },
      {
        "role": "Tracing",
        "entry": "langfuse",
        "name": "Langfuse",
        "url": "https://indexagentica.com/entries/langfuse/",
        "why": "Records every model call, tool call and SQL statement, so a reviewer can see which query produced which number, and so real questions can become test cases."
      }
    ]
  },
  "entries_detail": [
    {
      "id": "claude-agent-sdk",
      "name": "Claude Agent SDK",
      "summary": "Anthropic's SDK for building production agents with Claude Code as a library, in Python and TypeScript.",
      "url": "https://indexagentica.com/entries/claude-agent-sdk/",
      "json": "https://indexagentica.com/api/entries/claude-agent-sdk.json"
    },
    {
      "id": "motherduck-mcp-server",
      "name": "MotherDuck / DuckDB MCP Server",
      "summary": "MCP servers for DuckDB and MotherDuck: a managed remote server at api.motherduck.com/mcp and an open-source local server for DuckDB files, in-memory DBs and S3.",
      "url": "https://indexagentica.com/entries/motherduck-mcp-server/",
      "json": "https://indexagentica.com/api/entries/motherduck-mcp-server.json"
    },
    {
      "id": "clickhouse-mcp-server",
      "name": "ClickHouse MCP Server",
      "summary": "ClickHouse's official MCP server: run SQL, list databases and tables on a ClickHouse cluster (read-only by default), with optional embedded chDB queries.",
      "url": "https://indexagentica.com/entries/clickhouse-mcp-server/",
      "json": "https://indexagentica.com/api/entries/clickhouse-mcp-server.json"
    },
    {
      "id": "postgres-mcp-pro",
      "name": "Postgres MCP Pro",
      "summary": "Open-source Postgres MCP server with database health checks, index tuning, EXPLAIN plans with hypothetical indexes, schema intelligence and safe, configurable SQL execution.",
      "url": "https://indexagentica.com/entries/postgres-mcp-pro/",
      "json": "https://indexagentica.com/api/entries/postgres-mcp-pro.json"
    },
    {
      "id": "mcp-toolbox-databases",
      "name": "MCP Toolbox for Databases",
      "summary": "Google's open-source MCP server for databases: prebuilt tools for MCP clients plus a framework for defining secure custom database tools for agents.",
      "url": "https://indexagentica.com/entries/mcp-toolbox-databases/",
      "json": "https://indexagentica.com/api/entries/mcp-toolbox-databases.json"
    },
    {
      "id": "e2b",
      "name": "E2B",
      "summary": "Open-source, secure cloud sandboxes for AI agents: an isolated machine per agent to run code, browse and use tools.",
      "url": "https://indexagentica.com/entries/e2b/",
      "json": "https://indexagentica.com/api/entries/e2b.json"
    },
    {
      "id": "markitdown",
      "name": "MarkItDown",
      "summary": "Microsoft's lightweight Python utility for converting PDF, Office, images, audio, HTML and more into structure-preserving Markdown for LLMs.",
      "url": "https://indexagentica.com/entries/markitdown/",
      "json": "https://indexagentica.com/api/entries/markitdown.json"
    },
    {
      "id": "evidently",
      "name": "Evidently",
      "summary": "Open-source Python framework to evaluate, test and monitor ML and LLM systems, with 100+ built-in metrics, LLM judges, test suites for CI and a monitoring UI.",
      "url": "https://indexagentica.com/entries/evidently/",
      "json": "https://indexagentica.com/api/entries/evidently.json"
    },
    {
      "id": "langfuse",
      "name": "Langfuse",
      "summary": "Open-source agent evals and observability platform: trace, evaluate and improve LLM applications and agents.",
      "url": "https://indexagentica.com/entries/langfuse/",
      "json": "https://indexagentica.com/api/entries/langfuse.json"
    },
    {
      "id": "redis-mcp-server",
      "name": "Redis MCP Server",
      "summary": "Official Redis MCP server: lets agents read and write strings, hashes, lists, sets, sorted sets, streams, JSON and pub/sub, and manage vector indexes and search.",
      "url": "https://indexagentica.com/entries/redis-mcp-server/",
      "json": "https://indexagentica.com/api/entries/redis-mcp-server.json"
    },
    {
      "id": "elastic-agent-builder-mcp",
      "name": "Elastic Agent Builder MCP Server",
      "summary": "Elastic's built-in MCP endpoint in Kibana (Elastic 9.2+ and Serverless) exposing Agent Builder tools, such as ES|QL queries, to external MCP hosts.",
      "url": "https://indexagentica.com/entries/elastic-agent-builder-mcp/",
      "json": "https://indexagentica.com/api/entries/elastic-agent-builder-mcp.json"
    },
    {
      "id": "pinecone-mcp-server",
      "name": "Pinecone Developer MCP Server",
      "summary": "Pinecone's MCP server for coding assistants: search Pinecone docs, configure and manage indexes, upsert data and query indexes from Cursor, Claude and others.",
      "url": "https://indexagentica.com/entries/pinecone-mcp-server/",
      "json": "https://indexagentica.com/api/entries/pinecone-mcp-server.json"
    },
    {
      "id": "neon-mcp-server",
      "name": "Neon MCP Server",
      "summary": "Lets AI assistants manage Neon serverless Postgres projects and databases through the Neon Management API.",
      "url": "https://indexagentica.com/entries/neon-mcp-server/",
      "json": "https://indexagentica.com/api/entries/neon-mcp-server.json"
    },
    {
      "id": "supabase-mcp",
      "name": "Supabase MCP Server",
      "summary": "Connects AI assistants to your Supabase projects over MCP (hosted with OAuth 2.1, or locally via the Supabase CLI).",
      "url": "https://indexagentica.com/entries/supabase-mcp/",
      "json": "https://indexagentica.com/api/entries/supabase-mcp.json"
    },
    {
      "id": "docling",
      "name": "Docling",
      "summary": "Open-source document parser that converts PDF, Office, HTML, audio, images and more into Markdown, JSON or DocTags for gen-AI pipelines; includes an MCP server.",
      "url": "https://indexagentica.com/entries/docling/",
      "json": "https://indexagentica.com/api/entries/docling.json"
    }
  ],
  "related": [
    {
      "type": "comparison",
      "id": "database-mcp-servers",
      "title": "Database MCP servers compared",
      "url": "https://indexagentica.com/compare/database-mcp-servers/",
      "json": "https://indexagentica.com/api/longform/compare/database-mcp-servers.json"
    },
    {
      "type": "guide",
      "id": "run-untrusted-code-in-a-sandbox",
      "title": "Run agent-generated code safely in a sandbox",
      "url": "https://indexagentica.com/guides/run-untrusted-code-in-a-sandbox/",
      "json": "https://indexagentica.com/api/longform/guides/run-untrusted-code-in-a-sandbox.json"
    },
    {
      "type": "comparison",
      "id": "code-sandboxes",
      "title": "Code sandboxes for AI agents",
      "url": "https://indexagentica.com/compare/code-sandboxes/",
      "json": "https://indexagentica.com/api/longform/compare/code-sandboxes.json"
    },
    {
      "type": "guide",
      "id": "convert-documents-to-markdown-for-agents",
      "title": "Convert documents to Markdown for agents with MarkItDown and Docling",
      "url": "https://indexagentica.com/guides/convert-documents-to-markdown-for-agents/",
      "json": "https://indexagentica.com/api/longform/guides/convert-documents-to-markdown-for-agents.json"
    },
    {
      "type": "guide",
      "id": "evaluate-an-ai-agent",
      "title": "Evaluate an AI agent with open-source eval and observability tools",
      "url": "https://indexagentica.com/guides/evaluate-an-ai-agent/",
      "json": "https://indexagentica.com/api/longform/guides/evaluate-an-ai-agent.json"
    },
    {
      "type": "comparison",
      "id": "agent-observability-platforms",
      "title": "Observability and eval platforms for AI agents",
      "url": "https://indexagentica.com/compare/agent-observability-platforms/",
      "json": "https://indexagentica.com/api/longform/compare/agent-observability-platforms.json"
    },
    {
      "type": "guide",
      "id": "add-mcp-servers-to-claude-code",
      "title": "Add MCP servers to Claude Code",
      "url": "https://indexagentica.com/guides/add-mcp-servers-to-claude-code/",
      "json": "https://indexagentica.com/api/longform/guides/add-mcp-servers-to-claude-code.json"
    }
  ],
  "sources": [
    {
      "title": "Claude Agent SDK overview",
      "url": "https://code.claude.com/docs/en/agent-sdk/overview",
      "accessed": "2026-10-19"
    },
    {
      "title": "MotherDuck MCP Server docs",
      "url": "https://motherduck.com/docs/sql-reference/mcp/",
      "accessed": "2026-10-19"
    },
    {
      "title": "DuckDB / MotherDuck local MCP server README",
      "url": "https://github.com/motherduckdb/mcp-server-motherduck",
      "accessed": "2026-10-19"
    },
    {
      "title": "ClickHouse MCP Server README",
      "url": "https://github.com/ClickHouse/mcp-clickhouse",
      "accessed": "2026-10-19"
    },
    {
      "title": "Postgres MCP Pro README",
      "url": "https://github.com/crystaldba/postgres-mcp",
      "accessed": "2026-10-19"
    },
    {
      "title": "MCP Toolbox for Databases README",
      "url": "https://github.com/googleapis/mcp-toolbox",
      "accessed": "2026-10-19"
    },
    {
      "title": "E2B docs, Internet access",
      "url": "https://docs.e2b.dev/network/internet-access",
      "accessed": "2026-10-19"
    },
    {
      "title": "MarkItDown README",
      "url": "https://github.com/microsoft/markitdown",
      "accessed": "2026-10-19"
    },
    {
      "title": "Evidently README",
      "url": "https://github.com/evidentlyai/evidently",
      "accessed": "2026-10-19"
    },
    {
      "title": "Langfuse README",
      "url": "https://github.com/langfuse/langfuse",
      "accessed": "2026-10-19"
    }
  ],
  "front_matter": {
    "id": "data-analysis-agent",
    "type": "stack",
    "title": "Data analysis agent stack",
    "summary": "An agent that answers questions from your data: it queries DuckDB files, a ClickHouse warehouse or Postgres through read-only MCP servers, runs heavier analysis in a sandbox, reads spreadsheets and PDFs, and is tested and traced so you can trust the numbers.",
    "description": "A component list for an analytics or BI agent, with the reason each piece is there and the safety settings that matter when you connect an agent to real data: read-only defaults, least-privilege database users, write and destructive-statement opt-ins, sandbox network controls, and evaluation in CI. Built around the DuckDB/MotherDuck, ClickHouse and Postgres MCP servers added to the directory on 2026-10-18 and 2026-10-19.",
    "author": "Agentica Author",
    "use_case": "Answer business and research questions from tabular data (local files, a cloud warehouse or an operational Postgres) with SQL and Python, show the queries behind every number, and never change the data unless a human allows it.",
    "components": [
      {
        "role": "Agent harness",
        "entry": "claude-agent-sdk",
        "why": "Claude Code's agent loop as a Python or TypeScript library, with MCP connections, subagents and permission controls over which tools run automatically and which need approval."
      },
      {
        "role": "Local files and lake data",
        "entry": "motherduck-mcp-server",
        "why": "The open-source local server opens DuckDB files read-only by default, as well as in-memory databases, S3-hosted DuckDB and MotherDuck. The managed remote server at api.motherduck.com/mcp adds OAuth and MotherDuck's Dives, Flights and Guides."
      },
      {
        "role": "Warehouse",
        "entry": "clickhouse-mcp-server",
        "why": "ClickHouse's official server runs queries read-only by default. Writes need CLICKHOUSE_ALLOW_WRITE_ACCESS=true and DROP-style statements need a second flag, and it takes typed query parameters so values are kept apart from SQL."
      },
      {
        "role": "Operational Postgres",
        "entry": "postgres-mcp-pro",
        "why": "Restricted mode limits the server to read-only transactions and caps execution time, and EXPLAIN and index-tuning tools help the agent understand why a query is slow before it runs it."
      },
      {
        "role": "Many databases, fixed queries",
        "entry": "mcp-toolbox-databases",
        "why": "When the agent should only run vetted queries, Toolbox lets you define parameterized SQL tools across many engines instead of handing over raw SQL."
      },
      {
        "role": "Analysis sandbox",
        "entry": "e2b",
        "why": "Runs the agent's pandas, plotting or modeling code in an isolated cloud sandbox instead of on your machine. Internet access is on by default and can be turned off or limited with allow and deny lists."
      },
      {
        "role": "Spreadsheets and documents",
        "entry": "markitdown",
        "why": "Converts Excel, PDF, Word and other files to Markdown so the agent can read tables and reports that are not in a database. It reads with the privileges of its process, so give it only the files it needs."
      },
      {
        "role": "Answer testing",
        "entry": "evidently",
        "why": "Open-source evals with LLM judges and text checks. Turn a Report into a Test Suite with pass/fail conditions and run it in CI against a set of questions with known answers."
      },
      {
        "role": "Tracing",
        "entry": "langfuse",
        "why": "Records every model call, tool call and SQL statement, so a reviewer can see which query produced which number, and so real questions can become test cases."
      }
    ],
    "tags": [
      "data-analysis",
      "sql",
      "analytics",
      "mcp",
      "duckdb",
      "clickhouse",
      "postgres",
      "read-only"
    ],
    "entries": [
      "claude-agent-sdk",
      "motherduck-mcp-server",
      "clickhouse-mcp-server",
      "postgres-mcp-pro",
      "mcp-toolbox-databases",
      "e2b",
      "markitdown",
      "evidently",
      "langfuse",
      "redis-mcp-server",
      "elastic-agent-builder-mcp",
      "pinecone-mcp-server",
      "neon-mcp-server",
      "supabase-mcp",
      "docling"
    ],
    "related": [
      "database-mcp-servers",
      "run-untrusted-code-in-a-sandbox",
      "code-sandboxes",
      "convert-documents-to-markdown-for-agents",
      "evaluate-an-ai-agent",
      "agent-observability-platforms",
      "add-mcp-servers-to-claude-code"
    ],
    "sources": [
      {
        "title": "Claude Agent SDK overview",
        "url": "https://code.claude.com/docs/en/agent-sdk/overview",
        "accessed": "2026-10-19"
      },
      {
        "title": "MotherDuck MCP Server docs",
        "url": "https://motherduck.com/docs/sql-reference/mcp/",
        "accessed": "2026-10-19"
      },
      {
        "title": "DuckDB / MotherDuck local MCP server README",
        "url": "https://github.com/motherduckdb/mcp-server-motherduck",
        "accessed": "2026-10-19"
      },
      {
        "title": "ClickHouse MCP Server README",
        "url": "https://github.com/ClickHouse/mcp-clickhouse",
        "accessed": "2026-10-19"
      },
      {
        "title": "Postgres MCP Pro README",
        "url": "https://github.com/crystaldba/postgres-mcp",
        "accessed": "2026-10-19"
      },
      {
        "title": "MCP Toolbox for Databases README",
        "url": "https://github.com/googleapis/mcp-toolbox",
        "accessed": "2026-10-19"
      },
      {
        "title": "E2B docs, Internet access",
        "url": "https://docs.e2b.dev/network/internet-access",
        "accessed": "2026-10-19"
      },
      {
        "title": "MarkItDown README",
        "url": "https://github.com/microsoft/markitdown",
        "accessed": "2026-10-19"
      },
      {
        "title": "Evidently README",
        "url": "https://github.com/evidentlyai/evidently",
        "accessed": "2026-10-19"
      },
      {
        "title": "Langfuse README",
        "url": "https://github.com/langfuse/langfuse",
        "accessed": "2026-10-19"
      }
    ],
    "last_verified": "2026-10-19",
    "published": "2026-10-19"
  },
  "markdown": "\n## How the pieces fit\n\nA data analysis agent works in a loop: understand the question, find the right tables, write a query, check the result, maybe compute more in Python, then explain the answer with the query behind it. The stack maps one component to each step and keeps the agent read-only unless a human allows more.\n\n1. **Discover the schema first.** All three database servers have tools for listing databases and tables or reading schema. ClickHouse's `list_tables` is paginated and can leave out column details to keep responses small. ClickHouse also suggests reading an `AGENTS` schema database first if you keep one. MotherDuck's remote server can serve **Guides**: Markdown documents with your metric definitions and join conventions, so the agent stops guessing what \"active user\" means.\n2. **Query where the data lives.** Use [DuckDB/MotherDuck](https://indexagentica.com/entries/motherduck-mcp-server/) for local files, Parquet on S3 and MotherDuck, [ClickHouse](https://indexagentica.com/entries/clickhouse-mcp-server/) for the warehouse and [Postgres MCP Pro](https://indexagentica.com/entries/postgres-mcp-pro/) for the application database. Search indexes and caches have their own servers too: [Elastic Agent Builder](https://indexagentica.com/entries/elastic-agent-builder-mcp/) for ES|QL and [Redis](https://indexagentica.com/entries/redis-mcp-server/).\n3. **Move big results out of the context.** MotherDuck's docs note that every tool result passes through the model's context. Ask for aggregates, not raw rows. When the agent needs a large extract for modeling, have it write the data to a file and process it in the [E2B](https://indexagentica.com/entries/e2b/) sandbox with pandas, then return only the summary and the chart.\n4. **Read what isn't in a database.** Convert spreadsheets and PDF reports with [MarkItDown](https://indexagentica.com/entries/markitdown/), or with [Docling](https://indexagentica.com/entries/docling/) for complex layouts. The [document conversion guide](https://indexagentica.com/guides/convert-documents-to-markdown-for-agents/) compares the options.\n5. **Show the work.** Require the final answer to include the SQL it ran. [Langfuse](https://indexagentica.com/entries/langfuse/) keeps the full trace, so anyone can re-run the query.\n\nThe harness here is the [Claude Agent SDK](https://indexagentica.com/entries/claude-agent-sdk/). Any MCP-capable harness works; see [adding MCP servers to Claude Code](https://indexagentica.com/guides/add-mcp-servers-to-claude-code/) for one client's setup.\n\n## Keep it read-only by default\n\n- **Use the server defaults.** The local DuckDB server opens a file read-only unless you pass `--read-write`. ClickHouse runs read-only unless `CLICKHOUSE_ALLOW_WRITE_ACCESS=true`, and `DROP`-style statements need a further opt-in even then. Postgres MCP Pro's `--access-mode=restricted` allows only read-only transactions and limits execution time.\n- **Give the server its own database user.** ClickHouse's README is explicit that its write checks are \"a best-effort guard against accidents\" and that the real security boundary is the ClickHouse user's grants. Its read-only mode is enforced server-side with `readonly=1`. Apply the same rule everywhere: a dedicated user with `SELECT` on the tables the agent needs. The [database MCP servers comparison](https://indexagentica.com/compare/database-mcp-servers/) explains what each server's read-only flag really enforces.\n- **Pass values as parameters.** ClickHouse's `run_query` accepts a `params` object for `{name:Type}` placeholders, so user-supplied values never get pasted into SQL text. If the agent should only ever run known queries, define them as parameterized tools in [MCP Toolbox](https://indexagentica.com/entries/mcp-toolbox-databases/) instead of exposing raw SQL.\n- **Lock down the sandbox.** E2B sandboxes have internet access by default. Turn it off, or allow only the hosts you need, once the data is loaded, so analysis code cannot send your data anywhere. See [running untrusted code in a sandbox](https://indexagentica.com/guides/run-untrusted-code-in-a-sandbox/).\n\n## Test the answers, not just the queries\n\nA query can run without errors and still answer the wrong question. Keep a set of questions with known answers, such as last quarter's revenue or this month's sign-ups, and run the agent against them on every prompt or model change. [Evidently](https://indexagentica.com/entries/evidently/) turns these checks into a Test Suite with pass/fail conditions for CI. Its LLM-judge evals can also grade the written explanation, not just the final number. [Evaluate an AI agent](https://indexagentica.com/guides/evaluate-an-ai-agent/) covers building that dataset from real traces.\n\n## Variations\n\n- **Postgres on Neon or Supabase:** use their hosted servers with read-only mode and one-project scoping ([Neon](https://indexagentica.com/entries/neon-mcp-server/), [Supabase](https://indexagentica.com/entries/supabase-mcp/)).\n- **Semantic search over documents:** add a vector store, for example through the [Pinecone MCP server](https://indexagentica.com/entries/pinecone-mcp-server/). See the [vector databases comparison](https://indexagentica.com/compare/vector-databases-for-agents/).\n",
  "raw": "---\nid: data-analysis-agent\ntype: stack\ntitle: Data analysis agent stack\nsummary: \"An agent that answers questions from your data: it queries DuckDB files, a ClickHouse warehouse or Postgres through read-only MCP servers, runs heavier analysis in a sandbox, reads spreadsheets and PDFs, and is tested and traced so you can trust the numbers.\"\ndescription: \"A component list for an analytics or BI agent, with the reason each piece is there and the safety settings that matter when you connect an agent to real data: read-only defaults, least-privilege database users, write and destructive-statement opt-ins, sandbox network controls, and evaluation in CI. Built around the DuckDB/MotherDuck, ClickHouse and Postgres MCP servers added to the directory on 2026-10-18 and 2026-10-19.\"\nauthor: Agentica Author\nuse_case: \"Answer business and research questions from tabular data (local files, a cloud warehouse or an operational Postgres) with SQL and Python, show the queries behind every number, and never change the data unless a human allows it.\"\ncomponents:\n  - role: Agent harness\n    entry: claude-agent-sdk\n    why: \"Claude Code's agent loop as a Python or TypeScript library, with MCP connections, subagents and permission controls over which tools run automatically and which need approval.\"\n  - role: Local files and lake data\n    entry: motherduck-mcp-server\n    why: \"The open-source local server opens DuckDB files read-only by default, as well as in-memory databases, S3-hosted DuckDB and MotherDuck. The managed remote server at api.motherduck.com/mcp adds OAuth and MotherDuck's Dives, Flights and Guides.\"\n  - role: Warehouse\n    entry: clickhouse-mcp-server\n    why: \"ClickHouse's official server runs queries read-only by default. Writes need CLICKHOUSE_ALLOW_WRITE_ACCESS=true and DROP-style statements need a second flag, and it takes typed query parameters so values are kept apart from SQL.\"\n  - role: Operational Postgres\n    entry: postgres-mcp-pro\n    why: \"Restricted mode limits the server to read-only transactions and caps execution time, and EXPLAIN and index-tuning tools help the agent understand why a query is slow before it runs it.\"\n  - role: Many databases, fixed queries\n    entry: mcp-toolbox-databases\n    why: \"When the agent should only run vetted queries, Toolbox lets you define parameterized SQL tools across many engines instead of handing over raw SQL.\"\n  - role: Analysis sandbox\n    entry: e2b\n    why: \"Runs the agent's pandas, plotting or modeling code in an isolated cloud sandbox instead of on your machine. Internet access is on by default and can be turned off or limited with allow and deny lists.\"\n  - role: Spreadsheets and documents\n    entry: markitdown\n    why: \"Converts Excel, PDF, Word and other files to Markdown so the agent can read tables and reports that are not in a database. It reads with the privileges of its process, so give it only the files it needs.\"\n  - role: Answer testing\n    entry: evidently\n    why: \"Open-source evals with LLM judges and text checks. Turn a Report into a Test Suite with pass/fail conditions and run it in CI against a set of questions with known answers.\"\n  - role: Tracing\n    entry: langfuse\n    why: \"Records every model call, tool call and SQL statement, so a reviewer can see which query produced which number, and so real questions can become test cases.\"\ntags: [data-analysis, sql, analytics, mcp, duckdb, clickhouse, postgres, read-only]\nentries: [claude-agent-sdk, motherduck-mcp-server, clickhouse-mcp-server, postgres-mcp-pro, mcp-toolbox-databases, e2b, markitdown, evidently, langfuse, redis-mcp-server, elastic-agent-builder-mcp, pinecone-mcp-server, neon-mcp-server, supabase-mcp, docling]\nrelated: [database-mcp-servers, run-untrusted-code-in-a-sandbox, code-sandboxes, convert-documents-to-markdown-for-agents, evaluate-an-ai-agent, agent-observability-platforms, add-mcp-servers-to-claude-code]\nsources:\n  - {title: Claude Agent SDK overview, url: \"https://code.claude.com/docs/en/agent-sdk/overview\", accessed: 2026-10-19}\n  - {title: MotherDuck MCP Server docs, url: \"https://motherduck.com/docs/sql-reference/mcp/\", accessed: 2026-10-19}\n  - {title: DuckDB / MotherDuck local MCP server README, url: \"https://github.com/motherduckdb/mcp-server-motherduck\", accessed: 2026-10-19}\n  - {title: ClickHouse MCP Server README, url: \"https://github.com/ClickHouse/mcp-clickhouse\", accessed: 2026-10-19}\n  - {title: Postgres MCP Pro README, url: \"https://github.com/crystaldba/postgres-mcp\", accessed: 2026-10-19}\n  - {title: MCP Toolbox for Databases README, url: \"https://github.com/googleapis/mcp-toolbox\", accessed: 2026-10-19}\n  - {title: \"E2B docs, Internet access\", url: \"https://docs.e2b.dev/network/internet-access\", accessed: 2026-10-19}\n  - {title: MarkItDown README, url: \"https://github.com/microsoft/markitdown\", accessed: 2026-10-19}\n  - {title: Evidently README, url: \"https://github.com/evidentlyai/evidently\", accessed: 2026-10-19}\n  - {title: Langfuse README, url: \"https://github.com/langfuse/langfuse\", accessed: 2026-10-19}\nlast_verified: 2026-10-19\npublished: 2026-10-19\n---\n\n## How the pieces fit\n\nA data analysis agent works in a loop: understand the question, find the right tables, write a query, check the result, maybe compute more in Python, then explain the answer with the query behind it. The stack maps one component to each step and keeps the agent read-only unless a human allows more.\n\n1. **Discover the schema first.** All three database servers have tools for listing databases and tables or reading schema. ClickHouse's `list_tables` is paginated and can leave out column details to keep responses small. ClickHouse also suggests reading an `AGENTS` schema database first if you keep one. MotherDuck's remote server can serve **Guides**: Markdown documents with your metric definitions and join conventions, so the agent stops guessing what \"active user\" means.\n2. **Query where the data lives.** Use [DuckDB/MotherDuck](https://indexagentica.com/entries/motherduck-mcp-server/) for local files, Parquet on S3 and MotherDuck, [ClickHouse](https://indexagentica.com/entries/clickhouse-mcp-server/) for the warehouse and [Postgres MCP Pro](https://indexagentica.com/entries/postgres-mcp-pro/) for the application database. Search indexes and caches have their own servers too: [Elastic Agent Builder](https://indexagentica.com/entries/elastic-agent-builder-mcp/) for ES|QL and [Redis](https://indexagentica.com/entries/redis-mcp-server/).\n3. **Move big results out of the context.** MotherDuck's docs note that every tool result passes through the model's context. Ask for aggregates, not raw rows. When the agent needs a large extract for modeling, have it write the data to a file and process it in the [E2B](https://indexagentica.com/entries/e2b/) sandbox with pandas, then return only the summary and the chart.\n4. **Read what isn't in a database.** Convert spreadsheets and PDF reports with [MarkItDown](https://indexagentica.com/entries/markitdown/), or with [Docling](https://indexagentica.com/entries/docling/) for complex layouts. The [document conversion guide](https://indexagentica.com/guides/convert-documents-to-markdown-for-agents/) compares the options.\n5. **Show the work.** Require the final answer to include the SQL it ran. [Langfuse](https://indexagentica.com/entries/langfuse/) keeps the full trace, so anyone can re-run the query.\n\nThe harness here is the [Claude Agent SDK](https://indexagentica.com/entries/claude-agent-sdk/). Any MCP-capable harness works; see [adding MCP servers to Claude Code](https://indexagentica.com/guides/add-mcp-servers-to-claude-code/) for one client's setup.\n\n## Keep it read-only by default\n\n- **Use the server defaults.** The local DuckDB server opens a file read-only unless you pass `--read-write`. ClickHouse runs read-only unless `CLICKHOUSE_ALLOW_WRITE_ACCESS=true`, and `DROP`-style statements need a further opt-in even then. Postgres MCP Pro's `--access-mode=restricted` allows only read-only transactions and limits execution time.\n- **Give the server its own database user.** ClickHouse's README is explicit that its write checks are \"a best-effort guard against accidents\" and that the real security boundary is the ClickHouse user's grants. Its read-only mode is enforced server-side with `readonly=1`. Apply the same rule everywhere: a dedicated user with `SELECT` on the tables the agent needs. The [database MCP servers comparison](https://indexagentica.com/compare/database-mcp-servers/) explains what each server's read-only flag really enforces.\n- **Pass values as parameters.** ClickHouse's `run_query` accepts a `params` object for `{name:Type}` placeholders, so user-supplied values never get pasted into SQL text. If the agent should only ever run known queries, define them as parameterized tools in [MCP Toolbox](https://indexagentica.com/entries/mcp-toolbox-databases/) instead of exposing raw SQL.\n- **Lock down the sandbox.** E2B sandboxes have internet access by default. Turn it off, or allow only the hosts you need, once the data is loaded, so analysis code cannot send your data anywhere. See [running untrusted code in a sandbox](https://indexagentica.com/guides/run-untrusted-code-in-a-sandbox/).\n\n## Test the answers, not just the queries\n\nA query can run without errors and still answer the wrong question. Keep a set of questions with known answers, such as last quarter's revenue or this month's sign-ups, and run the agent against them on every prompt or model change. [Evidently](https://indexagentica.com/entries/evidently/) turns these checks into a Test Suite with pass/fail conditions for CI. Its LLM-judge evals can also grade the written explanation, not just the final number. [Evaluate an AI agent](https://indexagentica.com/guides/evaluate-an-ai-agent/) covers building that dataset from real traces.\n\n## Variations\n\n- **Postgres on Neon or Supabase:** use their hosted servers with read-only mode and one-project scoping ([Neon](https://indexagentica.com/entries/neon-mcp-server/), [Supabase](https://indexagentica.com/entries/supabase-mcp/)).\n- **Semantic search over documents:** add a vector store, for example through the [Pinecone MCP server](https://indexagentica.com/entries/pinecone-mcp-server/). See the [vector databases comparison](https://indexagentica.com/compare/vector-databases-for-agents/).\n",
  "html": "<h2>How the pieces fit</h2>\n<p>A data analysis agent works in a loop: understand the question, find the right tables, write a query, check the result, maybe compute more in Python, then explain the answer with the query behind it. The stack maps one component to each step and keeps the agent read-only unless a human allows more.</p>\n<ol><li><strong>Discover the schema first.</strong> All three database servers have tools for listing databases and tables or reading schema. ClickHouse&#39;s <code>list_tables</code> is paginated and can leave out column details to keep responses small. ClickHouse also suggests reading an <code>AGENTS</code> schema database first if you keep one. MotherDuck&#39;s remote server can serve <strong>Guides</strong>: Markdown documents with your metric definitions and join conventions, so the agent stops guessing what &quot;active user&quot; means.</li><li><strong>Query where the data lives.</strong> Use <a href=\"/entries/motherduck-mcp-server/\">DuckDB/MotherDuck</a> for local files, Parquet on S3 and MotherDuck, <a href=\"/entries/clickhouse-mcp-server/\">ClickHouse</a> for the warehouse and <a href=\"/entries/postgres-mcp-pro/\">Postgres MCP Pro</a> for the application database. Search indexes and caches have their own servers too: <a href=\"/entries/elastic-agent-builder-mcp/\">Elastic Agent Builder</a> for ES|QL and <a href=\"/entries/redis-mcp-server/\">Redis</a>.</li><li><strong>Move big results out of the context.</strong> MotherDuck&#39;s docs note that every tool result passes through the model&#39;s context. Ask for aggregates, not raw rows. When the agent needs a large extract for modeling, have it write the data to a file and process it in the <a href=\"/entries/e2b/\">E2B</a> sandbox with pandas, then return only the summary and the chart.</li><li><strong>Read what isn&#39;t in a database.</strong> Convert spreadsheets and PDF reports with <a href=\"/entries/markitdown/\">MarkItDown</a>, or with <a href=\"/entries/docling/\">Docling</a> for complex layouts. The <a href=\"/guides/convert-documents-to-markdown-for-agents/\">document conversion guide</a> compares the options.</li><li><strong>Show the work.</strong> Require the final answer to include the SQL it ran. <a href=\"/entries/langfuse/\">Langfuse</a> keeps the full trace, so anyone can re-run the query.</li></ol>\n<p>The harness here is the <a href=\"/entries/claude-agent-sdk/\">Claude Agent SDK</a>. Any MCP-capable harness works; see <a href=\"/guides/add-mcp-servers-to-claude-code/\">adding MCP servers to Claude Code</a> for one client&#39;s setup.</p>\n<h2>Keep it read-only by default</h2>\n<ul><li><strong>Use the server defaults.</strong> The local DuckDB server opens a file read-only unless you pass <code>--read-write</code>. ClickHouse runs read-only unless <code>CLICKHOUSE_ALLOW_WRITE_ACCESS=true</code>, and <code>DROP</code>-style statements need a further opt-in even then. Postgres MCP Pro&#39;s <code>--access-mode=restricted</code> allows only read-only transactions and limits execution time.</li><li><strong>Give the server its own database user.</strong> ClickHouse&#39;s README is explicit that its write checks are &quot;a best-effort guard against accidents&quot; and that the real security boundary is the ClickHouse user&#39;s grants. Its read-only mode is enforced server-side with <code>readonly=1</code>. Apply the same rule everywhere: a dedicated user with <code>SELECT</code> on the tables the agent needs. The <a href=\"/compare/database-mcp-servers/\">database MCP servers comparison</a> explains what each server&#39;s read-only flag really enforces.</li><li><strong>Pass values as parameters.</strong> ClickHouse&#39;s <code>run_query</code> accepts a <code>params</code> object for <code>{name:Type}</code> placeholders, so user-supplied values never get pasted into SQL text. If the agent should only ever run known queries, define them as parameterized tools in <a href=\"/entries/mcp-toolbox-databases/\">MCP Toolbox</a> instead of exposing raw SQL.</li><li><strong>Lock down the sandbox.</strong> E2B sandboxes have internet access by default. Turn it off, or allow only the hosts you need, once the data is loaded, so analysis code cannot send your data anywhere. See <a href=\"/guides/run-untrusted-code-in-a-sandbox/\">running untrusted code in a sandbox</a>.</li></ul>\n<h2>Test the answers, not just the queries</h2>\n<p>A query can run without errors and still answer the wrong question. Keep a set of questions with known answers, such as last quarter&#39;s revenue or this month&#39;s sign-ups, and run the agent against them on every prompt or model change. <a href=\"/entries/evidently/\">Evidently</a> turns these checks into a Test Suite with pass/fail conditions for CI. Its LLM-judge evals can also grade the written explanation, not just the final number. <a href=\"/guides/evaluate-an-ai-agent/\">Evaluate an AI agent</a> covers building that dataset from real traces.</p>\n<h2>Variations</h2>\n<ul><li><strong>Postgres on Neon or Supabase:</strong> use their hosted servers with read-only mode and one-project scoping (<a href=\"/entries/neon-mcp-server/\">Neon</a>, <a href=\"/entries/supabase-mcp/\">Supabase</a>).</li><li><strong>Semantic search over documents:</strong> add a vector store, for example through the <a href=\"/entries/pinecone-mcp-server/\">Pinecone MCP server</a>. See the <a href=\"/compare/vector-databases-for-agents/\">vector databases comparison</a>.</li></ul>"
}
