This is page 1 of 2. Use http://codebase.md/davidamom/snowflake-mcp?page={x} to view the full context. # Directory Structure ``` ├── __init__.py ├── .env.template ├── .gitignore ├── assets │ ├── communication_flow_sequence_bright.svg │ ├── communication_flow_sequence.svg │ ├── key_components_bright.svg │ └── key_components.svg ├── Dockerfile ├── LICENSE ├── pyproject.toml ├── README.md ├── requirements.txt ├── server.py ├── src │ ├── __init__.py │ └── snowflake_mcp │ ├── __init__.py │ ├── auth │ │ └── __init__.py │ ├── config │ │ └── __init__.py │ ├── connection │ │ └── __init__.py │ ├── server │ │ └── __init__.py │ └── utils │ └── __init__.py └── tests └── __init__.py ``` # Files -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` # Environment variables .env .venv/ # Python cache __pycache__/ *.py[cod] *$py.class # Distribution / packaging dist/ build/ *.egg-info/ # Virtual environments venv/ env/ ENV/ # IDE files .vscode/ .idea/ *.swp *.swo # Logs *.log rsa_key.pub rsa_key.p8 _venv ``` -------------------------------------------------------------------------------- /.env.template: -------------------------------------------------------------------------------- ``` # Snowflake Configuration - Basic Info SNOWFLAKE_USER=your_username # Your Snowflake username SNOWFLAKE_ACCOUNT=your_account # Your Snowflake account SNOWFLAKE_DATABASE=your_database # Your Snowflake database SNOWFLAKE_WAREHOUSE=your_warehouse # Your Snowflake warehouse # Authentication Method - Choose one method # Option 1: Password Authentication SNOWFLAKE_PASSWORD=your_password # Your Snowflake password # Option 2: Key Pair Authentication - Choose A or B: # A) For private key WITHOUT passphrase: # SNOWFLAKE_PRIVATE_KEY_FILE=/path/to/rsa_key.p8 # Leave SNOWFLAKE_PRIVATE_KEY_PASSPHRASE commented out or empty # B) For private key WITH passphrase: # SNOWFLAKE_PRIVATE_KEY_FILE=/path/to/rsa_key.p8 # SNOWFLAKE_PRIVATE_KEY_PASSPHRASE=your_passphrase ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # Snowflake MCP Service A Model Context Protocol (MCP) server that provides access to Snowflake databases for any MCP-compatible client.   This server implements the Model Context Protocol to allow any MCP client to: - Execute SQL queries on Snowflake databases - Automatically handle database connection lifecycle (connect, reconnect on timeout, close) - Handle query results and errors - Perform database operations safely - Connect using either password or key pair authentication ## Architecture Overview ### What is MCP (Model Context Protocol)? MCP is a standard protocol that allows applications to communicate with AI models and external services. It enables AI models to access tools and data sources beyond their training data, expanding their capabilities through a standardized communication interface. Key features include: - Based on stdio communication (standard input/output) - Structured tool definition and discovery - Standardized tool call mechanism - Structured results transmission ### System Components The Snowflake-MCP server consists of several key components: 1. **MCP Server** - Central component that implements the MCP protocol and handles client requests 2. **Snowflake Connection Manager** - Manages database connections, including creation, maintenance, and cleanup 3. **Query Processor** - Executes SQL queries on Snowflake and processes the results 4. **Authentication Manager** - Handles different authentication methods (password or private key)  ### Communication Flow The system works through the following communication flow: 1. An MCP Client (such as Claude or other MCP-compatible application) sends a request to the MCP Server 2. The MCP Server authenticates with Snowflake using credentials from the `.env` file 3. The MCP Server executes SQL queries on Snowflake 4. Snowflake returns results to the MCP Server 5. The MCP Server formats and sends the results back to the MCP Client  This architecture allows for seamless integration between AI applications and Snowflake databases while maintaining security and efficient connection management. ## Installation 1. Clone this repository ```bash git clone https://github.com/davidamom/snowflake-mcp.git ``` 2. Install dependencies ```bash pip install -r requirements.txt ``` ## Configuration ### MCP Client Configuration Example Below is an example configuration for Claude Desktop, but this server works with any MCP-compatible client. Each client may have its own configuration method: ```json { "mcpServers": { "snowflake": { "command": "C:\\Users\\YourUsername\\path\\to\\python.exe", "args": ["C:\\path\\to\\snowflake-mcp\\server.py"] } } } ``` Configuration parameters: - `command`: Full path to your Python interpreter. Please modify this according to your Python installation location. - `args`: Full path to the server script. Please modify this according to where you cloned the repository. Example paths for different operating systems: Windows: ```json { "mcpServers": { "snowflake": { "command": "C:\\Users\\YourUsername\\anaconda3\\python.exe", "args": ["C:\\Path\\To\\snowflake-mcp\\server.py"] } } } ``` MacOS/Linux: ```json { "mcpServers": { "snowflake": { "command": "/usr/bin/python3", "args": ["/path/to/snowflake-mcp/server.py"] } } } ``` ### Snowflake Configuration Create a `.env` file in the project root directory and add the following configuration: ```env # Snowflake Configuration - Basic Info SNOWFLAKE_USER=your_username # Your Snowflake username SNOWFLAKE_ACCOUNT=YourAccount.Region # Example: MyOrg.US-WEST-2 SNOWFLAKE_DATABASE=your_database # Your database SNOWFLAKE_WAREHOUSE=your_warehouse # Your warehouse SNOWFLAKE_ROLE=your_role # Your role # Authentication - Choose one method ``` #### Authentication Options This MCP server supports two authentication methods: 1. **Password Authentication** ```env SNOWFLAKE_PASSWORD=your_password # Your Snowflake password ``` 2. **Key Pair Authentication** ```env SNOWFLAKE_PRIVATE_KEY_FILE=/path/to/rsa_key.p8 # Path to private key file SNOWFLAKE_PRIVATE_KEY_PASSPHRASE=your_passphrase # Optional: passphrase if key is encrypted ``` For key pair authentication, you must first set up key pair authentication with Snowflake: - Generate a key pair and register the public key with Snowflake - Store the private key file securely on your machine - Provide the full path to the private key file in the configuration For instructions on setting up key pair authentication, refer to [Snowflake documentation on key pair authentication](https://docs.snowflake.com/en/user-guide/key-pair-auth). If both authentication methods are configured, the server will prioritize key pair authentication. ## Connection Management The server provides automatic connection management features: - Automatic connection initialization - Creates connection when first query is received - Validates connection parameters - Connection maintenance - Keeps track of connection state - Handles connection timeouts - Automatically reconnects if connection is lost - Connection cleanup - Properly closes connections when server stops - Releases resources appropriately ## Usage ### Standard Usage The server will start automatically when configured with your MCP client. No manual startup is required in normal operation. Once the server is running, your MCP client will be able to execute Snowflake queries. For development testing, you can start the server manually using: ```bash python server.py ``` Note: Manual server startup is not needed for normal use. The MCP client will typically manage server startup and shutdown based on the configuration. ### Docker Usage You can also run the server using Docker. This method is recommended for production environments and ensures consistent execution across different platforms. 1. Build the Docker image: ```bash docker build -t snowflake-mcp . ``` 2. Configure your MCP client to use Docker. Example configuration: ```json { "mcpServers": { "snowflake-docker": { "command": "docker", "args": [ "run", "-i", "snowflake-mcp" ], "env": { "SNOWFLAKE_USER": "your_username", "SNOWFLAKE_ACCOUNT": "your_account", "SNOWFLAKE_DATABASE": "your_database", "SNOWFLAKE_WAREHOUSE": "your_warehouse", "SNOWFLAKE_PASSWORD": "your_password", "SNOWFLAKE_ROLE": "your_role" } } } } ``` Note: The Docker implementation uses stdio for communication, so no ports need to be exposed. If using key pair authentication with Docker, you'll need to mount your private key file: ```bash docker run -i -v /path/to/your/key.p8:/app/rsa_key.p8:ro snowflake-mcp ``` And update your configuration accordingly: ```json { "mcpServers": { "Snowflake-Docker": { "command": "docker", "args": [ "run", "-i", "-v", "/path/to/your/key.p8:/app/rsa_key.p8:ro", //optional "-v", "/path/to/export/dir/:/export/" "snowflake-mcp" ], "env": { "SNOWFLAKE_USER": "your_username", "SNOWFLAKE_ACCOUNT": "your_account", "SNOWFLAKE_DATABASE": "your_database", "SNOWFLAKE_WAREHOUSE": "your_warehouse", "SNOWFLAKE_ROLE": "your_role", "SNOWFLAKE_PRIVATE_KEY_FILE": "path_for_your_private_key", "SNOWFLAKE_PRIVATE_KEY_PASSPHRASE": "your_password_for_private_key" } } } } ``` ## Features - Secure Snowflake database access - Flexible authentication (password or key pair authentication) - Robust error handling and reporting - Automatic connection management - Query execution and result processing - Compatible with any MCP-compliant client ## Technical Details ### Core Components The implementation consists of several key classes and modules: - **server.py** - The main entry point containing the MCP server implementation. - **SnowflakeConnection** - Class that handles all Snowflake database operations, including: - Connection establishment and reconnection - Query execution and transaction management - Connection maintenance and cleanup - **SnowflakeMCPServer** - The main server class that implements the MCP protocol: - Registers available tools with the MCP framework - Handles tool call requests from clients - Manages the lifecycle of connections ### Connection Lifecycle The connection lifecycle is carefully managed to ensure reliability: 1. **Initialization** - Connections are created lazily when the first query is received 2. **Validation** - Connection parameters are validated before attempting to connect 3. **Monitoring** - Connections are regularly tested for validity 4. **Recovery** - Automatic reconnection if the connection is lost or times out 5. **Cleanup** - Proper resource release when the server shuts down ### MCP Tool Interface The server exposes the following tool to MCP clients: - **execute_query** - Executes a SQL query on Snowflake and returns the results - Input: SQL query string - Output: Query results in a structured format - **export_to_csv** - Executes a SQL query on Snowflake and returns the results - Input: SQL query string - Output: Num rows exported. File path of the output file This implementation follows best practices for both MCP protocol implementation and Snowflake database interaction. ## License [](https://opensource.org/licenses/MIT) This project is licensed under the [MIT License](LICENSE). See the [LICENSE](LICENSE) file for details. Copyright (c) 2025 David Amom ``` -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /src/snowflake_mcp/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /src/snowflake_mcp/auth/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /src/snowflake_mcp/config/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /src/snowflake_mcp/connection/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /src/snowflake_mcp/server/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /src/snowflake_mcp/utils/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- ```python ``` -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- ```python """Snowflake MCP Service""" __version__ = "0.1.0" ``` -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- ``` snowflake-connector-python[pandas]>=2.7.0 python-dotenv>=0.19.0 mcp>=1.0.0 cryptography>=36.0.0 ``` -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- ```dockerfile FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . ENV PYTHONUNBUFFERED=1 CMD ["python", "server.py"] ``` -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- ```toml # Python project configuration [project] name = "snowflake-mcp" version = "0.1.0" description = "MCP server for interacting with Snowflake databases" readme = "README.md" requires-python = ">=3.10" # Required Python version dependencies = [ # Project dependencies "mcp>=1.0.0", # MCP SDK "snowflake-connector-python", # Snowflake connector "python-dotenv" # Environment variable management ] # Build system configuration [build-system] requires = ["hatchling"] # Build tool requirement build-backend = "hatchling.build" # Build backend # Build configuration [tool.hatch.build.targets.wheel] packages = ["src/snowflake_mcp"] # Package location # Entry points [project.scripts] snowflake-mcp = "snowflake_mcp.server:main" # Command line entry ``` -------------------------------------------------------------------------------- /assets/key_components_bright.svg: -------------------------------------------------------------------------------- ``` <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="770" height="530" viewBox="0 0 770 530" style="fill:none;stroke:none;fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style class="text-font-style fontImports" data-font-family="Roboto">@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=block');</style><g id="items" style="isolation: isolate"><g id="blend" style="mix-blend-mode: normal"><g id="g-root-0.g-0_fr_13z9kvs1fxylfy-fill" data-item-order="-311030" transform="translate(255, 159)"><g id="0.g-0_fr_13z9kvs1fxylfy-fill" stroke="none" fill="#f5f5f5"><g><path d="M 250 130C 250 196.274 196.274 250 130 250C 63.7258 250 10 196.274 10 130C 10 63.7258 63.7258 10 130 10C 196.274 10 250 63.7258 250 130Z"></path></g></g></g><g id="g-root-4.g-4_fr_zk2jug1fxyj2g-fill" data-item-order="-311026" transform="translate(183, 87)"><g id="4.g-4_fr_zk2jug1fxyj2g-fill" stroke="none" fill="#fffbda"><g><path d="M 94 10C 47.6081 10 10 47.6081 10 94C 10 137.183 42.5856 172.756 84.5093 177.47C 94.1869 130.879 130.879 94.1869 177.47 84.5093C 172.756 42.5856 137.183 10 94 10Z"></path></g></g></g><g id="g-root-3.g-3_fr_v491q01fxyjuq-fill" data-item-order="-311020" transform="translate(183, 303)"><g id="3.g-3_fr_v491q01fxyjuq-fill" stroke="none" fill="#f4ffdc"><g><path d="M 10 93.999097C 10 140.391297 47.6081 177.999297 94 177.999297C 137.183 177.999297 172.756 145.413297 177.47 103.489797C 130.879 93.812197 94.1869 57.119897 84.5093 10.529297C 42.5856 15.243497 10 50.815897 10 93.999097Z"></path></g></g></g><g id="g-root-2.g-2_fr_m8m1h41fxykng-fill" data-item-order="-311014" transform="translate(399, 303)"><g id="2.g-2_fr_m8m1h41fxykng-fill" stroke="none" fill="#e3fff2"><g><path d="M 94.000073 177.999297C 140.392273 177.999297 178.000273 140.391297 178.000273 93.999097C 178.000273 50.815897 145.414273 15.243597 103.490773 10.529297C 93.813173 57.119897 57.120873 93.812197 10.530273 103.489797C 15.244473 145.413297 50.816873 177.999297 94.000073 177.999297Z"></path></g></g></g><g id="g-root-1.g-1_fr_8xs06w1fxyj2m-fill" data-item-order="-311008" transform="translate(399, 87)"><g id="1.g-1_fr_8xs06w1fxyj2m-fill" stroke="none" fill="#e8f9ff"><g><path d="M 178.000212 94C 178.000212 47.6081 140.392212 10 94.000012 10C 50.816812 10 15.244412 42.5856 10.530212 84.5093C 57.120812 94.1869 93.813112 130.879 103.490712 177.47C 145.414212 172.756 178.000212 137.183 178.000212 94Z"></path></g></g></g><g id="g-root-tx_keycompo_1lsf0mw1fxyiv5-fill" data-item-order="0" transform="translate(99, 39)"><g id="tx_keycompo_1lsf0mw1fxyiv5-fill" stroke="none" fill="#484848"><g><text style="font: 20px Roboto, sans-serif; white-space: pre;" font-size="20px" font-family="Roboto, sans-serif"><tspan x="12.67" y="34" dominant-baseline="ideographic">Key Components Enhancing Snowflake-MCP Server Efficiency</tspan></text></g></g></g><g id="g-root-tx_authenti_hznraw1fy8fm7-fill" data-item-order="0" transform="translate(15, 93)"><g id="tx_authenti_hznraw1fy8fm7-fill" stroke="none" fill="#e0cb15"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="19.73" y="34" dominant-baseline="ideographic">Authentication </tspan><tspan x="72.31" y="58" dominant-baseline="ideographic">Manager</tspan></text></g></g></g><g id="g-root-tx_mcpserve_1q6d3i01fy9szx-fill" data-item-order="0" transform="translate(591, 99)"><g id="tx_mcpserve_1q6d3i01fy9szx-fill" stroke="none" fill="#1eabda"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="12" y="34" dominant-baseline="ideographic">MCP Server</tspan></text></g></g></g><g id="g-root-key_91iupk1fy8cul-fill" data-item-order="0" transform="translate(225, 129)"></g><g id="g-root-hier_8z0yd41fxyl8s-fill" data-item-order="0" transform="translate(477, 129)"></g><g id="g-root-tx_centralc_1cvj27s1fy9rf2-fill" data-item-order="0" transform="translate(591, 135)"><g id="tx_centralc_1cvj27s1fy9rf2-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="12" y="28" dominant-baseline="ideographic">Central component </tspan><tspan x="12" y="46" dominant-baseline="ideographic">managing protocol </tspan><tspan x="12" y="64" dominant-baseline="ideographic">and client </tspan><tspan x="12" y="82" dominant-baseline="ideographic">interactions</tspan></text></g></g></g><g id="g-root-tx_managesa_907w81fy8etk-fill" data-item-order="0" transform="translate(15, 153)"><g id="tx_managesa_907w81fy8etk-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="78.17" y="31" dominant-baseline="ideographic">Manages </tspan><tspan x="44.2" y="49" dominant-baseline="ideographic">authentication </tspan><tspan x="21.78" y="67" dominant-baseline="ideographic">methods securely</tspan></text></g></g></g><g id="g-root-tx_snowflak_mahgqg1fxyjnv-fill" data-item-order="0" transform="translate(315, 255)"><g id="tx_snowflak_mahgqg1fxyjnv-fill" stroke="none" fill="#969696"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="19.18" y="34" dominant-baseline="ideographic">Snowflake-</tspan><tspan x="16.4" y="58" dominant-baseline="ideographic">MCP Server</tspan></text></g></g></g><g id="g-root-tx_querypro_18ntq7s1fy8emh-fill" data-item-order="0" transform="translate(15, 345)"><g id="tx_querypro_18ntq7s1fy8emh-fill" stroke="none" fill="#92bd39"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="50.64" y="34" dominant-baseline="ideographic">Query </tspan><tspan x="12.41" y="58" dominant-baseline="ideographic">Processor</tspan></text></g></g></g><g id="g-root-tx_connecti_dbq3201fy9tz7-fill" data-item-order="0" transform="translate(591, 345)"><g id="tx_connecti_dbq3201fy9tz7-fill" stroke="none" fill="#3cc583"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="12" y="34" dominant-baseline="ideographic">Connection </tspan><tspan x="12" y="58" dominant-baseline="ideographic">Manager</tspan></text></g></g></g><g id="g-root-sear_dj7s3c1fy5kb0-fill" data-item-order="0" transform="translate(225, 381)"></g><g id="g-root-brid_zp2cjc1fy8f0m-fill" data-item-order="0" transform="translate(477, 381)"></g><g id="g-root-tx_executes_v303js1fy9rm2-fill" data-item-order="0" transform="translate(15, 405)"><g id="tx_executes_v303js1fy9rm2-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="26.88" y="31" dominant-baseline="ideographic">Executes and </tspan><tspan x="16.06" y="49" dominant-baseline="ideographic">processes SQL </tspan><tspan x="66.81" y="67" dominant-baseline="ideographic">queries</tspan></text></g></g></g><g id="g-root-tx_oversees_w1rs1fy9sec-fill" data-item-order="0" transform="translate(591, 405)"><g id="tx_oversees_w1rs1fy9sec-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="12" y="31" dominant-baseline="ideographic">Oversees database </tspan><tspan x="12" y="49" dominant-baseline="ideographic">connections </tspan><tspan x="12" y="67" dominant-baseline="ideographic">lifecycle</tspan></text></g></g></g><g id="g-root-0.g-0_fr_13z9kvs1fxylfy-stroke" data-item-order="-311030" transform="translate(255, 159)"><g id="0.g-0_fr_13z9kvs1fxylfy-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#969696" stroke-width="2"><g><path d="M 250 130C 250 196.2742 196.2742 250 130 250C 63.7258 250 10 196.2742 10 130C 10 63.7258 63.7258 10 130 10C 196.2742 10 250 63.7258 250 130Z"></path></g></g></g><g id="g-root-4.g-4_fr_zk2jug1fxyj2g-stroke" data-item-order="-311026" transform="translate(183, 87)"><g id="4.g-4_fr_zk2jug1fxyj2g-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#e0cb15" stroke-width="2"><g><path d="M 94 10C 47.6081 10 10 47.6081 10 94C 10 137.1832 42.5856 172.7555 84.5093 177.4698C 94.1869 130.8792 130.8792 94.1869 177.4698 84.5093C 172.7555 42.5856 137.1832 10 94 10ZM 93.999977 178.000466C 140.391877 178.000466 177.999977 140.392366 177.999977 94.000466C 177.999977 90.791666 177.820077 87.624966 177.469777 84.509766C 130.879177 94.187366 94.186877 130.879666 84.509277 177.470266C 87.624477 177.820566 90.791177 178.000466 93.999977 178.000466Z"></path></g></g></g><g id="g-root-3.g-3_fr_v491q01fxyjuq-stroke" data-item-order="-311020" transform="translate(183, 303)"><g id="3.g-3_fr_v491q01fxyjuq-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 10 93.999097C 10 140.390997 47.6081 177.999097 94 177.999097C 137.1832 177.999097 172.7555 145.413497 177.4698 103.489797C 130.8792 93.812197 94.1869 57.119897 84.5093 10.529297C 42.5856 15.243497 10 50.815897 10 93.999097ZM 178.000015 94C 178.000015 47.6081 140.391915 10 94.000015 10C 90.791215 10 87.624515 10.1799 84.509315 10.5302C 94.186915 57.1208 130.879215 93.8131 177.469815 103.4907C 177.820115 100.3755 178.000015 97.2088 178.000015 94Z"></path></g></g></g><g id="g-root-2.g-2_fr_m8m1h41fxykng-stroke" data-item-order="-311014" transform="translate(399, 303)"><g id="2.g-2_fr_m8m1h41fxykng-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 94.000073 177.999097C 140.391973 177.999097 178.000073 140.390997 178.000073 93.999097C 178.000073 50.815897 145.414473 15.243497 103.490773 10.529297C 93.813173 57.119897 57.120873 93.812197 10.530273 103.489797C 15.244473 145.413497 50.816873 177.999097 94.000073 177.999097ZM 94 10C 47.6081 10 10 47.6081 10 94C 10 97.2088 10.1799 100.3755 10.5302 103.4907C 57.1208 93.8131 93.8131 57.1208 103.4907 10.5302C 100.3755 10.1799 97.2088 10 94 10Z"></path></g></g></g><g id="g-root-1.g-1_fr_8xs06w1fxyj2m-stroke" data-item-order="-311008" transform="translate(399, 87)"><g id="1.g-1_fr_8xs06w1fxyj2m-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 178.000012 94C 178.000012 47.6081 140.391912 10 94.000012 10C 50.816812 10 15.244412 42.5856 10.530212 84.5093C 57.120812 94.1869 93.813112 130.8792 103.490712 177.4698C 145.414412 172.7555 178.000012 137.1832 178.000012 94ZM 10 94.000466C 10 140.392366 47.6081 178.000466 94 178.000466C 97.2088 178.000466 100.3755 177.820566 103.4907 177.470266C 93.8131 130.879666 57.1208 94.187366 10.5302 84.509766C 10.1799 87.624966 10 90.791666 10 94.000466Z"></path></g></g></g><g id="g-root-tx_keycompo_1lsf0mw1fxyiv5-stroke" data-item-order="0" transform="translate(99, 39)"></g><g id="g-root-tx_authenti_hznraw1fy8fm7-stroke" data-item-order="0" transform="translate(15, 93)"></g><g id="g-root-tx_mcpserve_1q6d3i01fy9szx-stroke" data-item-order="0" transform="translate(591, 99)"></g><g id="g-root-key_91iupk1fy8cul-stroke" data-item-order="0" transform="translate(225, 129)"><g id="key_91iupk1fy8cul-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#e0cb15" stroke-width="2"><g><path d="M 42.810001 50.462002C 41.833622 51.438122 40.250832 51.437984 39.27462 50.461689C 38.298416 49.485397 38.298416 47.902603 39.27462 46.926311C 40.250832 45.95002 41.833622 45.949879 42.810001 46.925999C 43.785519 47.902821 43.785519 49.48518 42.810001 50.462002ZM 10 10M 48.096001 45.883999L 56.706001 37.293999C 56.894161 37.106426 56.999943 36.851685 57 36.585999L 57 34C 57 33.447716 56.552284 33 56 33L 53.400002 33C 53.144054 32.999924 52.89782 33.097984 52.712002 33.274002L 43.854 41.641998C 40.328316 40.148323 36.238579 41.362339 34.098885 44.53775C 31.959192 47.713158 32.369568 51.959496 35.077744 54.666393C 37.785919 57.373291 42.032452 57.78167 45.206848 55.64048C 48.381248 53.49929 49.593338 49.408978 48.098 45.883999ZM 16.5 19.5C 16.5 24.19442 20.30558 28 25 28C 29.69442 28 33.5 24.19442 33.5 19.5C 33.5 14.80558 29.69442 11 25 11C 20.30558 11 16.5 14.80558 16.5 19.5ZM 27 45L 11 45C 10.999902 39.114559 14.680733 33.857452 20.211155 31.844276C 25.741575 29.831099 31.940599 31.491751 35.723999 36"></path></g></g></g><g id="g-root-hier_8z0yd41fxyl8s-stroke" data-item-order="0" transform="translate(477, 129)"><g id="hier_8z0yd41fxyl8s-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 23 26.002001C 23 28.763424 27.924868 31.002001 34 31.002001C 40.075134 31.002001 45 28.763424 45 26.002001C 45 23.240578 40.075134 21.001999 34 21.001999C 27.924868 21.001999 23 23.240578 23 26.002001ZM 47 14.002C 47 15.658854 49.238575 17.002001 52 17.002001C 54.761425 17.002001 57 15.658854 57 14.002001C 57 12.345146 54.761425 11.002 52 11.002C 49.238575 11.002 47 12.345146 47 14.002001ZM 57 14L 57 20C 57 21.656 54.762001 23 52 23C 49.237999 23 47 21.658001 47 20L 47 14M 11 14.002C 11 15.658854 13.238577 17.002001 16 17.002001C 18.761425 17.002001 21 15.658854 21 14.002001C 21 12.345146 18.761425 11.002 16 11.002C 13.238577 11.002 11 12.345146 11 14.002001ZM 21 14L 21 20C 21 21.656 18.762001 23 16 23C 13.238 23 11 21.658001 11 20L 11 14M 47 48.001999C 47 49.658855 49.238575 51.002003 52 51.002003C 54.761425 51.002003 57 49.658855 57 48.002003C 57 46.345146 54.761425 45.002003 52 45.002003C 49.238575 45.002003 47 46.345146 47 48.002003ZM 57 48L 57 54C 57 55.655998 54.762001 57 52 57C 49.237999 57 47 55.655998 47 54L 47 48M 11 48.001999C 11 49.658855 13.238577 51.002003 16 51.002003C 18.761425 51.002003 21 49.658855 21 48.002003C 21 46.345146 18.761425 45.002003 16 45.002003C 13.238577 45.002003 11 46.345146 11 48.002003ZM 21 48L 21 54C 21 55.655998 18.762001 57 16 57C 13.238 57 11 55.658001 11 54L 11 48M 45 34C 45 36.762001 40.073997 39 34 39C 27.926001 39 23 36.764 23 34M 23 26L 23 42C 23 44.762001 27.926001 47 34 47C 40.073997 47 45 44.762001 45 42L 45 26M 20.618 21.156L 23.702 24.24M 47.382 21.156L 44.298 24.24M 20.709999 46.993999L 23.812 43.889999M 47.290001 46.993999L 44.188 43.889999"></path></g></g></g><g id="g-root-tx_centralc_1cvj27s1fy9rf2-stroke" data-item-order="0" transform="translate(591, 135)"></g><g id="g-root-tx_managesa_907w81fy8etk-stroke" data-item-order="0" transform="translate(15, 153)"></g><g id="g-root-tx_snowflak_mahgqg1fxyjnv-stroke" data-item-order="0" transform="translate(315, 255)"></g><g id="g-root-tx_querypro_18ntq7s1fy8emh-stroke" data-item-order="0" transform="translate(15, 345)"></g><g id="g-root-tx_connecti_dbq3201fy9tz7-stroke" data-item-order="0" transform="translate(591, 345)"></g><g id="g-root-sear_dj7s3c1fy5kb0-stroke" data-item-order="0" transform="translate(225, 381)"><g id="sear_dj7s3c1fy5kb0-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 35 44.057999C 35 49.060593 39.055405 53.115997 44.057999 53.115997C 49.060593 53.115997 53.115997 49.060593 53.115997 44.057999C 53.115997 39.055405 49.060593 35 44.057999 35C 39.055405 35 35 39.055405 35 44.057999ZM 57 57L 50.504002 50.504002M 19 27L 38 27M 19 33L 31 33M 19 21L 33 21M 19 39L 27 39M 19 45L 27 45M 35 57L 13 57C 11.895431 57 11 56.104568 11 55L 11 13C 11 11.895431 11.895431 11 13 11L 39.585999 11C 40.11639 11.000113 40.625015 11.210901 41 11.586L 48.414001 19C 48.789101 19.374985 48.999886 19.88361 49 20.414L 49 29"></path></g></g></g><g id="g-root-brid_zp2cjc1fy8f0m-stroke" data-item-order="0" transform="translate(477, 381)"><g id="brid_zp2cjc1fy8f0m-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 56.987999 22.633999C 51.417332 21.449936 47.327156 16.685707 46.999996 11C 47 17.628 40.627998 23 34 23C 27.372 23 21 17.628 21 11C 20.672398 16.703152 16.559757 21.477453 10.968 22.646M 11 33L 57 33M 23 45L 23 33M 19 33L 19 43M 45 43L 45 33.001999M 49 33L 49 43M 15.002 20.966L 15.002 33M 21.001999 11L 21.001999 33M 27.002001 20.968L 27.002001 33M 35.001999 22.959999L 35.001999 33M 41.001999 21.001999L 41.001999 33M 47 11L 47.001999 33M 53.001999 20.966L 53.001999 32.996002M 56.981998 56.776001C 51.981998 57.818001 48.862 52.818001 48.862 52.818001L 48.862 52.818001C 47.290386 55.316471 44.57085 56.860619 41.620003 56.930004C 38.693253 56.786953 36.009048 55.260334 34.389999 52.818001L 34.389999 52.818001C 32.818771 55.315887 30.100136 56.859955 27.150002 56.930004C 24.222607 56.789177 21.537462 55.262028 19.919998 52.817997L 19.92 52.818001C 19.92 52.818001 15.92 57.902 11.01 56.858002M 56.981998 49.776001C 51.981998 50.818001 48.862 45.818001 48.862 45.818001L 48.862 45.818001C 47.290386 48.316471 44.57085 49.860619 41.620003 49.93C 38.693253 49.786953 36.009048 48.260334 34.389999 45.818001L 34.389999 45.818001C 32.818771 48.315887 30.100136 49.859955 27.150002 49.93C 24.222607 49.789177 21.537462 48.262028 19.919998 45.817997L 19.92 45.818001C 19.92 45.818001 15.92 50.902 11.01 49.858002"></path></g></g></g><g id="g-root-tx_executes_v303js1fy9rm2-stroke" data-item-order="0" transform="translate(15, 405)"></g><g id="g-root-tx_oversees_w1rs1fy9sec-stroke" data-item-order="0" transform="translate(591, 405)"></g></g></g></svg> ``` -------------------------------------------------------------------------------- /assets/key_components.svg: -------------------------------------------------------------------------------- ``` <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="770" height="530" viewBox="0 0 770 530" style="fill:none;stroke:none;fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style class="text-font-style fontImports" data-font-family="Roboto">@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=block');</style><g id="items" style="isolation: isolate"><g id="blend" style="mix-blend-mode: normal"><g id="g-root-0.g-0_fr_13z9kvs1fxylfy-fill" data-item-order="-311030" transform="translate(255, 159)"><g id="0.g-0_fr_13z9kvs1fxylfy-fill" stroke="none" fill="#545454"><g><path d="M 250 130C 250 196.274 196.274 250 130 250C 63.7258 250 10 196.274 10 130C 10 63.7258 63.7258 10 130 10C 196.274 10 250 63.7258 250 130Z"></path></g></g></g><g id="g-root-4.g-4_fr_zk2jug1fxyj2g-fill" data-item-order="-311026" transform="translate(183, 87)"><g id="4.g-4_fr_zk2jug1fxyj2g-fill" stroke="none" fill="#54502f"><g><path d="M 94 10C 47.6081 10 10 47.6081 10 94C 10 137.183 42.5856 172.756 84.5093 177.47C 94.1869 130.879 130.879 94.1869 177.47 84.5093C 172.756 42.5856 137.183 10 94 10Z"></path></g></g></g><g id="g-root-3.g-3_fr_v491q01fxyjuq-fill" data-item-order="-311020" transform="translate(183, 303)"><g id="3.g-3_fr_v491q01fxyjuq-fill" stroke="none" fill="#4b533a"><g><path d="M 10 93.999097C 10 140.391297 47.6081 177.999297 94 177.999297C 137.183 177.999297 172.756 145.413297 177.47 103.489797C 130.879 93.812197 94.1869 57.119897 84.5093 10.529297C 42.5856 15.243497 10 50.815897 10 93.999097Z"></path></g></g></g><g id="g-root-2.g-2_fr_m8m1h41fxykng-fill" data-item-order="-311014" transform="translate(399, 303)"><g id="2.g-2_fr_m8m1h41fxykng-fill" stroke="none" fill="#3b5649"><g><path d="M 94.000073 177.999297C 140.392273 177.999297 178.000273 140.391297 178.000273 93.999097C 178.000273 50.815897 145.414273 15.243597 103.490773 10.529297C 93.813173 57.119897 57.120873 93.812197 10.530273 103.489797C 15.244473 145.413297 50.816873 177.999297 94.000073 177.999297Z"></path></g></g></g><g id="g-root-1.g-1_fr_8xs06w1fxyj2m-fill" data-item-order="-311008" transform="translate(399, 87)"><g id="1.g-1_fr_8xs06w1fxyj2m-fill" stroke="none" fill="#344e57"><g><path d="M 178.000212 94C 178.000212 47.6081 140.392212 10 94.000012 10C 50.816812 10 15.244412 42.5856 10.530212 84.5093C 57.120812 94.1869 93.813112 130.879 103.490712 177.47C 145.414212 172.756 178.000212 137.183 178.000212 94Z"></path></g></g></g><g id="g-root-tx_keycompo_1lsf0mw1fxyiv5-fill" data-item-order="0" transform="translate(99, 39)"><g id="tx_keycompo_1lsf0mw1fxyiv5-fill" stroke="none" fill="#f4f4f4"><g><text style="font: 20px Roboto, sans-serif; white-space: pre;" font-size="20px" font-family="Roboto, sans-serif"><tspan x="12.67" y="34" dominant-baseline="ideographic">Key Components Enhancing Snowflake-MCP Server Efficiency</tspan></text></g></g></g><g id="g-root-tx_authenti_hznraw1fy8fm7-fill" data-item-order="0" transform="translate(15, 93)"><g id="tx_authenti_hznraw1fy8fm7-fill" stroke="none" fill="#ffe711"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="19.73" y="34" dominant-baseline="ideographic">Authentication </tspan><tspan x="72.31" y="58" dominant-baseline="ideographic">Manager</tspan></text></g></g></g><g id="g-root-tx_mcpserve_1q6d3i01fy9szx-fill" data-item-order="0" transform="translate(591, 99)"><g id="tx_mcpserve_1q6d3i01fy9szx-fill" stroke="none" fill="#1ac3fb"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="12" y="34" dominant-baseline="ideographic">MCP Server</tspan></text></g></g></g><g id="g-root-key_91iupk1fy8cul-fill" data-item-order="0" transform="translate(225, 129)"></g><g id="g-root-hier_8z0yd41fxyl8s-fill" data-item-order="0" transform="translate(477, 129)"></g><g id="g-root-tx_centralc_1cvj27s1fy9rf2-fill" data-item-order="0" transform="translate(591, 135)"><g id="tx_centralc_1cvj27s1fy9rf2-fill" stroke="none" fill="#f4f4f4"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="12" y="28" dominant-baseline="ideographic">Central component </tspan><tspan x="12" y="46" dominant-baseline="ideographic">managing protocol </tspan><tspan x="12" y="64" dominant-baseline="ideographic">and client </tspan><tspan x="12" y="82" dominant-baseline="ideographic">interactions</tspan></text></g></g></g><g id="g-root-tx_managesa_907w81fy8etk-fill" data-item-order="0" transform="translate(15, 153)"><g id="tx_managesa_907w81fy8etk-fill" stroke="none" fill="#f4f4f4"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="78.17" y="31" dominant-baseline="ideographic">Manages </tspan><tspan x="44.2" y="49" dominant-baseline="ideographic">authentication </tspan><tspan x="21.78" y="67" dominant-baseline="ideographic">methods securely</tspan></text></g></g></g><g id="g-root-tx_snowflak_mahgqg1fxyjnv-fill" data-item-order="0" transform="translate(315, 255)"><g id="tx_snowflak_mahgqg1fxyjnv-fill" stroke="none" fill="#b7b7b7"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="19.18" y="34" dominant-baseline="ideographic">Snowflake-</tspan><tspan x="16.4" y="58" dominant-baseline="ideographic">MCP Server</tspan></text></g></g></g><g id="g-root-tx_querypro_18ntq7s1fy8emh-fill" data-item-order="0" transform="translate(15, 345)"><g id="tx_querypro_18ntq7s1fy8emh-fill" stroke="none" fill="#a6da37"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="50.64" y="34" dominant-baseline="ideographic">Query </tspan><tspan x="12.41" y="58" dominant-baseline="ideographic">Processor</tspan></text></g></g></g><g id="g-root-tx_connecti_dbq3201fy9tz7-fill" data-item-order="0" transform="translate(591, 345)"><g id="tx_connecti_dbq3201fy9tz7-fill" stroke="none" fill="#43dd93"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="12" y="34" dominant-baseline="ideographic">Connection </tspan><tspan x="12" y="58" dominant-baseline="ideographic">Manager</tspan></text></g></g></g><g id="g-root-sear_dj7s3c1fy5kb0-fill" data-item-order="0" transform="translate(225, 381)"></g><g id="g-root-brid_zp2cjc1fy8f0m-fill" data-item-order="0" transform="translate(477, 381)"></g><g id="g-root-tx_executes_v303js1fy9rm2-fill" data-item-order="0" transform="translate(15, 405)"><g id="tx_executes_v303js1fy9rm2-fill" stroke="none" fill="#f4f4f4"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="26.88" y="31" dominant-baseline="ideographic">Executes and </tspan><tspan x="16.06" y="49" dominant-baseline="ideographic">processes SQL </tspan><tspan x="66.81" y="67" dominant-baseline="ideographic">queries</tspan></text></g></g></g><g id="g-root-tx_oversees_w1rs1fy9sec-fill" data-item-order="0" transform="translate(591, 405)"><g id="tx_oversees_w1rs1fy9sec-fill" stroke="none" fill="#f4f4f4"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="12" y="31" dominant-baseline="ideographic">Oversees database </tspan><tspan x="12" y="49" dominant-baseline="ideographic">connections </tspan><tspan x="12" y="67" dominant-baseline="ideographic">lifecycle</tspan></text></g></g></g><g id="g-root-0.g-0_fr_13z9kvs1fxylfy-stroke" data-item-order="-311030" transform="translate(255, 159)"><g id="0.g-0_fr_13z9kvs1fxylfy-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#b7b7b7" stroke-width="2"><g><path d="M 250 130C 250 196.2742 196.2742 250 130 250C 63.7258 250 10 196.2742 10 130C 10 63.7258 63.7258 10 130 10C 196.2742 10 250 63.7258 250 130Z"></path></g></g></g><g id="g-root-4.g-4_fr_zk2jug1fxyj2g-stroke" data-item-order="-311026" transform="translate(183, 87)"><g id="4.g-4_fr_zk2jug1fxyj2g-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ffe711" stroke-width="2"><g><path d="M 94 10C 47.6081 10 10 47.6081 10 94C 10 137.1832 42.5856 172.7555 84.5093 177.4698C 94.1869 130.8792 130.8792 94.1869 177.4698 84.5093C 172.7555 42.5856 137.1832 10 94 10ZM 93.999977 178.000466C 140.391877 178.000466 177.999977 140.392366 177.999977 94.000466C 177.999977 90.791666 177.820077 87.624966 177.469777 84.509766C 130.879177 94.187366 94.186877 130.879666 84.509277 177.470266C 87.624477 177.820566 90.791177 178.000466 93.999977 178.000466Z"></path></g></g></g><g id="g-root-3.g-3_fr_v491q01fxyjuq-stroke" data-item-order="-311020" transform="translate(183, 303)"><g id="3.g-3_fr_v491q01fxyjuq-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#a6da37" stroke-width="2"><g><path d="M 10 93.999097C 10 140.390997 47.6081 177.999097 94 177.999097C 137.1832 177.999097 172.7555 145.413497 177.4698 103.489797C 130.8792 93.812197 94.1869 57.119897 84.5093 10.529297C 42.5856 15.243497 10 50.815897 10 93.999097ZM 178.000015 94C 178.000015 47.6081 140.391915 10 94.000015 10C 90.791215 10 87.624515 10.1799 84.509315 10.5302C 94.186915 57.1208 130.879215 93.8131 177.469815 103.4907C 177.820115 100.3755 178.000015 97.2088 178.000015 94Z"></path></g></g></g><g id="g-root-2.g-2_fr_m8m1h41fxykng-stroke" data-item-order="-311014" transform="translate(399, 303)"><g id="2.g-2_fr_m8m1h41fxykng-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#43dd93" stroke-width="2"><g><path d="M 94.000073 177.999097C 140.391973 177.999097 178.000073 140.390997 178.000073 93.999097C 178.000073 50.815897 145.414473 15.243497 103.490773 10.529297C 93.813173 57.119897 57.120873 93.812197 10.530273 103.489797C 15.244473 145.413497 50.816873 177.999097 94.000073 177.999097ZM 94 10C 47.6081 10 10 47.6081 10 94C 10 97.2088 10.1799 100.3755 10.5302 103.4907C 57.1208 93.8131 93.8131 57.1208 103.4907 10.5302C 100.3755 10.1799 97.2088 10 94 10Z"></path></g></g></g><g id="g-root-1.g-1_fr_8xs06w1fxyj2m-stroke" data-item-order="-311008" transform="translate(399, 87)"><g id="1.g-1_fr_8xs06w1fxyj2m-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1ac3fb" stroke-width="2"><g><path d="M 178.000012 94C 178.000012 47.6081 140.391912 10 94.000012 10C 50.816812 10 15.244412 42.5856 10.530212 84.5093C 57.120812 94.1869 93.813112 130.8792 103.490712 177.4698C 145.414412 172.7555 178.000012 137.1832 178.000012 94ZM 10 94.000466C 10 140.392366 47.6081 178.000466 94 178.000466C 97.2088 178.000466 100.3755 177.820566 103.4907 177.470266C 93.8131 130.879666 57.1208 94.187366 10.5302 84.509766C 10.1799 87.624966 10 90.791666 10 94.000466Z"></path></g></g></g><g id="g-root-tx_keycompo_1lsf0mw1fxyiv5-stroke" data-item-order="0" transform="translate(99, 39)"></g><g id="g-root-tx_authenti_hznraw1fy8fm7-stroke" data-item-order="0" transform="translate(15, 93)"></g><g id="g-root-tx_mcpserve_1q6d3i01fy9szx-stroke" data-item-order="0" transform="translate(591, 99)"></g><g id="g-root-key_91iupk1fy8cul-stroke" data-item-order="0" transform="translate(225, 129)"><g id="key_91iupk1fy8cul-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ffe711" stroke-width="2"><g><path d="M 42.810001 50.462002C 41.833622 51.438122 40.250832 51.437984 39.27462 50.461689C 38.298416 49.485397 38.298416 47.902603 39.27462 46.926311C 40.250832 45.95002 41.833622 45.949879 42.810001 46.925999C 43.785519 47.902821 43.785519 49.48518 42.810001 50.462002ZM 10 10M 48.096001 45.883999L 56.706001 37.293999C 56.894161 37.106426 56.999943 36.851685 57 36.585999L 57 34C 57 33.447716 56.552284 33 56 33L 53.400002 33C 53.144054 32.999924 52.89782 33.097984 52.712002 33.274002L 43.854 41.641998C 40.328316 40.148323 36.238579 41.362339 34.098885 44.53775C 31.959192 47.713158 32.369568 51.959496 35.077744 54.666393C 37.785919 57.373291 42.032452 57.78167 45.206848 55.64048C 48.381248 53.49929 49.593338 49.408978 48.098 45.883999ZM 16.5 19.5C 16.5 24.19442 20.30558 28 25 28C 29.69442 28 33.5 24.19442 33.5 19.5C 33.5 14.80558 29.69442 11 25 11C 20.30558 11 16.5 14.80558 16.5 19.5ZM 27 45L 11 45C 10.999902 39.114559 14.680733 33.857452 20.211155 31.844276C 25.741575 29.831099 31.940599 31.491751 35.723999 36"></path></g></g></g><g id="g-root-hier_8z0yd41fxyl8s-stroke" data-item-order="0" transform="translate(477, 129)"><g id="hier_8z0yd41fxyl8s-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1ac3fb" stroke-width="2"><g><path d="M 23 26.002001C 23 28.763424 27.924868 31.002001 34 31.002001C 40.075134 31.002001 45 28.763424 45 26.002001C 45 23.240578 40.075134 21.001999 34 21.001999C 27.924868 21.001999 23 23.240578 23 26.002001ZM 47 14.002C 47 15.658854 49.238575 17.002001 52 17.002001C 54.761425 17.002001 57 15.658854 57 14.002001C 57 12.345146 54.761425 11.002 52 11.002C 49.238575 11.002 47 12.345146 47 14.002001ZM 57 14L 57 20C 57 21.656 54.762001 23 52 23C 49.237999 23 47 21.658001 47 20L 47 14M 11 14.002C 11 15.658854 13.238577 17.002001 16 17.002001C 18.761425 17.002001 21 15.658854 21 14.002001C 21 12.345146 18.761425 11.002 16 11.002C 13.238577 11.002 11 12.345146 11 14.002001ZM 21 14L 21 20C 21 21.656 18.762001 23 16 23C 13.238 23 11 21.658001 11 20L 11 14M 47 48.001999C 47 49.658855 49.238575 51.002003 52 51.002003C 54.761425 51.002003 57 49.658855 57 48.002003C 57 46.345146 54.761425 45.002003 52 45.002003C 49.238575 45.002003 47 46.345146 47 48.002003ZM 57 48L 57 54C 57 55.655998 54.762001 57 52 57C 49.237999 57 47 55.655998 47 54L 47 48M 11 48.001999C 11 49.658855 13.238577 51.002003 16 51.002003C 18.761425 51.002003 21 49.658855 21 48.002003C 21 46.345146 18.761425 45.002003 16 45.002003C 13.238577 45.002003 11 46.345146 11 48.002003ZM 21 48L 21 54C 21 55.655998 18.762001 57 16 57C 13.238 57 11 55.658001 11 54L 11 48M 45 34C 45 36.762001 40.073997 39 34 39C 27.926001 39 23 36.764 23 34M 23 26L 23 42C 23 44.762001 27.926001 47 34 47C 40.073997 47 45 44.762001 45 42L 45 26M 20.618 21.156L 23.702 24.24M 47.382 21.156L 44.298 24.24M 20.709999 46.993999L 23.812 43.889999M 47.290001 46.993999L 44.188 43.889999"></path></g></g></g><g id="g-root-tx_centralc_1cvj27s1fy9rf2-stroke" data-item-order="0" transform="translate(591, 135)"></g><g id="g-root-tx_managesa_907w81fy8etk-stroke" data-item-order="0" transform="translate(15, 153)"></g><g id="g-root-tx_snowflak_mahgqg1fxyjnv-stroke" data-item-order="0" transform="translate(315, 255)"></g><g id="g-root-tx_querypro_18ntq7s1fy8emh-stroke" data-item-order="0" transform="translate(15, 345)"></g><g id="g-root-tx_connecti_dbq3201fy9tz7-stroke" data-item-order="0" transform="translate(591, 345)"></g><g id="g-root-sear_dj7s3c1fy5kb0-stroke" data-item-order="0" transform="translate(225, 381)"><g id="sear_dj7s3c1fy5kb0-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#a6da37" stroke-width="2"><g><path d="M 35 44.057999C 35 49.060593 39.055405 53.115997 44.057999 53.115997C 49.060593 53.115997 53.115997 49.060593 53.115997 44.057999C 53.115997 39.055405 49.060593 35 44.057999 35C 39.055405 35 35 39.055405 35 44.057999ZM 57 57L 50.504002 50.504002M 19 27L 38 27M 19 33L 31 33M 19 21L 33 21M 19 39L 27 39M 19 45L 27 45M 35 57L 13 57C 11.895431 57 11 56.104568 11 55L 11 13C 11 11.895431 11.895431 11 13 11L 39.585999 11C 40.11639 11.000113 40.625015 11.210901 41 11.586L 48.414001 19C 48.789101 19.374985 48.999886 19.88361 49 20.414L 49 29"></path></g></g></g><g id="g-root-brid_zp2cjc1fy8f0m-stroke" data-item-order="0" transform="translate(477, 381)"><g id="brid_zp2cjc1fy8f0m-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#43dd93" stroke-width="2"><g><path d="M 56.987999 22.633999C 51.417332 21.449936 47.327156 16.685707 46.999996 11C 47 17.628 40.627998 23 34 23C 27.372 23 21 17.628 21 11C 20.672398 16.703152 16.559757 21.477453 10.968 22.646M 11 33L 57 33M 23 45L 23 33M 19 33L 19 43M 45 43L 45 33.001999M 49 33L 49 43M 15.002 20.966L 15.002 33M 21.001999 11L 21.001999 33M 27.002001 20.968L 27.002001 33M 35.001999 22.959999L 35.001999 33M 41.001999 21.001999L 41.001999 33M 47 11L 47.001999 33M 53.001999 20.966L 53.001999 32.996002M 56.981998 56.776001C 51.981998 57.818001 48.862 52.818001 48.862 52.818001L 48.862 52.818001C 47.290386 55.316471 44.57085 56.860619 41.620003 56.930004C 38.693253 56.786953 36.009048 55.260334 34.389999 52.818001L 34.389999 52.818001C 32.818771 55.315887 30.100136 56.859955 27.150002 56.930004C 24.222607 56.789177 21.537462 55.262028 19.919998 52.817997L 19.92 52.818001C 19.92 52.818001 15.92 57.902 11.01 56.858002M 56.981998 49.776001C 51.981998 50.818001 48.862 45.818001 48.862 45.818001L 48.862 45.818001C 47.290386 48.316471 44.57085 49.860619 41.620003 49.93C 38.693253 49.786953 36.009048 48.260334 34.389999 45.818001L 34.389999 45.818001C 32.818771 48.315887 30.100136 49.859955 27.150002 49.93C 24.222607 49.789177 21.537462 48.262028 19.919998 45.817997L 19.92 45.818001C 19.92 45.818001 15.92 50.902 11.01 49.858002"></path></g></g></g><g id="g-root-tx_executes_v303js1fy9rm2-stroke" data-item-order="0" transform="translate(15, 405)"></g><g id="g-root-tx_oversees_w1rs1fy9sec-stroke" data-item-order="0" transform="translate(591, 405)"></g></g></g></svg> ``` -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- ```python #!/usr/bin/env python import os import asyncio import logging import json import time import snowflake.connector from dotenv import load_dotenv import mcp.server.stdio from mcp.server import Server from mcp.types import Tool, TextContent from typing import Optional, Any, List, Dict import pandas as pd # Configure logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger('snowflake_mcp') # Load environment variables from .env file load_dotenv() # Define the allowed base path for CSV exports, defaulting to /export # This directory MUST be mounted as a volume in Docker. EXPORT_BASE_PATH = os.getenv("EXPORT_BASE_PATH", "/export") if not os.path.exists(EXPORT_BASE_PATH): try: os.makedirs(EXPORT_BASE_PATH) logger.info(f"Created export directory: {EXPORT_BASE_PATH}") except OSError as e: logger.error(f"Failed to create export directory {EXPORT_BASE_PATH}: {e}. CSV exports will likely fail.") elif not os.path.isdir(EXPORT_BASE_PATH): logger.error(f"Configured EXPORT_BASE_PATH '{EXPORT_BASE_PATH}' exists but is not a directory. CSV exports will likely fail.") else: logger.info(f"Using export base path: {EXPORT_BASE_PATH}") class SnowflakeConnection: """ Snowflake database connection management class """ def __init__(self): # Initialize configuration from environment variables self.config = { "user": os.getenv("SNOWFLAKE_USER"), "account": os.getenv("SNOWFLAKE_ACCOUNT"), "database": os.getenv("SNOWFLAKE_DATABASE"), "warehouse": os.getenv("SNOWFLAKE_WAREHOUSE"), "role": os.getenv("SNOWFLAKE_ROLE"), } # Log authentication configuration start logger.info("=== CONFIGURING AUTHENTICATION ===") # Check authentication methods available private_key_file = os.getenv("SNOWFLAKE_PRIVATE_KEY_FILE") private_key_passphrase = os.getenv("SNOWFLAKE_PRIVATE_KEY_PASSPHRASE") # Treat empty string passphrase as None if private_key_passphrase == "" or private_key_passphrase is None or (isinstance(private_key_passphrase, str) and private_key_passphrase.strip() == ""): private_key_passphrase = None logger.info("No passphrase provided or empty passphrase detected, treating as None") password = os.getenv("SNOWFLAKE_PASSWORD") # Priority 1: Key pair authentication (always preferred if available) if private_key_file: # First, check if the file exists if not os.path.exists(private_key_file): logger.error(f"Private key file does not exist: {private_key_file}") logger.info("Will try password authentication instead") # Fallback to password authentication if password: self.config["password"] = password logger.info("SELECTED AUTH: PASSWORD (fallback)") logger.info("Using password authentication as fallback") else: logger.error("No password available for fallback. Authentication will fail.") else: # Private key file exists, use key pair authentication if private_key_passphrase is not None: logger.info("SELECTED AUTH: KEY PAIR WITH PASSPHRASE") logger.info(f"Key file: {private_key_file}") else: logger.info("SELECTED AUTH: KEY PAIR WITHOUT PASSPHRASE") logger.info(f"Key file: {private_key_file}") # Ensure passphrase is None private_key_passphrase = None # Try to setup key pair authentication auth_success = self._setup_key_pair_auth(private_key_file, private_key_passphrase) # If key pair auth failed for any reason, try password as fallback if not auth_success: logger.warning("Failed to set up key pair authentication") # Only use password fallback if available if password: logger.info("FALLBACK AUTH: PASSWORD") logger.info("Using password authentication as fallback") self.config["password"] = password else: logger.error("No password available for fallback after key auth failure") logger.error("Authentication will likely fail") # Priority 2: Password authentication (if no key is available) elif password: self.config["password"] = password logger.info("SELECTED AUTH: PASSWORD") logger.info("Using password authentication (no key file configured)") # No authentication method available else: logger.error("NO AUTHENTICATION METHOD AVAILABLE") logger.error("Please configure either a private key or password") # Log authentication configuration end logger.info("=== AUTHENTICATION CONFIGURED ===") self.conn: Optional[snowflake.connector.SnowflakeConnection] = None # Log config (excluding sensitive info) safe_config = {k: v for k, v in self.config.items() if k not in ['password', 'private_key', 'private_key_passphrase']} logger.info(f"Initialized with config: {json.dumps(safe_config)}") # Store the base path for exports self.export_base_path = EXPORT_BASE_PATH if not self.export_base_path: logger.warning("EXPORT_BASE_PATH is not set. CSV export functionality might be limited or fail.") elif not os.path.isdir(self.export_base_path): logger.warning(f"Export base path '{self.export_base_path}' is not a valid directory. CSV exports might fail.") def _setup_key_pair_auth(self, private_key_file: str, passphrase: str = None) -> bool: """ Set up key pair authentication Args: private_key_file (str): Path to private key file passphrase (str, optional): Passphrase for the private key (NOT the Snowflake password) Returns: bool: True if key pair authentication was set up successfully, False otherwise """ try: # Read private key file with open(private_key_file, "rb") as key_file: private_key = key_file.read() # Try to load the key using snowflake's recommended approach from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.serialization import load_pem_private_key logger.info(f"Loading private key from {private_key_file}") # Only pass passphrase if it's not None and not empty if passphrase is not None and passphrase.strip() != "": logger.info("Using passphrase to decrypt private key") p_key = load_pem_private_key( private_key, password=passphrase.encode(), backend=default_backend() ) # Add passphrase to config for encrypted keys self.config["private_key_passphrase"] = passphrase logger.info("Private key with passphrase loaded successfully") else: logger.info("Using private key without passphrase") p_key = load_pem_private_key( private_key, password=None, backend=default_backend() ) logger.info("Private key without passphrase loaded successfully") # Convert key to DER format from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption pkb = p_key.private_bytes( encoding=Encoding.DER, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption() ) # Add private key to config (required for Snowflake key pair auth) self.config["private_key"] = pkb return True except Exception as e: logger.error(f"Error setting up key pair authentication: {str(e)}") logger.error("Details:", exc_info=True) return False def ensure_connection(self) -> snowflake.connector.SnowflakeConnection: """ Ensure database connection is available, create new connection if it doesn't exist or is disconnected """ try: # Check if connection needs to be re-established if self.conn is None: logger.info("Creating new Snowflake connection...") # Determine the auth method we're actually using auth_method = "UNKNOWN" if "private_key" in self.config: auth_method = "KEY_PAIR" if "private_key_passphrase" in self.config and self.config.get("private_key_passphrase") is not None: auth_method += "_WITH_PASSPHRASE" else: auth_method += "_WITHOUT_PASSPHRASE" elif "password" in self.config: auth_method = "PASSWORD" logger.info(f"Connecting with authentication method: {auth_method}") # Attempt connection self.conn = snowflake.connector.connect( **self.config, client_session_keep_alive=True, network_timeout=15, login_timeout=15 ) self.conn.cursor().execute("ALTER SESSION SET TIMEZONE = 'UTC'") # Log successful connection details logger.info(f"=== CONNECTION ESTABLISHED ===") logger.info(f"Authentication Method: {auth_method}") logger.info(f"Connected to: {self.config['account']}") logger.info(f"User: {self.config['user']}") logger.info(f"Database: {self.config['database']}") logger.info(f"Warehouse: {self.config['warehouse']}") logger.info(f"==============================") logger.info("New connection established and configured") # Test if connection is valid try: self.conn.cursor().execute("SELECT 1") except: logger.info("Connection lost, reconnecting...") self.conn = None return self.ensure_connection() return self.conn except Exception as e: logger.error(f"Connection error: {str(e)}") raise def execute_query(self, query: str) -> List[Dict[str, Any]]: """ Execute SQL query and return results Args: query (str): SQL query statement Returns: List[Dict[str, Any]]: List of query results """ start_time = time.time() logger.info(f"Executing query: {query[:200]}...") # Log only first 200 characters try: conn = self.ensure_connection() with conn.cursor() as cursor: # For write operations use transaction if any(query.strip().upper().startswith(word) for word in ['INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER']): cursor.execute("BEGIN") try: cursor.execute(query) conn.commit() logger.info(f"Write query executed in {time.time() - start_time:.2f}s") return [{"affected_rows": cursor.rowcount}] except Exception as e: conn.rollback() raise else: # Read operations cursor.execute(query) if cursor.description: columns = [col[0] for col in cursor.description] rows = cursor.fetchall() results = [dict(zip(columns, row)) for row in rows] logger.info(f"Read query returned {len(results)} rows in {time.time() - start_time:.2f}s") return results return [] except snowflake.connector.errors.ProgrammingError as e: logger.error(f"SQL Error: {str(e)}") logger.error(f"Error Code: {getattr(e, 'errno', 'unknown')}") raise except Exception as e: logger.error(f"Query error: {str(e)}") logger.error(f"Error type: {type(e).__name__}") raise def export_to_csv(self, query: str, relative_file_path: str) -> Dict[str, Any]: """ Execute SQL query and export results to a CSV file within the configured base path. Args: query (str): SQL query statement. relative_file_path (str): The relative path and filename for the CSV file (e.g., 'my_report.csv' or 'subdir/data.csv'). This will be joined with the EXPORT_BASE_PATH. Returns: Dict[str, Any]: A dictionary containing the full path to the exported file and the number of rows exported. Raises: ValueError: If the relative_file_path attempts to escape the export base path or is invalid. FileNotFoundError: If the export base path does not exist or is not a directory. Exception: Propagates exceptions from database query or file writing. """ start_time = time.time() logger.info(f"Exporting query to CSV: {query[:200]}...") logger.info(f"Target relative path: {relative_file_path}") if not self.export_base_path or not os.path.isdir(self.export_base_path): error_msg = f"Export base path '{self.export_base_path}' is not configured or not a valid directory." logger.error(error_msg) raise FileNotFoundError(error_msg) # Prevent path traversal attacks and ensure the path is relative if relative_file_path.startswith('/') or '..' in relative_file_path: error_msg = f"Invalid relative file path: '{relative_file_path}'. Must not start with '/' or contain '..'." logger.error(error_msg) raise ValueError(error_msg) # Construct the full path safely full_path = os.path.abspath(os.path.join(self.export_base_path, relative_file_path)) # Double-check it's still within the base path after resolving if not full_path.startswith(os.path.abspath(self.export_base_path)): error_msg = f"Resolved path '{full_path}' is outside the allowed export directory '{self.export_base_path}'." logger.error(error_msg) raise ValueError(error_msg) # Ensure the target directory exists target_dir = os.path.dirname(full_path) if not os.path.exists(target_dir): try: os.makedirs(target_dir) logger.info(f"Created directory for export: {target_dir}") except OSError as e: logger.error(f"Failed to create directory {target_dir}: {e}") raise logger.info(f"Full export path: {full_path}") try: conn = self.ensure_connection() with conn.cursor() as cursor: # Execute the query (read operations only for export) if any(query.strip().upper().startswith(word) for word in ['INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER']): raise ValueError("Only SELECT queries can be exported to CSV.") cursor.execute(query) if cursor.description: # Fetch data using pandas for efficient CSV writing df = cursor.fetch_pandas_all() row_count = len(df) # Write DataFrame to CSV df.to_csv(full_path, index=False) execution_time = time.time() - start_time logger.info(f"Exported {row_count} rows to '{full_path}' in {execution_time:.2f}s") return { "message": f"Successfully exported {row_count} rows.", "file_path": full_path, # Return the full path on the server's filesystem "rows_exported": row_count } else: # Handle queries that return no description (e.g., USE DATABASE) logger.info("Query did not return results to export.") # Create an empty file or return specific message? Let's return 0 rows. # Create an empty file to signify the query ran but had no output columns/rows pd.DataFrame().to_csv(full_path, index=False) execution_time = time.time() - start_time logger.info(f"Exported 0 rows (query returned no data/columns) to '{full_path}' in {execution_time:.2f}s") return { "message": "Query executed but returned no data/columns to export.", "file_path": full_path, "rows_exported": 0 } except snowflake.connector.errors.ProgrammingError as e: logger.error(f"SQL Error during export: {str(e)}") logger.error(f"Error Code: {getattr(e, 'errno', 'unknown')}") raise except Exception as e: logger.error(f"Error during CSV export: {str(e)}") logger.error(f"Error type: {type(e).__name__}") raise def close(self): """ Close database connection """ if self.conn: try: self.conn.close() logger.info("Connection closed") except Exception as e: logger.error(f"Error closing connection: {str(e)}") finally: self.conn = None class SnowflakeMCPServer(Server): """ Snowflake MCP server class, handles client interactions """ def __init__(self): super().__init__(name="snowflake-mcp-server") self.db = SnowflakeConnection() logger.info("SnowflakeMCPServer initialized") @self.list_tools() async def handle_tools(): """ Return list of available tools """ return [ Tool( name="execute_query", description="Execute a SQL query on Snowflake and return results directly.", inputSchema={ "type": "object", "properties": { "query": { "type": "string", "description": "SQL query to execute (SELECT, INSERT, UPDATE, etc.)." } }, "required": ["query"] } ), Tool( # Add the new tool definition name="export_query_to_csv", description=f"Execute a SELECT SQL query on Snowflake and export the results to a CSV file within the designated export directory ('{EXPORT_BASE_PATH}' on the server).", inputSchema={ "type": "object", "properties": { "query": { "type": "string", "description": "SELECT SQL query to execute." }, "relative_file_path": { "type": "string", "description": f"The relative path and filename for the CSV file (e.g., 'my_data.csv' or 'reports/quarterly.csv'). This will be saved relative to the server's base export path: {EXPORT_BASE_PATH}. Do not use '..' or start with '/'." } }, "required": ["query", "relative_file_path"] } ) ] @self.call_tool() async def handle_call_tool(name: str, arguments: dict): """ Handle tool call requests Args: name (str): Tool name arguments (dict): Tool arguments Returns: list[TextContent]: Execution results """ if name == "execute_query": start_time = time.time() try: result = self.db.execute_query(arguments["query"]) execution_time = time.time() - start_time return [TextContent( type="text", text=f"Results (execution time: {execution_time:.2f}s):\n{result}" )] except Exception as e: error_message = f"Error executing query: {str(e)}" logger.error(error_message) return [TextContent( type="text", text=error_message )] elif name == "export_query_to_csv": # Handle the new tool call start_time = time.time() try: query = arguments["query"] relative_path = arguments["relative_file_path"] result = self.db.export_to_csv(query, relative_path) execution_time = time.time() - start_time return [TextContent( type="text", text=f"Export successful (execution time: {execution_time:.2f}s):\n{json.dumps(result, indent=2)}" )] except (ValueError, FileNotFoundError) as e: # Catch specific configuration/path errors error_message = f"Error preparing export: {str(e)}" logger.error(error_message) return [TextContent(type="text", text=error_message)] except Exception as e: # Catch database or file writing errors error_message = f"Error exporting query to CSV: {str(e)}" logger.error(error_message) return [TextContent( type="text", text=error_message )] def __del__(self): """ Clean up resources, close database connection """ if hasattr(self, 'db'): self.db.close() async def main(): """ Main function, starts server and handles requests """ try: server = SnowflakeMCPServer() initialization_options = server.create_initialization_options() logger.info("Starting server") async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, initialization_options ) except Exception as e: logger.critical(f"Server failed: {str(e)}", exc_info=True) raise finally: logger.info("Server shutting down") if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------------------------------------------------------- /assets/communication_flow_sequence_bright.svg: -------------------------------------------------------------------------------- ``` <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="1104" height="540" viewBox="0 0 1104 540" style="fill:none;stroke:none;fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style class="text-font-style fontImports" data-font-family="Roboto">@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=block');</style><g id="items" style="isolation: isolate"><g id="blend" style="mix-blend-mode: normal"><g id="g-root-6.g-6_fr_zk2q541dgdgcp-fill" data-item-order="-557270" transform="translate(863, 74)"><g id="6.g-6_fr_zk2q541dgdgcp-fill" stroke="none" fill="#faf0ff"><g><path d="M 136.5037 52C 138.1093 48.3252 139 44.2666 139 40C 139 35.7334 138.1093 31.6748 136.5037 28L 157 28L 157 27C 157 25.8954 157.895 25 159 25L 163 25L 163 55L 159 55C 157.895 55 157 54.1046 157 53L 157 52L 136.5037 52ZM 81.4963 52L 61 52L 61 53C 61 54.1046 60.1046 55 59 55L 55 55L 55 25L 59 25C 60.1046 25 61 25.8954 61 27L 61 28L 81.4963 28C 79.8907 31.6748 79 35.7334 79 40C 79 44.2666 79.8907 48.3252 81.4963 52Z"></path></g></g><g id="6.g-6_fr_zk2q541dgdgcp-fill" stroke="none" fill="#faf0ff"><g><path d="M 10 130L 10 126C 10 124.8954 10.8954 124 12 124L 13 124L 13 76L 12 76C 10.8954 76 10.000002 75.1046 10.000002 74L 10.000003 70L 40 70.000001L 40 74C 40 75.1046 39.1046 76 38 76L 37 76L 37 124L 38 124C 39.1046 124 40 124.8954 40 126L 40 130L 10 130Z"></path></g></g><g id="6.g-6_fr_zk2q541dgdgcp-fill" stroke="none" fill="#faf0ff"><g><path d="M 13 52C 13 38.7452 23.7452 28 37 28L 49 28L 49 27C 49 25.8954 49.8954 25 51 25L 55 25L 55 55L 51 55C 49.8954 55 49 54.1046 49 53L 49 52L 41 52C 38.7909 52 37 53.7909 37 56L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 52Z"></path></g></g><g id="6.g-6_fr_zk2q541dgdgcp-fill" stroke="none" fill="#faf0ff"><g><path d="M 139 40C 139 56.5685 125.5685 70 109 70C 92.4315 70 79 56.5685 79 40C 79 23.4315 92.4315 10 109 10C 125.5685 10 139 23.4315 139 40Z"></path></g></g></g><g id="g-root-5.g-5_fr_v4980o1dgdh52-fill" data-item-order="-557266" transform="translate(695, 194)"><g id="5.g-5_fr_v4980o1dgdh52-fill" stroke="none" fill="#ffebf7"><g><path d="M 136.5037 112C 138.1093 108.3252 139 104.2666 139 100C 139 95.7334 138.1093 91.6748 136.5037 88L 157 88L 157 87C 157 85.8954 157.895 85 159 85L 163 85L 163 115L 159 115C 157.895 115 157 114.1046 157 113L 157 112L 136.5037 112ZM 81.4963 112L 61 112L 61 113C 61 114.1046 60.1046 115 59 115L 55 115L 55 85L 59 85C 60.1046 85 61 85.8954 61 87L 61 88L 81.4963 88C 79.8907 91.6748 79 95.7334 79 100C 79 104.2666 79.8907 108.3252 81.4963 112Z"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-fill" stroke="none" fill="#ffebf7"><g><path d="M 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 46L 12 46C 10.8954 46 10.000001 45.1046 10.000001 44L 10.000001 40L 40 40.000001L 40 44C 40 45.1046 39.1046 46 38 46L 37 46L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70Z"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-fill" stroke="none" fill="#ffebf7"><g><path d="M 178 70L 178 66C 178 64.8954 178.8954 64 180 64L 181 64L 181 16L 180 16C 178.8954 16 178.000002 15.1046 178.000002 14L 178.000003 10L 208 10.000001L 208 14C 208 15.1046 207.1046 16 206 16L 205 16L 205 64L 206 64C 207.1046 64 208 64.8954 208 66L 208 70L 178 70Z"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-fill" stroke="none" fill="#ffebf7"><g><path d="M 13 88C 13 101.2548 23.7452 112 37 112L 49 112L 49 113C 49 114.1046 49.8954 115 51 115L 55 115L 55 85L 51 85C 49.8954 85 49 85.8954 49 87L 49 88L 41 88C 38.7909 88 37 86.2091 37 84L 37 76L 38 76C 39.1046 76 40 75.1046 40 74L 40 70L 10 70.000005L 10.000001 74C 10.000001 75.1046 10.8954 76 12 76L 13 76L 13 88Z"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-fill" stroke="none" fill="#ffebf7"><g><path d="M 205 88C 205 101.2548 194.2548 112 181 112L 169 112L 169 113C 169 114.1046 168.1046 115 167 115L 163 115L 163.000007 85L 167 85C 168.1046 85 169 85.8954 169 87L 169 88L 177 88C 179.2091 88 181 86.2091 181 84L 181 76L 180 76C 178.8954 76 178 75.1046 178 74L 178 70L 208 70.000005L 208 74C 208 75.1046 207.1046 76 206 76L 205 76L 205 88Z"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-fill" stroke="none" fill="#ffebf7"><g><path d="M 139 100C 139 116.5685 125.5685 130 109 130C 92.4315 130 79 116.5685 79 100C 79 83.4315 92.4315 70 109 70C 125.5685 70 139 83.4315 139 100Z"></path></g></g></g><g id="g-root-4.g-4_fr_htf6qg1dgdfkd-fill" data-item-order="-557262" transform="translate(527, 134)"><g id="4.g-4_fr_htf6qg1dgdfkd-fill" stroke="none" fill="#e8f9ff"><g><path d="M 136.5037 52C 138.1093 48.3252 139 44.2666 139 40C 139 35.7334 138.1093 31.6748 136.5037 28L 157 28L 157 27C 157 25.8954 157.895 25 159 25L 163 25L 163 55L 159 55C 157.895 55 157 54.1046 157 53L 157 52L 136.5037 52ZM 81.4963 52L 61 52L 61 53C 61 54.1046 60.1046 55 59 55L 55 55L 55 25L 59 25C 60.1046 25 61 25.8954 61 27L 61 28L 81.4963 28C 79.8907 31.6748 79 35.7334 79 40C 79 44.2666 79.8907 48.3252 81.4963 52Z"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-fill" stroke="none" fill="#e8f9ff"><g><path d="M 178 100L 178 96C 178 94.8954 178.8954 94 180 94L 181 94L 181 76L 180 76C 178.8954 76 178.000001 75.1046 178.000001 74L 178.000001 70L 208 70.000001L 208 74C 208 75.1046 207.1046 76 206 76L 205 76L 205 94L 206 94C 207.1046 94 208 94.8954 208 96L 208 100L 178 100Z"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-fill" stroke="none" fill="#e8f9ff"><g><path d="M 13 52C 13 38.7452 23.7452 28 37 28L 49 28L 49 27C 49 25.8954 49.8954 25 51 25L 55 25L 55 55L 51 55C 49.8954 55 49 54.1046 49 53L 49 52L 41 52C 38.7909 52 37 53.7909 37 56L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 52Z"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-fill" stroke="none" fill="#e8f9ff"><g><path d="M 205 52C 205 38.7452 194.2548 28 181 28L 169 28L 169 27C 169 25.8954 168.1046 25 167 25L 163 25L 163.000001 55L 167 55C 168.1046 55 169 54.1046 169 53L 169 52L 177 52C 179.2091 52 181 53.7909 181 56L 181 64L 180 64C 178.8954 64 178 64.8954 178 66L 178 70L 208 70L 208 66C 208 64.8954 207.1046 64 206 64L 205 64L 205 52Z"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-fill" stroke="none" fill="#e8f9ff"><g><path d="M 139 40C 139 56.5685 125.5685 70 109 70C 92.4315 70 79 56.5685 79 40C 79 23.4315 92.4315 10 109 10C 125.5685 10 139 23.4315 139 40Z"></path></g></g></g><g id="g-root-3.g-3_fr_8xs6hk1dgdh4z-fill" data-item-order="-557258" transform="translate(359, 164)"><g id="3.g-3_fr_8xs6hk1dgdh4z-fill" stroke="none" fill="#f4ffdc"><g><path d="M 136.5037 82C 138.1093 78.3252 139 74.2666 139 70C 139 65.7334 138.1093 61.6748 136.5037 58L 157 58L 157 57C 157 55.8954 157.895 55 159 55L 163 55L 163 85L 159 85C 157.895 85 157 84.1046 157 83L 157 82L 136.5037 82ZM 81.4963 82L 61 82L 61 83C 61 84.1046 60.1046 85 59 85L 55 85L 55 55L 59 55C 60.1046 55 61 55.8954 61 57L 61 58L 81.4963 58C 79.8907 61.6748 79 65.7334 79 70C 79 74.2666 79.8907 78.3252 81.4963 82Z"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-fill" stroke="none" fill="#f4ffdc"><g><path d="M 10 40L 10 36C 10 34.8954 10.8954 34 12 34L 13 34L 13 16L 12 16C 10.8954 16 10.000001 15.1046 10.000001 14L 10.000001 10L 40 10.000001L 40 14C 40 15.1046 39.1046 16 38 16L 37 16L 37 34L 38 34C 39.1046 34 40 34.8954 40 36L 40 40L 10 40Z"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-fill" stroke="none" fill="#f4ffdc"><g><path d="M 205 58C 205 71.2548 194.2548 82 181 82L 169 82L 169 83C 169 84.1046 168.1046 85 167 85L 163 85L 163.000007 55L 167 55C 168.1046 55 169 55.8954 169 57L 169 58L 177 58C 179.2091 58 181 56.2091 181 54L 181 46L 180 46C 178.8954 46 178 45.1046 178 44L 178 40L 208 40.000005L 208 44C 208 45.1046 207.1046 46 206 46L 205 46L 205 58Z"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-fill" stroke="none" fill="#f4ffdc"><g><path d="M 13 58C 13 71.2548 23.7452 82 37 82L 49 82L 49 83C 49 84.1046 49.8954 85 51 85L 55 85L 55 55L 51 55C 49.8954 55 49 55.8954 49 57L 49 58L 41 58C 38.7909 58 37 56.2091 37 54L 37 46L 38 46C 39.1046 46 40 45.1046 40 44L 40 40L 10 40.000005L 10.000001 44C 10.000001 45.1046 10.8954 46 12 46L 13 46L 13 58Z"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-fill" stroke="none" fill="#f4ffdc"><g><path d="M 139 70C 139 86.5685 125.5685 100 109 100C 92.4315 100 79 86.5685 79 70C 79 53.4315 92.4315 40 109 40C 125.5685 40 139 53.4315 139 70Z"></path></g></g></g><g id="g-root-2.g-2_fr_4il5g81dgderl-fill" data-item-order="-557254" transform="translate(191, 74)"><g id="2.g-2_fr_4il5g81dgderl-fill" stroke="none" fill="#e3fff2"><g><path d="M 136.5037 52C 138.1093 48.3252 139 44.2666 139 40C 139 35.7334 138.1093 31.6748 136.5037 28L 157 28L 157 27C 157 25.8954 157.895 25 159 25L 163 25L 163 55L 159 55C 157.895 55 157 54.1046 157 53L 157 52L 136.5037 52ZM 81.4963 52L 61 52L 61 53C 61 54.1046 60.1046 55 59 55L 55 55L 55 25L 59 25C 60.1046 25 61 25.8954 61 27L 61 28L 81.4963 28C 79.8907 31.6748 79 35.7334 79 40C 79 44.2666 79.8907 48.3252 81.4963 52Z"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-fill" stroke="none" fill="#e3fff2"><g><path d="M 178 100L 178 96C 178 94.8954 178.8954 94 180 94L 181 94L 181 76L 180 76C 178.8954 76 178.000001 75.1046 178.000001 74L 178.000001 70L 208 70.000001L 208 74C 208 75.1046 207.1046 76 206 76L 205 76L 205 94L 206 94C 207.1046 94 208 94.8954 208 96L 208 100L 178 100Z"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-fill" stroke="none" fill="#e3fff2"><g><path d="M 10 130L 10 126C 10 124.8954 10.8954 124 12 124L 13 124L 13 76L 12 76C 10.8954 76 10.000002 75.1046 10.000002 74L 10.000003 70L 40 70.000001L 40 74C 40 75.1046 39.1046 76 38 76L 37 76L 37 124L 38 124C 39.1046 124 40 124.8954 40 126L 40 130L 10 130Z"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-fill" stroke="none" fill="#e3fff2"><g><path d="M 205 52C 205 38.7452 194.2548 28 181 28L 169 28L 169 27C 169 25.8954 168.1046 25 167 25L 163 25L 163.000001 55L 167 55C 168.1046 55 169 54.1046 169 53L 169 52L 177 52C 179.2091 52 181 53.7909 181 56L 181 64L 180 64C 178.8954 64 178 64.8954 178 66L 178 70L 208 70L 208 66C 208 64.8954 207.1046 64 206 64L 205 64L 205 52Z"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-fill" stroke="none" fill="#e3fff2"><g><path d="M 13 52C 13 38.7452 23.7452 28 37 28L 49 28L 49 27C 49 25.8954 49.8954 25 51 25L 55 25L 55 55L 51 55C 49.8954 55 49 54.1046 49 53L 49 52L 41 52C 38.7909 52 37 53.7909 37 56L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 52Z"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-fill" stroke="none" fill="#e3fff2"><g><path d="M 139 40C 139 56.5685 125.5685 70 109 70C 92.4315 70 79 56.5685 79 40C 79 23.4315 92.4315 10 109 10C 125.5685 10 139 23.4315 139 40Z"></path></g></g></g><g id="g-root-1.g-1_fr_1q88p201dgdg5k-fill" data-item-order="-557250" transform="translate(68, 194)"><g id="1.g-1_fr_1q88p201dgdg5k-fill" stroke="none" fill="#edf4ff"><g><path d="M 133 69.999999L 133 65.999999C 133 64.895399 133.8954 63.999999 135 63.999999L 136 63.999999L 136 15.999999L 135 15.999999C 133.8954 15.999999 133.000002 15.104599 133.000002 13.999999L 133.000003 9.999999L 163 10L 163 13.999999C 163 15.104599 162.1046 15.999999 161 15.999999L 160 15.999999L 160 63.999999L 161 63.999999C 162.1046 63.999999 163 64.895399 163 65.999999L 163 69.999999L 133 69.999999Z"></path></g></g><g id="1.g-1_fr_1q88p201dgdg5k-fill" stroke="none" fill="#edf4ff"><g><path d="M 91.5037 112C 93.1093 108.3252 94 104.2666 94 100C 94 95.7334 93.1093 91.6748 91.5037 88L 112 88L 112 87C 112 85.8954 112.895 85 114 85L 118 85L 118 115L 114 115C 112.895 115 112 114.1046 112 113L 112 112L 91.5037 112ZM 36.4963 112L 16 112L 16 113C 16 114.1046 15.1046 115 14 115L 10 115L 10 85L 14 85C 15.1046 85 16 85.8954 16 87L 16 88L 36.4963 88C 34.8907 91.6748 34 95.7334 34 100C 34 104.2666 34.8907 108.3252 36.4963 112Z"></path></g></g><g id="1.g-1_fr_1q88p201dgdg5k-fill" stroke="none" fill="#edf4ff"><g><path d="M 160 88.000004C 160 101.254804 149.2548 112.000004 136 112.000004L 124 112.000004L 124 113.000004C 124 114.104604 123.1046 115.000004 122 115.000004L 118 115.000004L 118.000007 85.000004L 122 85.000004C 123.1046 85.000004 124 85.895404 124 87.000004L 124 88.000004L 132 88.000004C 134.2091 88.000004 136 86.209104 136 84.000004L 136 76.000004L 135 76.000004C 133.8954 76.000004 133 75.104604 133 74.000004L 133 70.000004L 163 70.000009L 163 74.000004C 163 75.104604 162.1046 76.000004 161 76.000004L 160 76.000004L 160 88.000004Z"></path></g></g><g id="1.g-1_fr_1q88p201dgdg5k-fill" stroke="none" fill="#edf4ff"><g><path d="M 94 100C 94 116.5685 80.5685 130 64 130C 47.4315 130 34 116.5685 34 100C 34 83.4315 47.4315 70 64 70C 80.5685 70 94 83.4315 94 100Z"></path></g></g></g><g id="g-root-bloc_i093a01dq8utj-fill" data-item-order="0" transform="translate(608, 146)"></g><g id="g-root-mail_zly5eg1dgdg5q-fill" data-item-order="0" transform="translate(944, 86)"></g><g id="g-root-warn_m97dg81dqa9s1-fill" data-item-order="0" transform="translate(272, 86)"></g><g id="g-root-1_1lz93h41dq8veo-fill" data-item-order="0" transform="translate(440, 206)"></g><g id="g-root-tx_communic_1cws6oo1dgdhql-fill" data-item-order="0" transform="translate(398, 2)"><g id="tx_communic_1cws6oo1dgdhql-fill" stroke="none" fill="#484848"><g><text style="font: 20px Roboto, sans-serif; white-space: pre;" font-size="20px" font-family="Roboto, sans-serif"><tspan x="13.24" y="34" dominant-baseline="ideographic">Communication Flow Sequence</tspan></text></g></g></g><g id="g-root-smar_zisgk81dqbmkq-fill" data-item-order="0" transform="translate(104, 266)"></g><g id="g-root-48px_i093a01dqbll9-fill" data-item-order="0" transform="translate(104, 326)"></g><g id="g-root-48px_1q6bye01dqd24o-fill" data-item-order="0" transform="translate(272, 326)"></g><g id="g-root-48px_1cwqva01dqd2pv-fill" data-item-order="0" transform="translate(440, 326)"></g><g id="g-root-48px_qs59081dqd0xy-fill" data-item-order="0" transform="translate(608, 326)"></g><g id="g-root-48px_144upjs1dqd1j5-fill" data-item-order="0" transform="translate(776, 326)"></g><g id="g-root-48px_4oskwo1dqd1c4-fill" data-item-order="0" transform="translate(944.5, 326)"></g><g id="g-root-tx_mcpclien_18mjmxk1dqbll7-fill" data-item-order="0" transform="translate(50, 374)"><g id="tx_mcpclien_18mjmxk1dqbll7-fill" stroke="none" fill="#4e88e7"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="25.53" y="34" dominant-baseline="ideographic">MCP Client </tspan><tspan x="12.47" y="58" dominant-baseline="ideographic">sends request</tspan></text></g></g></g><g id="g-root-tx_mcpserve_v2yyfs1dqd0qu-fill" data-item-order="0" transform="translate(218, 374)"><g id="tx_mcpserve_v2yyfs1dqd0qu-fill" stroke="none" fill="#3cc583"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="22.4" y="34" dominant-baseline="ideographic">MCP Server </tspan><tspan x="14.54" y="58" dominant-baseline="ideographic">authenticates</tspan></text></g></g></g><g id="g-root-tx_mcpserve_4hxcyg1dqd2wx-fill" data-item-order="0" transform="translate(386, 374)"><g id="tx_mcpserve_4hxcyg1dqd2wx-fill" stroke="none" fill="#92bd39"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="22.4" y="34" dominant-baseline="ideographic">MCP Server </tspan><tspan x="14.52" y="58" dominant-baseline="ideographic">executes SQL</tspan></text></g></g></g><g id="g-root-tx_snowflak_1hefsns1dqd0xw-fill" data-item-order="0" transform="translate(554, 374)"><g id="tx_snowflak_1hefsns1dqd0xw-fill" stroke="none" fill="#1eabda"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="35.13" y="34" dominant-baseline="ideographic">Snowflake </tspan><tspan x="16.28" y="58" dominant-baseline="ideographic">returns results</tspan></text></g></g></g><g id="g-root-tx_mcpserve_1qbbr2w1dqd1jj-fill" data-item-order="0" transform="translate(722, 374)"><g id="tx_mcpserve_1qbbr2w1dqd1jj-fill" stroke="none" fill="#de58a9"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="28.39" y="34" dominant-baseline="ideographic">MCP Server </tspan><tspan x="13.22" y="58" dominant-baseline="ideographic">formats results</tspan></text></g></g></g><g id="g-root-tx_mcpserve_zqwmoo1dqd0ju-fill" data-item-order="0" transform="translate(890, 374)"><g id="tx_mcpserve_zqwmoo1dqd0ju-fill" stroke="none" fill="#ba5de5"><g><text style="font: bold 20px Roboto, sans-serif; white-space: pre;" font-weight="bold" font-size="20px" font-family="Roboto, sans-serif"><tspan x="22.4" y="34" dominant-baseline="ideographic">MCP Server </tspan><tspan x="15.73" y="58" dominant-baseline="ideographic">sends results</tspan></text></g></g></g><g id="g-root-tx_theclien_vb34k81dqbn64-fill" data-item-order="0" transform="translate(50, 434)"><g id="tx_theclien_vb34k81dqbn64-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="13.58" y="31" dominant-baseline="ideographic">The client initiates a </tspan><tspan x="34.33" y="49" dominant-baseline="ideographic">request to the </tspan><tspan x="58.33" y="67" dominant-baseline="ideographic">server.</tspan></text></g></g></g><g id="g-root-tx_theserve_hrig2g1dqd2br-fill" data-item-order="0" transform="translate(218, 434)"><g id="tx_theserve_hrig2g1dqd2br-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="13.34" y="31" dominant-baseline="ideographic">The server verifies </tspan><tspan x="21.45" y="49" dominant-baseline="ideographic">credentials with </tspan><tspan x="37.6" y="67" dominant-baseline="ideographic">Snowflake.</tspan></text></g></g></g><g id="g-root-tx_theserve_1q87dnc1dqd14y-fill" data-item-order="0" transform="translate(386, 434)"><g id="tx_theserve_1q87dnc1dqd14y-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="13.46" y="31" dominant-baseline="ideographic">The server runs SQL </tspan><tspan x="45.66" y="49" dominant-baseline="ideographic">queries on </tspan><tspan x="44.01" y="67" dominant-baseline="ideographic">Snowflake.</tspan></text></g></g></g><g id="g-root-tx_snowflak_18issew1dqd1ql-fill" data-item-order="0" transform="translate(554, 434)"><g id="tx_snowflak_18issew1dqd1ql-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="12.03" y="28" dominant-baseline="ideographic">Snowflake sends the </tspan><tspan x="18.11" y="46" dominant-baseline="ideographic">query results back.</tspan></text></g></g></g><g id="g-root-tx_theserve_18ko7o81dqd0qw-fill" data-item-order="0" transform="translate(722, 434)"><g id="tx_theserve_18ko7o81dqd0qw-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="13.99" y="31" dominant-baseline="ideographic">The server prepares </tspan><tspan x="29.15" y="49" dominant-baseline="ideographic">the data for the </tspan><tspan x="60.01" y="67" dominant-baseline="ideographic">client.</tspan></text></g></g></g><g id="g-root-tx_theserve_mfg4bc1dqd24r-fill" data-item-order="0" transform="translate(890, 434)"><g id="tx_theserve_mfg4bc1dqd24r-fill" stroke="none" fill="#484848"><g><text style="font: 15px Roboto, sans-serif; white-space: pre;" font-size="15px" font-family="Roboto, sans-serif"><tspan x="18.85" y="31" dominant-baseline="ideographic">The server delivers </tspan><tspan x="35.93" y="49" dominant-baseline="ideographic">the formatted </tspan><tspan x="16.02" y="67" dominant-baseline="ideographic">results to the client.</tspan></text></g></g></g><g id="g-root-6.g-6_fr_zk2q541dgdgcp-stroke" data-item-order="-557270" transform="translate(863, 74)"><g id="6.g-6_fr_zk2q541dgdgcp-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ba5de5" stroke-width="2"><g><path d="M 136.5037 52C 138.1093 48.3252 139 44.2666 139 40C 139 35.7334 138.1093 31.6748 136.5037 28L 157 28L 157 27C 157 25.8954 157.8954 25 159 25L 163 25L 163 55L 159 55C 157.8954 55 157 54.1046 157 53L 157 52L 136.5037 52ZM 81.4963 52L 61 52L 61 53C 61 54.1046 60.1046 55 59 55L 55 55L 55 25L 59 25C 60.1046 25 61 25.8954 61 27L 61 28L 81.4963 28C 79.8907 31.6748 79 35.7334 79 40C 79 44.2666 79.8907 48.3252 81.4963 52ZM 157 28L 157 52M 61 52L 61 28"></path></g></g><g id="6.g-6_fr_zk2q541dgdgcp-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ba5de5" stroke-width="2"><g><path d="M 10 130L 10 126C 10 124.8954 10.8954 124 12 124L 13 124L 13 76L 12 76C 10.8954 76 10 75.1046 10 74L 10 70L 40 70L 40 74C 40 75.1046 39.1046 76 38 76L 37 76L 37 124L 38 124C 39.1046 124 40 124.8954 40 126L 40 130L 10 130ZM 13 124L 37 124M 13 76L 37 76"></path></g></g><g id="6.g-6_fr_zk2q541dgdgcp-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ba5de5" stroke-width="2"><g><path d="M 13 52C 13 38.7452 23.7452 28 37 28L 49 28L 49 27C 49 25.8954 49.8954 25 51 25L 55 25L 55 55L 51 55C 49.8954 55 49 54.1046 49 53L 49 52L 41 52C 38.7909 52 37 53.7909 37 56L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 52ZM 49 28L 49 52M 37 64L 13 64"></path></g></g><g id="6.g-6_fr_zk2q541dgdgcp-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ba5de5" stroke-width="2"><g><path d="M 139 40C 139 56.5685 125.5685 70 109 70C 92.4315 70 79 56.5685 79 40C 79 23.4315 92.4315 10 109 10C 125.5685 10 139 23.4315 139 40Z"></path></g></g></g><g id="g-root-5.g-5_fr_v4980o1dgdh52-stroke" data-item-order="-557266" transform="translate(695, 194)"><g id="5.g-5_fr_v4980o1dgdh52-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#de58a9" stroke-width="2"><g><path d="M 136.5037 112C 138.1093 108.3252 139 104.2666 139 100C 139 95.7334 138.1093 91.6748 136.5037 88L 157 88L 157 87C 157 85.8954 157.8954 85 159 85L 163 85L 163 115L 159 115C 157.8954 115 157 114.1046 157 113L 157 112L 136.5037 112ZM 81.4963 112L 61 112L 61 113C 61 114.1046 60.1046 115 59 115L 55 115L 55 85L 59 85C 60.1046 85 61 85.8954 61 87L 61 88L 81.4963 88C 79.8907 91.6748 79 95.7334 79 100C 79 104.2666 79.8907 108.3252 81.4963 112ZM 157 88L 157 112M 61 112L 61 88"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#de58a9" stroke-width="2"><g><path d="M 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 46L 12 46C 10.8954 46 10 45.1046 10 44L 10 40L 40 40L 40 44C 40 45.1046 39.1046 46 38 46L 37 46L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70ZM 13 64L 37 64M 13 46L 37 46"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#de58a9" stroke-width="2"><g><path d="M 178 70L 178 66C 178 64.8954 178.8954 64 180 64L 181 64L 181 16L 180 16C 178.8954 16 178 15.1046 178 14L 178 10L 208 10L 208 14C 208 15.1046 207.1046 16 206 16L 205 16L 205 64L 206 64C 207.1046 64 208 64.8954 208 66L 208 70L 178 70ZM 181 64L 205 64M 181 16L 205 16"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#de58a9" stroke-width="2"><g><path d="M 13 88C 13 101.2548 23.7452 112 37 112L 49 112L 49 113C 49 114.1046 49.8954 115 51 115L 55 115L 55 85L 51 85C 49.8954 85 49 85.8954 49 87L 49 88L 41 88C 38.7909 88 37 86.2091 37 84L 37 76L 38 76C 39.1046 76 40 75.1046 40 74L 40 70L 10 70L 10.000001 74C 10.000001 75.1046 10.8954 76 12 76L 13 76L 13 88ZM 49 112L 49 88M 37 76L 13 76"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#de58a9" stroke-width="2"><g><path d="M 205 88C 205 101.2548 194.2548 112 181 112L 169 112L 169 113C 169 114.1046 168.1046 115 167 115L 163 115L 163 85L 167 85C 168.1046 85 169 85.8954 169 87L 169 88L 177 88C 179.2091 88 181 86.2091 181 84L 181 76L 180 76C 178.8954 76 178 75.1046 178 74L 178 70L 208 70L 208 74C 208 75.1046 207.1046 76 206 76L 205 76L 205 88ZM 169 112L 169 88M 181 76L 205 76"></path></g></g><g id="5.g-5_fr_v4980o1dgdh52-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#de58a9" stroke-width="2"><g><path d="M 139 100C 139 116.5685 125.5685 130 109 130C 92.4315 130 79 116.5685 79 100C 79 83.4315 92.4315 70 109 70C 125.5685 70 139 83.4315 139 100Z"></path></g></g></g><g id="g-root-4.g-4_fr_htf6qg1dgdfkd-stroke" data-item-order="-557262" transform="translate(527, 134)"><g id="4.g-4_fr_htf6qg1dgdfkd-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 136.5037 52C 138.1093 48.3252 139 44.2666 139 40C 139 35.7334 138.1093 31.6748 136.5037 28L 157 28L 157 27C 157 25.8954 157.8954 25 159 25L 163 25L 163 55L 159 55C 157.8954 55 157 54.1046 157 53L 157 52L 136.5037 52ZM 81.4963 52L 61 52L 61 53C 61 54.1046 60.1046 55 59 55L 55 55L 55 25L 59 25C 60.1046 25 61 25.8954 61 27L 61 28L 81.4963 28C 79.8907 31.6748 79 35.7334 79 40C 79 44.2666 79.8907 48.3252 81.4963 52ZM 157 28L 157 52M 61 52L 61 28"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 178 100L 178 96C 178 94.8954 178.8954 94 180 94L 181 94L 181 76L 180 76C 178.8954 76 178 75.1046 178 74L 178 70L 208 70L 208 74C 208 75.1046 207.1046 76 206 76L 205 76L 205 94L 206 94C 207.1046 94 208 94.8954 208 96L 208 100L 178 100ZM 181 94L 205 94M 181 76L 205 76"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 13 52C 13 38.7452 23.7452 28 37 28L 49 28L 49 27C 49 25.8954 49.8954 25 51 25L 55 25L 55 55L 51 55C 49.8954 55 49 54.1046 49 53L 49 52L 41 52C 38.7909 52 37 53.7909 37 56L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 52ZM 49 28L 49 52M 37 64L 13 64"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 205 52C 205 38.7452 194.2548 28 181 28L 169 28L 169 27C 169 25.8954 168.1046 25 167 25L 163 25L 163 55L 167 55C 168.1046 55 169 54.1046 169 53L 169 52L 177 52C 179.2091 52 181 53.7909 181 56L 181 64L 180 64C 178.8954 64 178 64.8954 178 66L 178 70L 208 70L 208 66C 208 64.8954 207.1046 64 206 64L 205 64L 205 52ZM 169 28L 169 52M 181 64L 205 64"></path></g></g><g id="4.g-4_fr_htf6qg1dgdfkd-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 139 40C 139 56.5685 125.5685 70 109 70C 92.4315 70 79 56.5685 79 40C 79 23.4315 92.4315 10 109 10C 125.5685 10 139 23.4315 139 40Z"></path></g></g></g><g id="g-root-3.g-3_fr_8xs6hk1dgdh4z-stroke" data-item-order="-557258" transform="translate(359, 164)"><g id="3.g-3_fr_8xs6hk1dgdh4z-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 136.5037 82C 138.1093 78.3252 139 74.2666 139 70C 139 65.7334 138.1093 61.6748 136.5037 58L 157 58L 157 57C 157 55.8954 157.8954 55 159 55L 163 55L 163 85L 159 85C 157.8954 85 157 84.1046 157 83L 157 82L 136.5037 82ZM 81.4963 82L 61 82L 61 83C 61 84.1046 60.1046 85 59 85L 55 85L 55 55L 59 55C 60.1046 55 61 55.8954 61 57L 61 58L 81.4963 58C 79.8907 61.6748 79 65.7334 79 70C 79 74.2666 79.8907 78.3252 81.4963 82ZM 157 58L 157 82M 61 82L 61 58"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 10 40L 10 36C 10 34.8954 10.8954 34 12 34L 13 34L 13 16L 12 16C 10.8954 16 10 15.1046 10 14L 10 10L 40 10L 40 14C 40 15.1046 39.1046 16 38 16L 37 16L 37 34L 38 34C 39.1046 34 40 34.8954 40 36L 40 40L 10 40ZM 13 34L 37 34M 13 16L 37 16"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 205 58C 205 71.2548 194.2548 82 181 82L 169 82L 169 83C 169 84.1046 168.1046 85 167 85L 163 85L 163 55L 167 55C 168.1046 55 169 55.8954 169 57L 169 58L 177 58C 179.2091 58 181 56.2091 181 54L 181 46L 180 46C 178.8954 46 178 45.1046 178 44L 178 40L 208 40L 208 44C 208 45.1046 207.1046 46 206 46L 205 46L 205 58ZM 169 82L 169 58M 181 46L 205 46"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 13 58C 13 71.2548 23.7452 82 37 82L 49 82L 49 83C 49 84.1046 49.8954 85 51 85L 55 85L 55 55L 51 55C 49.8954 55 49 55.8954 49 57L 49 58L 41 58C 38.7909 58 37 56.2091 37 54L 37 46L 38 46C 39.1046 46 40 45.1046 40 44L 40 40L 10 40L 10.000001 44C 10.000001 45.1046 10.8954 46 12 46L 13 46L 13 58ZM 49 82L 49 58M 37 46L 13 46"></path></g></g><g id="3.g-3_fr_8xs6hk1dgdh4z-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 139 70C 139 86.5685 125.5685 100 109 100C 92.4315 100 79 86.5685 79 70C 79 53.4315 92.4315 40 109 40C 125.5685 40 139 53.4315 139 70Z"></path></g></g></g><g id="g-root-2.g-2_fr_4il5g81dgderl-stroke" data-item-order="-557254" transform="translate(191, 74)"><g id="2.g-2_fr_4il5g81dgderl-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 136.5037 52C 138.1093 48.3252 139 44.2666 139 40C 139 35.7334 138.1093 31.6748 136.5037 28L 157 28L 157 27C 157 25.8954 157.8954 25 159 25L 163 25L 163 55L 159 55C 157.8954 55 157 54.1046 157 53L 157 52L 136.5037 52ZM 81.4963 52L 61 52L 61 53C 61 54.1046 60.1046 55 59 55L 55 55L 55 25L 59 25C 60.1046 25 61 25.8954 61 27L 61 28L 81.4963 28C 79.8907 31.6748 79 35.7334 79 40C 79 44.2666 79.8907 48.3252 81.4963 52ZM 157 28L 157 52M 61 52L 61 28"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 178 100L 178 96C 178 94.8954 178.8954 94 180 94L 181 94L 181 76L 180 76C 178.8954 76 178 75.1046 178 74L 178 70L 208 70L 208 74C 208 75.1046 207.1046 76 206 76L 205 76L 205 94L 206 94C 207.1046 94 208 94.8954 208 96L 208 100L 178 100ZM 181 94L 205 94M 181 76L 205 76"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 10 130L 10 126C 10 124.8954 10.8954 124 12 124L 13 124L 13 76L 12 76C 10.8954 76 10 75.1046 10 74L 10 70L 40 70L 40 74C 40 75.1046 39.1046 76 38 76L 37 76L 37 124L 38 124C 39.1046 124 40 124.8954 40 126L 40 130L 10 130ZM 13 124L 37 124M 13 76L 37 76"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 205 52C 205 38.7452 194.2548 28 181 28L 169 28L 169 27C 169 25.8954 168.1046 25 167 25L 163 25L 163 55L 167 55C 168.1046 55 169 54.1046 169 53L 169 52L 177 52C 179.2091 52 181 53.7909 181 56L 181 64L 180 64C 178.8954 64 178 64.8954 178 66L 178 70L 208 70L 208 66C 208 64.8954 207.1046 64 206 64L 205 64L 205 52ZM 169 28L 169 52M 181 64L 205 64"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 13 52C 13 38.7452 23.7452 28 37 28L 49 28L 49 27C 49 25.8954 49.8954 25 51 25L 55 25L 55 55L 51 55C 49.8954 55 49 54.1046 49 53L 49 52L 41 52C 38.7909 52 37 53.7909 37 56L 37 64L 38 64C 39.1046 64 40 64.8954 40 66L 40 70L 10 70L 10 66C 10 64.8954 10.8954 64 12 64L 13 64L 13 52ZM 49 28L 49 52M 37 64L 13 64"></path></g></g><g id="2.g-2_fr_4il5g81dgderl-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 139 40C 139 56.5685 125.5685 70 109 70C 92.4315 70 79 56.5685 79 40C 79 23.4315 92.4315 10 109 10C 125.5685 10 139 23.4315 139 40Z"></path></g></g></g><g id="g-root-1.g-1_fr_1q88p201dgdg5k-stroke" data-item-order="-557250" transform="translate(68, 194)"><g id="1.g-1_fr_1q88p201dgdg5k-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#4e88e7" stroke-width="2"><g><path d="M 133 69.999999L 133 65.999999C 133 64.895399 133.8954 63.999999 135 63.999999L 136 63.999999L 136 15.999999L 135 15.999999C 133.8954 15.999999 133 15.104599 133 13.999999L 133 9.999999L 163 9.999999L 163 13.999999C 163 15.104599 162.1046 15.999999 161 15.999999L 160 15.999999L 160 63.999999L 161 63.999999C 162.1046 63.999999 163 64.895399 163 65.999999L 163 69.999999L 133 69.999999ZM 136 63.999999L 160 63.999999M 136 15.999999L 160 15.999999"></path></g></g><g id="1.g-1_fr_1q88p201dgdg5k-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#4e88e7" stroke-width="2"><g><path d="M 91.5037 112C 93.1093 108.3252 94 104.2666 94 100C 94 95.7334 93.1093 91.6748 91.5037 88L 112 88L 112 87C 112 85.8954 112.8954 85 114 85L 118 85L 118 115L 114 115C 112.8954 115 112 114.1046 112 113L 112 112L 91.5037 112ZM 36.4963 112L 16 112L 16 113C 16 114.1046 15.1046 115 14 115L 10 115L 10 85L 14 85C 15.1046 85 16 85.8954 16 87L 16 88L 36.4963 88C 34.8907 91.6748 34 95.7334 34 100C 34 104.2666 34.8907 108.3252 36.4963 112ZM 112 88L 112 112M 16 112L 16 88"></path></g></g><g id="1.g-1_fr_1q88p201dgdg5k-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#4e88e7" stroke-width="2"><g><path d="M 160 88.000004C 160 101.254804 149.2548 112.000004 136 112.000004L 124 112.000004L 124 113.000004C 124 114.104604 123.1046 115.000004 122 115.000004L 118 115.000004L 118 85.000004L 122 85.000004C 123.1046 85.000004 124 85.895404 124 87.000004L 124 88.000004L 132 88.000004C 134.2091 88.000004 136 86.209104 136 84.000004L 136 76.000004L 135 76.000004C 133.8954 76.000004 133 75.104604 133 74.000004L 133 70.000004L 163 70.000004L 163 74.000004C 163 75.104604 162.1046 76.000004 161 76.000004L 160 76.000004L 160 88.000004ZM 124 112.000004L 124 88.000004M 136 76.000004L 160 76.000004"></path></g></g><g id="1.g-1_fr_1q88p201dgdg5k-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#4e88e7" stroke-width="2"><g><path d="M 94 100C 94 116.5685 80.5685 130 64 130C 47.4315 130 34 116.5685 34 100C 34 83.4315 47.4315 70 64 70C 80.5685 70 94 83.4315 94 100Z"></path></g></g></g><g id="g-root-bloc_i093a01dq8utj-stroke" data-item-order="0" transform="translate(608, 146)"><g id="bloc_i093a01dq8utj-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#1eabda" stroke-width="2"><g><path d="M 25.7995 13.3255C 25.7995 14.540803 26.784698 15.526 28 15.526C 29.215302 15.526 30.2005 14.540803 30.2005 13.3255C 30.2005 12.110197 29.215302 11.125 28 11.125C 26.784698 11.125 25.7995 12.110197 25.7995 13.3255M 25.801001 42.6745C 25.801001 43.889805 26.786198 44.875 28.001501 44.875C 29.216803 44.875 30.202 43.889805 30.202 42.6745C 30.202 41.459198 29.216803 40.473999 28.001501 40.473999C 26.786198 40.473999 25.801001 41.459198 25.801001 42.6745M 37.536999 35.341C 37.536999 36.556305 38.522198 37.5415 39.737503 37.5415C 40.952805 37.5415 41.938 36.556305 41.938 35.341003C 41.938 34.125698 40.952805 33.140499 39.737503 33.140499C 38.522198 33.140499 37.536999 34.125698 37.536999 35.341003M 14.062 35.341C 14.062 36.556305 15.047197 37.5415 16.262501 37.5415C 17.477802 37.5415 18.463001 36.556305 18.463001 35.341003C 18.463001 34.125698 17.477802 33.140499 16.262501 33.140499C 15.047197 33.140499 14.062 34.125698 14.062 35.341003M 37.536999 20.6635C 37.536999 21.878803 38.522198 22.864 39.737503 22.864C 40.952805 22.864 41.938 21.878803 41.938 20.6635C 41.938 19.448198 40.952805 18.463001 39.737503 18.463001C 38.522198 18.463001 37.536999 19.448198 37.536999 20.6635M 14.062 20.6635C 14.062 21.878803 15.047197 22.864 16.262501 22.864C 17.477802 22.864 18.463001 21.878803 18.463001 20.6635C 18.463001 19.448198 17.477802 18.463001 16.262501 18.463001C 15.047197 18.463001 14.062 19.448198 14.062 20.6635M 25.066 28C 25.066 29.620403 26.379597 30.934 28 30.934C 29.620403 30.934 30.934 29.620403 30.934 28C 30.934 26.379597 29.620403 25.066 28 25.066C 26.379597 25.066 25.066 26.379597 25.066 28M 28 25.066L 28 19.195M 28 36.805L 28 30.934M 25.7995 21.396999L 28 19.195L 30.2005 21.396999M 25.7995 34.603001L 28 36.805L 30.2005 34.603001M 35.336502 23.5975L 30.517 26.4895M 33.136002 22.716999L 35.338001 23.5975L 35.0425 26.091999M 20.665001 23.5975L 25.483 26.4895M 22.864 22.716999L 20.6635 23.5975L 20.9575 26.091999M 35.336502 32.4025L 30.517 29.5105M 33.136002 33.281502L 35.336502 32.4025L 35.0425 29.9065M 20.6635 32.4025L 25.483 29.5105M 22.864 33.281502L 20.6635 32.4025L 20.9575 29.9065"></path></g></g></g><g id="g-root-mail_zly5eg1dgdg5q-stroke" data-item-order="0" transform="translate(944, 86)"><g id="mail_zly5eg1dgdg5q-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#ba5de5" stroke-width="2"><g><path d="M 45.25 34L 45.25 43.75C 45.25 44.578426 44.578426 45.25 43.75 45.25L 28.75 45.25C 27.921572 45.25 27.25 44.578426 27.25 43.75L 27.25 34M 45.25 34L 45.25 33.25C 45.25 32.421574 44.578426 31.75 43.75 31.75L 28.75 31.75C 27.921572 31.75 27.25 32.421574 27.25 33.25L 27.25 34L 35.050003 38.879501C 35.77961 39.335506 36.705391 39.335506 37.435001 38.879501ZM 18.25 40.75L 22.75 40.75M 22.751501 33.25L 22.751501 40.75M 14.875 40C 14.667893 40 14.5 40.167892 14.5 40.375C 14.5 40.582108 14.667893 40.75 14.875 40.75C 15.082107 40.75 15.25 40.582108 15.25 40.375C 15.25 40.167892 15.082107 40 14.875 40L 14.875 40M 11.125 40C 10.917893 40 10.75 40.167892 10.75 40.375C 10.75 40.582108 10.917893 40.75 11.125 40.75C 11.332107 40.75 11.5 40.582108 11.5 40.375C 11.5 40.167892 11.332107 40 11.125 40L 11.125 40M 16.375 14.125C 16.167892 14.125 16 14.292893 16 14.5C 16 14.707107 16.167892 14.875 16.375 14.875C 16.582108 14.875 16.75 14.707107 16.75 14.5C 16.75 14.292893 16.582108 14.125 16.375 14.125L 16.375 14.125M 20.125 14.125C 19.917892 14.125 19.75 14.292893 19.75 14.5C 19.75 14.707107 19.917892 14.875 20.125 14.875C 20.332108 14.875 20.5 14.707107 20.5 14.5C 20.5 14.292893 20.332108 14.125 20.125 14.125L 20.125 14.125M 36.25 14.5C 36.25 12.428932 34.571068 10.75 32.5 10.75L 14.5 10.75C 12.428932 10.75 10.75 12.428932 10.75 14.5C 10.75 16.571068 12.428932 18.25 14.5 18.25L 32.5 18.25C 34.571068 18.25 36.25 16.571068 36.25 14.5ZM 16.375 21.625C 16.167892 21.625 16 21.792892 16 22C 16 22.207108 16.167892 22.375 16.375 22.375C 16.582108 22.375 16.75 22.207108 16.75 22C 16.75 21.792892 16.582108 21.625 16.375 21.625L 16.375 21.625M 20.125 21.625C 19.917892 21.625 19.75 21.792892 19.75 22C 19.75 22.207108 19.917892 22.375 20.125 22.375C 20.332108 22.375 20.5 22.207108 20.5 22C 20.5 21.792892 20.332108 21.625 20.125 21.625L 20.125 21.625M 36.25 22C 36.25 19.928932 34.571068 18.25 32.5 18.25L 14.5 18.25C 12.428932 18.25 10.75 19.928932 10.75 22C 10.75 24.071068 12.428932 25.75 14.5 25.75L 32.5 25.75C 34.571068 25.75 36.25 24.071068 36.25 22ZM 16.375 29.125C 16.167892 29.125 16 29.292892 16 29.5C 16 29.707108 16.167892 29.875 16.375 29.875C 16.582108 29.875 16.75 29.707108 16.75 29.5C 16.75 29.292892 16.582108 29.125 16.375 29.125L 16.375 29.125M 20.125 29.125C 19.917892 29.125 19.75 29.292892 19.75 29.5C 19.75 29.707108 19.917892 29.875 20.125 29.875C 20.332108 29.875 20.5 29.707108 20.5 29.5C 20.5 29.292892 20.332108 29.125 20.125 29.125L 20.125 29.125M 35.5 27.25C 34.791798 26.305729 33.68034 25.75 32.5 25.75L 14.5 25.75C 12.428932 25.75 10.75 27.428932 10.75 29.5C 10.75 31.571068 12.428932 33.25 14.5 33.25L 22.75 33.25"></path></g></g></g><g id="g-root-warn_m97dg81dqa9s1-stroke" data-item-order="0" transform="translate(272, 86)"><g id="warn_m97dg81dqa9s1-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#3cc583" stroke-width="2"><g><path d="M 35.452599 38.400398C 35.152599 38.400398 34.8526 38.700401 34.8526 39.000397C 34.8526 39.3004 35.152599 39.600403 35.452599 39.600403M 35.450798 38.400398C 35.750801 38.400398 36.0508 38.700401 36.0508 39.000397C 36.0508 39.3004 35.750801 39.600403 35.450798 39.600403M 35.453201 35.095749L 35.453201 30.595751M 44.151852 38.998001C 44.601849 39.748001 44.451851 40.798 44.00185 41.548C 43.551849 42.298 42.651852 42.748001 41.75185 42.748001L 29.00185 42.748001C 28.101849 42.748001 27.201851 42.298 26.75185 41.548C 26.301849 40.798 26.151852 39.748001 26.601849 38.998001L 32.901852 26.247999C 33.351849 25.348 34.25185 24.748045 35.301849 24.748045C 36.351849 24.748045 37.25185 25.348 37.701851 26.247999L 44.151852 38.998001ZM 29.789349 25.680401L 13.07617 25.680401C 12.24775 25.680401 11.57617 25.00885 11.57617 24.180475L 11.57617 14.751955C 11.57617 13.92352 12.24775 13.251955 13.07617 13.251955L 41.513798 13.251955C 42.342251 13.251955 43.013798 13.92352 43.013798 14.751955L 43.013798 24.180475C 43.013798 25.00885 42.342251 25.680401 41.513798 25.680401L 41.077599 25.680401M 17.606125 20.964205C 18.434919 20.964205 19.106785 20.292339 19.106785 19.463545C 19.106785 18.634766 18.434919 17.962885 17.606125 17.962885C 16.77733 17.962885 16.105465 18.634766 16.105465 19.463545C 16.105465 20.292339 16.77733 20.964205 17.606125 20.964205ZM 23.606125 20.964205C 24.434919 20.964205 25.1068 20.292339 25.1068 19.463545C 25.1068 18.634766 24.434919 17.962885 23.606125 17.962885C 22.77733 17.962885 22.105465 18.634766 22.105465 19.463545C 22.105465 20.292339 22.77733 20.964205 23.606125 20.964205ZM 29.600201 20.964205C 30.4291 20.964205 31.10095 20.292339 31.10095 19.463545C 31.10095 18.634766 30.4291 17.962885 29.600201 17.962885C 28.77145 17.962885 28.0996 18.634766 28.0996 19.463545C 28.0996 20.292339 28.77145 20.964205 29.600201 20.964205Z"></path></g></g></g><g id="g-root-1_1lz93h41dq8veo-stroke" data-item-order="0" transform="translate(440, 206)"><g id="1_1lz93h41dq8veo-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#92bd39" stroke-width="2"><g><path d="M 12.25 10.756L 43.75 10.756C 43.75 10.756 45.25 10.756 45.25 12.256L 45.25 43.756001C 45.25 43.756001 45.25 45.256001 43.75 45.256001L 12.25 45.256001C 12.25 45.256001 10.75 45.256001 10.75 43.756001L 10.75 12.256C 10.75 12.256 10.75 10.756 12.25 10.756M 22.75 27.2365L 19.531 27.2365C 18.245129 27.241089 17.130075 28.126644 16.834427 29.378075C 16.538776 30.629505 17.139631 31.920443 18.2875 32.5L 21.2125 33.962502C 22.365597 34.539513 22.970835 35.833469 22.674614 37.08839C 22.378391 38.343315 21.25841 39.230034 19.969 39.230503L 16.75 39.230499M 31.712502 35.468498C 31.712502 37.125351 30.369354 38.468498 28.712502 38.468498C 27.055647 38.468498 25.712502 37.125351 25.712502 35.468498L 25.712502 30.2185C 25.712502 28.561646 27.055647 27.2185 28.712502 27.2185C 30.369354 27.2185 31.712502 28.561646 31.712502 30.2185ZM 31.712502 40.718498L 27.174999 38.043999M 34.712502 27.2185L 34.712502 36.968498C 34.712502 38.211143 35.71986 39.218498 36.962502 39.218498L 40.712502 39.218498"></path></g></g></g><g id="g-root-tx_communic_1cws6oo1dgdhql-stroke" data-item-order="0" transform="translate(398, 2)"></g><g id="g-root-smar_zisgk81dqbmkq-stroke" data-item-order="0" transform="translate(104, 266)"><g id="smar_zisgk81dqbmkq-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#4e88e7" stroke-width="2"><g><path d="M 27.618999 38.462502L 24.618999 38.462502C 22.133718 38.462502 20.118999 36.447784 20.118999 33.962502L 20.118999 30.212502M 17.118999 32.462502L 20.118999 29.462502L 23.118999 32.462502M 36.068501 27.212502L 43.568501 27.212502C 43.568501 27.212502 45.068501 27.212502 45.068501 28.712502L 45.068501 43.712502C 45.068501 43.712502 45.068501 45.212502 43.568501 45.212502L 36.068501 45.212502C 36.068501 45.212502 34.568501 45.212502 34.568501 43.712502L 34.568501 28.712502C 34.568501 28.712502 34.568501 27.212502 36.068501 27.212502M 45.068501 40.712502L 34.568501 40.712502M 28.931499 12.2875L 28.931499 22.7875C 28.931499 22.7875 28.931499 24.2875 27.431499 24.2875L 12.4315 24.2875C 12.4315 24.2875 10.9315 24.2875 10.9315 22.7875L 10.9315 12.2875C 10.9315 12.2875 10.9315 10.7875 12.4315 10.7875L 27.431499 10.7875C 27.431499 10.7875 28.931499 10.7875 28.931499 12.2875M 28.931499 15.2875L 10.9315 15.2875M 23.681499 20.5375L 25.931499 20.5375"></path></g></g></g><g id="g-root-48px_i093a01dqbll9-stroke" data-item-order="0" transform="translate(104, 326)"><g id="48px_i093a01dqbll9-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#484848" stroke-width="2"><g><path d="M 30.881351 20.033051L 37.222675 17.637701L 37.222675 38.463249M 13.804202 25.133875C 13.804202 20.861275 15.841548 17.271431 19.758026 17.271431C 23.674599 17.271431 25.711899 20.861275 25.711899 25.133875L 25.711899 30.454525C 25.711899 34.727127 23.57905 38.411201 19.758026 38.411201C 15.937067 38.411201 13.804202 34.727127 13.804202 30.454525L 13.804202 25.133875Z"></path></g></g></g><g id="g-root-48px_1q6bye01dqd24o-stroke" data-item-order="0" transform="translate(272, 326)"><g id="48px_1q6bye01dqd24o-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#484848" stroke-width="2"><g><path d="M 13.804202 25.133875C 13.804202 20.861275 15.841548 17.271431 19.758026 17.271431C 23.674599 17.271431 25.711899 20.861275 25.711899 25.133875L 25.711899 30.454525C 25.711899 34.727127 23.57905 38.411201 19.758026 38.411201C 15.937067 38.411201 13.804202 34.727127 13.804202 30.454525L 13.804202 25.133875ZM 30.123625 23.136551C 30.123625 19.671326 32.541924 17.271482 35.828201 17.271482C 41.279949 17.271482 43.139427 22.59145 39.565975 27.323799L 30.497499 38.063126L 42.963024 38.063126"></path></g></g></g><g id="g-root-48px_1cwqva01dqd2pv-stroke" data-item-order="0" transform="translate(440, 326)"><g id="48px_1cwqva01dqd2pv-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#484848" stroke-width="2"><g><path d="M 13.804202 25.133875C 13.804202 20.861275 15.841548 17.271431 19.758026 17.271431C 23.674599 17.271431 25.711899 20.861275 25.711899 25.133875L 25.711899 30.454525C 25.711899 34.727127 23.57905 38.411201 19.758026 38.411201C 15.937067 38.411201 13.804202 34.727127 13.804202 30.454525L 13.804202 25.133875ZM 30.3409 22.801075C 30.251575 20.9944 31.36195 17.282455 36.298973 17.282455C 41.236 17.282455 41.992226 20.94805 41.821152 23.01775C 41.632526 25.299925 40.20385 27.630924 34.150524 27.630924C 39.785202 27.630924 42.344124 29.171501 42.344124 33.343376C 42.344124 36.9496 39.156624 38.417351 36.244148 38.417351C 34.151051 38.399502 29.964701 37.215324 29.964701 32.621651"></path></g></g></g><g id="g-root-48px_qs59081dqd0xy-stroke" data-item-order="0" transform="translate(608, 326)"><g id="48px_qs59081dqd0xy-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#484848" stroke-width="2"><g><path d="M 13.804202 25.134251C 13.804202 20.86165 15.841548 17.271797 19.758026 17.271797C 23.674599 17.271797 25.711899 20.86165 25.711899 25.134251L 25.711899 30.454899C 25.711899 34.727501 23.57905 38.411575 19.758026 38.411575C 15.937067 38.411575 13.804202 34.727501 13.804202 30.454899L 13.804202 25.134251ZM 39.93235 38.4841L 39.93235 17.163452L 29.721176 32.303501L 43.986027 32.303501"></path></g></g></g><g id="g-root-48px_144upjs1dqd1j5-stroke" data-item-order="0" transform="translate(776, 326)"><g id="48px_144upjs1dqd1j5-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#484848" stroke-width="2"><g><path d="M 13.804202 25.134251C 13.804202 20.86165 15.841548 17.271797 19.758026 17.271797C 23.674599 17.271797 25.711899 20.86165 25.711899 25.134251L 25.711899 30.454899C 25.711899 34.727501 23.57905 38.411575 19.758026 38.411575C 15.937067 38.411575 13.804202 34.727501 13.804202 30.454899L 13.804202 25.134251ZM 42.769974 17.59045L 32.7841 17.59045L 31.74085 27.35815C 32.362675 26.73625 34.264824 25.492451 36.898827 25.492451C 39.978325 25.492451 42.859375 27.585024 42.570248 32.539299C 42.270851 37.670349 39.183998 38.42815 36.646374 38.42815C 33.958374 38.42815 31.303751 36.520676 31.0546 32.923752"></path></g></g></g><g id="g-root-48px_4oskwo1dqd1c4-stroke" data-item-order="0" transform="translate(944.5, 326)"><g id="48px_4oskwo1dqd1c4-stroke" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke="#484848" stroke-width="2"><g><path d="M 13.804202 25.134251C 13.804202 20.86165 15.841548 17.271797 19.758026 17.271797C 23.674599 17.271797 25.711899 20.86165 25.711899 25.134251L 25.711899 30.454899C 25.711899 34.727501 23.57905 38.411575 19.758026 38.411575C 15.937067 38.411575 13.804202 34.727501 13.804202 30.454899L 13.804202 25.134251ZM 40.313278 17.248413C 33.688076 17.248413 30.526676 21.536949 30.277901 28.107176L 30.277451 31.269325C 30.277451 35.417351 32.5816 38.083 36.423622 38.411648C 40.04245 38.551975 42.295074 35.710373 42.457302 31.593775C 42.560349 28.979874 41.233597 25.310875 37.160725 24.903551C 33.591549 24.5467 30.801849 26.918724 30.277901 29.48245"></path></g></g></g><g id="g-root-tx_mcpclien_18mjmxk1dqbll7-stroke" data-item-order="0" transform="translate(50, 374)"></g><g id="g-root-tx_mcpserve_v2yyfs1dqd0qu-stroke" data-item-order="0" transform="translate(218, 374)"></g><g id="g-root-tx_mcpserve_4hxcyg1dqd2wx-stroke" data-item-order="0" transform="translate(386, 374)"></g><g id="g-root-tx_snowflak_1hefsns1dqd0xw-stroke" data-item-order="0" transform="translate(554, 374)"></g><g id="g-root-tx_mcpserve_1qbbr2w1dqd1jj-stroke" data-item-order="0" transform="translate(722, 374)"></g><g id="g-root-tx_mcpserve_zqwmoo1dqd0ju-stroke" data-item-order="0" transform="translate(890, 374)"></g><g id="g-root-tx_theclien_vb34k81dqbn64-stroke" data-item-order="0" transform="translate(50, 434)"></g><g id="g-root-tx_theserve_hrig2g1dqd2br-stroke" data-item-order="0" transform="translate(218, 434)"></g><g id="g-root-tx_theserve_1q87dnc1dqd14y-stroke" data-item-order="0" transform="translate(386, 434)"></g><g id="g-root-tx_snowflak_18issew1dqd1ql-stroke" data-item-order="0" transform="translate(554, 434)"></g><g id="g-root-tx_theserve_18ko7o81dqd0qw-stroke" data-item-order="0" transform="translate(722, 434)"></g><g id="g-root-tx_theserve_mfg4bc1dqd24r-stroke" data-item-order="0" transform="translate(890, 434)"></g></g></g></svg> ```