How to Build an MCP Server for Your Data Warehouse (Tutorial)
Step-by-step guide to building MCP servers for Snowflake and BigQuery
Building an MCP server for your data warehouse means wrapping warehouse operations — query, schema introspection, cost estimation, governance — as Model Context Protocol tools that any AI agent can call. The tutorial pattern is: install an MCP SDK, define tools, wire credentials, expose the server, and connect from Claude or Cursor.
If you want to build an MCP server for your data warehouse, you are making the right architectural bet. The Model Context Protocol is rapidly becoming the standard interface between AI agents and data infrastructure, and a custom MCP server gives your agents native, bidirectional access to Snowflake, BigQuery, or any warehouse — complete with schema awareness, query execution, and context sharing. This tutorial walks you through building a production-grade MCP server in TypeScript that connects to Snowflake or BigQuery, step by step.
By the end of this guide, you will have a working MCP server that exposes your warehouse schema, executes parameterized queries, returns structured results, and integrates with any MCP-compatible client — including Data Workers, Claude Desktop, Cursor, and Windsurf. The full code is available under Apache 2.0, and the architecture patterns apply to any warehouse or database backend.
What Is an MCP Server and Why Build One for Your Warehouse?
The Model Context Protocol (MCP), introduced by Anthropic in late 2024, is an open standard that defines how AI agents discover and interact with external tools and data sources. An MCP server is a process that exposes tools (actions an agent can invoke), resources (data the agent can read), and prompts (reusable templates) over a standardized transport — typically stdio for local servers or Server-Sent Events (SSE) for remote deployments.
For data warehouses, an MCP server replaces brittle custom integrations with a standardized interface. Instead of writing bespoke API wrappers for each agent framework, you build one MCP server and every MCP client can use it. Snowflake, BigQuery, Databricks, and ClickHouse have all released official or community MCP servers, but building your own gives you full control over security boundaries, query governance, and the specific tools your agents need.
Architecture Overview: How an MCP Data Warehouse Server Works
A data warehouse MCP server has four logical layers. Understanding this architecture before writing code will save you hours of refactoring.
- •Transport layer — handles the MCP protocol communication. For local development, use stdio transport. For production multi-tenant deployments, use the SSE transport with authentication middleware.
- •Tool registry — defines the tools your server exposes:
list_schemas,list_tables,describe_table,run_query,get_query_history, and any custom tools specific to your organization. - •Warehouse client — manages the connection pool to Snowflake or BigQuery, handles authentication, enforces query timeouts, and manages cost controls like byte-scanned limits.
- •Security layer — implements OAuth 2.1 token validation, row-level security mapping, query allowlisting, and audit logging. This layer is critical for production deployments.
The data flow is straightforward: an MCP client (like Data Workers or Claude Desktop) sends a tools/call request. The transport layer deserializes it, the tool registry routes it to the appropriate handler, the handler builds and executes a query via the warehouse client, and the result flows back as a structured MCP response. Every step is logged for audit compliance.
Step 1: Initialize the Project and Install Dependencies
Start by creating a new TypeScript project. You need the official MCP SDK, your warehouse driver, and a few utilities.
Run the following commands to scaffold the project:
mkdir mcp-warehouse-server && cd mcp-warehouse-server && npm init -y
Install the core dependencies:
npm install @modelcontextprotocol/sdk snowflake-sdk zod dotenv
For BigQuery, replace snowflake-sdk with @google-cloud/bigquery. Install dev dependencies:
npm install -D typescript @types/node tsx
Create a tsconfig.json with "module": "nodenext" and "target": "ES2022". The MCP SDK requires ESM-compatible module resolution.
Step 2: Define Your MCP Tools with Zod Schemas
Every MCP tool requires a name, description, and a JSON Schema for its input parameters. The @modelcontextprotocol/sdk uses Zod for schema definitions, which gives you runtime validation for free.
Define your core tools in src/tools.ts:
The list_schemas tool takes no parameters and returns all accessible schemas. Define it as: server.tool("list_schemas", "List all database schemas accessible to the current user", {}, async () => { ... }). The empty object means no input parameters.
The describe_table tool takes a schema and table name: server.tool("describe_table", "Get column names, types, and descriptions for a table", { schema: z.string(), table: z.string() }, async ({ schema, table }) => { ... }). Zod validates that both parameters are strings before your handler executes.
The run_query tool is the most critical. Define it with guardrails: server.tool("run_query", "Execute a read-only SQL query", { sql: z.string(), max_rows: z.number().default(100) }, async ({ sql, max_rows }) => { ... }). Always enforce a max_rows default to prevent agents from pulling entire tables.
Step 3: Implement the Snowflake Connection and Query Execution
Create src/warehouse.ts to encapsulate the warehouse connection. For Snowflake, use key-pair authentication in production — never embed passwords in MCP servers.
The connection setup uses snowflake.createConnection({ account: process.env.SNOWFLAKE_ACCOUNT, username: process.env.SNOWFLAKE_USER, privateKey: process.env.SNOWFLAKE_PRIVATE_KEY, warehouse: process.env.SNOWFLAKE_WAREHOUSE, role: process.env.SNOWFLAKE_ROLE }). The role parameter is critical — it maps to Snowflake RBAC, ensuring the MCP server only accesses data its role permits.
Wrap query execution in a function that enforces timeouts and read-only access: parse the SQL to reject any DDL or DML statements (INSERT, UPDATE, DELETE, DROP, CREATE, ALTER). This is defense-in-depth — your Snowflake role should also be read-only, but application-level validation catches mistakes before they reach the warehouse.
For BigQuery, the equivalent setup uses new BigQuery({ projectId: process.env.GCP_PROJECT, keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS }). BigQuery's cost model requires an additional guardrail: set maximumBytesBilled on every query job to prevent runaway scans. A sensible default is 10 GB (10 * 1024 * 1024 * 1024).
Step 4: Wire Up the MCP Server Entry Point
Create src/index.ts as the server entry point. Import McpServer from @modelcontextprotocol/sdk/server/mcp.js and StdioServerTransport from @modelcontextprotocol/sdk/server/stdio.js. Instantiate the server with a name and version: const server = new McpServer({ name: "warehouse-mcp", version: "1.0.0" }).
Register all tools from Step 2, then connect the transport: const transport = new StdioServerTransport(); await server.connect(transport);. That is it — your server is now MCP-compliant and can be used by any MCP client.
Add a bin field to package.json pointing to your compiled entry point, and ensure your package.json includes "type": "module". Test locally by running npx tsx src/index.ts and connecting via the MCP Inspector: npx @modelcontextprotocol/inspector npx tsx src/index.ts.
Step 5: Add Resources for Schema Context
MCP resources let agents read contextual data without invoking a tool. For a warehouse server, expose your schema metadata as a resource so agents can browse schemas before writing queries.
Use server.resource("warehouse-schema", "warehouse://schemas", async (uri) => { ... }) to expose a resource that returns a JSON document of all schemas, tables, and column types. Agents can read this resource at connection time to build an internal model of your warehouse before generating any queries.
You can also expose dynamic resources using URI templates: server.resource("table-details", new ResourceTemplate("warehouse://tables/{schema}/{table}", { list: undefined }), async (uri, { schema, table }) => { ... }). This gives agents fine-grained access to individual table metadata without pulling the entire schema graph.
Step 6: Testing Your MCP Server End-to-End
Testing MCP servers requires validating both the protocol compliance and the business logic. Use the MCP Inspector (npx @modelcontextprotocol/inspector) for interactive testing — it lets you list tools, invoke them, and inspect the JSON-RPC messages.
For automated testing, the MCP SDK provides a Client class you can use in test frameworks like Vitest or Jest. Create an in-process transport pair using const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(), connect both client and server, and write assertions against tool call results. Test edge cases: SQL injection attempts, queries exceeding max_rows, invalid schema names, and connection timeouts.
For integration testing against a real warehouse, use a dedicated test schema with known data. Assert that list_schemas returns expected schemas, describe_table returns correct column types, and run_query returns accurate row counts. Run these tests in CI with warehouse credentials stored in environment variables or a secrets manager.
Production Deployment Considerations
Moving from a local stdio MCP server to a production deployment requires addressing authentication, scalability, and observability.
- •Authentication — switch from stdio to the Streamable HTTP transport and add OAuth 2.1 middleware. The MCP specification defines an authorization flow where clients obtain tokens before connecting. Validate tokens on every request.
- •Connection pooling — Snowflake connections are expensive to create. Use a connection pool (e.g.,
generic-pool) with a min/max size tuned to your concurrency requirements. For BigQuery, the client library handles pooling internally. - •Query audit logging — log every query executed through the MCP server with the authenticated user identity, timestamp, SQL text, rows returned, and bytes scanned. This is non-negotiable for SOC 2 and GDPR compliance.
- •Rate limiting — protect your warehouse from agent-driven query storms. Implement per-user rate limits at the MCP server level, not just at the warehouse level.
- •Cost controls — for BigQuery, enforce
maximumBytesBilledper query. For Snowflake, monitor credit consumption per MCP session and alert when thresholds are exceeded.
How Data Workers Builds on MCP for Data Warehouse Access
Data Workers takes this architecture further by deploying 15 specialized AI agents that communicate through MCP natively. Instead of building and maintaining a single MCP server yourself, Data Workers provides a coordinated swarm where the Schema Agent handles warehouse introspection, the Query Agent generates and validates SQL, and the Governance Agent enforces access policies — all communicating through MCP's bidirectional protocol.
The platform integrates with 85+ data tools out of the box, including Snowflake, BigQuery, Databricks, and PostgreSQL. Teams using Data Workers report saving over $1.3 million annually by eliminating manual data engineering toil. If you want the capabilities described in this tutorial without building and maintaining the infrastructure yourself, book a demo to see the platform in action.
Building an MCP server for your data warehouse is a high-leverage investment. You get a standardized interface that works with every MCP client, strong security primitives from the protocol itself, and the ability to give AI agents governed access to your most valuable data. Start with the stdio transport for development, add authentication for production, and consider Data Workers if you need a fully managed solution with 15 agents coordinating across your entire data stack. Visit the documentation or book a demo to get started.
See Data Workers in action
15 autonomous AI agents working across your entire data stack. MCP-native, open-source, deployed in minutes.
Book a DemoRelated Resources
- Model Context Protocol Specification — external reference
- Why AI Agents Need MCP Servers for Data Engineering — MCP servers give AI agents structured access to your data tools — Snowflake, BigQuery, dbt, Airflow, and more. Here is why MCP is the int…
- MCP Server Examples: 10 Real-World Data Engineering Integrations — 10 real-world MCP server examples for data engineering: dbt navigator, Airflow manager, Snowflake cost optimizer, Kafka inspector, qualit…
- Mcp Server Mongodb Data — Mcp Server Mongodb Data
- Mcp Server Data Dictionary Exposure — Mcp Server Data Dictionary Exposure
- MCP Server for Databases: Connect AI Agents to Postgres, BigQuery, and Snowflake — Connect AI agents to Postgres, BigQuery, and Snowflake via MCP servers. Database-specific patterns, schema exposure, and query execution.
- The Complete Guide to Agentic Data Engineering with MCP — Agentic data engineering replaces manual pipeline management with autonomous AI agents. Here is how to implement it with MCP — without lo…
- MCP Server Analytics: Understanding How Your AI Tools Are Actually Used — Your team uses dozens of MCP tools every day. MCP analytics tracks adoption, measures ROI, identifies unused tools, and provides the usag…
- The 10 Best MCP Servers for Data Engineering Teams in 2026 — With 19,000+ MCP servers available, finding the right ones for data engineering is overwhelming. Here are the 10 that matter most — from…
- MCP Server Security: Authentication, Authorization, and Audit Trails — MCP servers expose powerful capabilities to AI agents. Securing them requires OAuth 2.1 authentication, scoped authorization, least-privi…
- MCP Server for Snowflake: Connect AI Agents to Your Data Warehouse — Snowflake's MCP server exposes Cortex Analyst, Cortex Search, and schema metadata to AI agents. Here's how to set it up and how Data Work…
- MCP Server for BigQuery: Give AI Agents Access to Your Analytics — BigQuery's MCP server gives AI agents access to schemas, query execution, and cost estimation. Here's how to connect it and use Data Work…
- Claude Code + MCP: Connect AI Agents to Your Entire Data Stack — MCP connects Claude Code to Snowflake, BigQuery, dbt, Airflow, Data Workers — full data operations platform.
Explore Topic Clusters
- Data Governance: The Complete Guide — Policies, access controls, PII, and compliance at scale.
- Data Catalog: The Complete Guide — Discovery, metadata, lineage, and the modern catalog stack.
- Data Lineage: The Complete Guide — Column-level lineage, impact analysis, and observability.
- Data Quality: The Complete Guide — Tests, SLAs, anomaly detection, and data reliability engineering.
- AI Data Engineering: The Complete Guide — LLMs, agents, and autonomous workflows across the data stack.
- MCP for Data: The Complete Guide — Model Context Protocol servers, tools, and agent integration.
- Data Mesh & Data Fabric: The Complete Guide — Federated ownership, domain-oriented architecture, and interop.
- Open-Source Data Stack: The Complete Guide — dbt, Airflow, Iceberg, DuckDB, and the modern OSS toolkit.
- AI for Data Infra — The complete category for AI agents built specifically for data engineering, data governance, and data infrastructure work.