← back to blog
    Berner SetterwallSeptember 28, 20263 min read

    Azure SQL Is Live in Cogny: Let Your Agent Query Your Own Database, Read-Only

    A lot of the numbers that matter — orders, customers, subscriptions, margins — don't live in an ad platform or a SaaS tool with a REST API. They live in the company's own database, and for many teams that database is Azure SQL. Until today a Cogny agent couldn't see it unless you built an export into BigQuery first.

    Now it can. Azure SQL is a live MCP integration: point Cogny at your server with a read-only database user, and Claude can explore the schema and answer questions with T-SQL against your actual tables.

    This one came straight out of Wish for an MCP. The first answer to that wish was "we can't build this" — our researcher only knew how to wrap HTTP APIs, and Azure SQL speaks TDS on port 1433. That was the wrong answer, so we fixed both: the connector, and the researcher, which now treats customer-run databases as buildable.


    TL;DR

    • Azure SQL is live now. Connect it from Settings → MCPs For Cogny.
    • Four tools, all reads: get_server_info, list_tables, describe_table, run_query.
    • Read-only three times over: the user you create can only read; every query must be a single SELECT (or WITH … SELECT) — writes, EXEC, SELECT … INTO and multiple statements are rejected before they reach your server; and every connection is rolled back before it closes.
    • One IP to allow: all Cogny connections come from 207.175.17.47.
    • TLS is required and the server certificate is verified. Results cap at 5,000 rows per query; queries time out after 60 seconds.

    What the agent can do

    ToolWhat it returns
    get_server_infoDatabase, login and user, edition / service objective, role membership — and a warning if the user can write
    list_tablesTables and views with approximate row counts, filterable by schema or a LIKE pattern
    describe_tableColumns and types, primary key, foreign keys, and a few sample rows
    run_queryOne read-only T-SQL query, default 200 rows (max 5,000), with a truncated flag

    The intended loop is: list_tables → describe_table on the two or three tables that matter → a run_query that aggregates in SQL (GROUP BY, SUM, COUNT) rather than pulling raw rows into the conversation. The revenue-cohort-analysis report template now uses it when Azure SQL is connected.


    Setting it up

    1. Create a read-only user in the database itself (not master):

      CREATE USER cogny_reader WITH PASSWORD = '<strong password>';
      ALTER ROLE db_datareader ADD MEMBER cogny_reader;
      -- optional: hide what the agent shouldn't see
      DENY SELECT ON SCHEMA::hr TO cogny_reader;
      
    2. Allow Cogny's IP. In the Azure portal, open the SQL server → Security → Networking, set public network access to Selected networks, and add a firewall rule with start and end IP 207.175.17.47.

    3. Connect. Settings → MCPs For Cogny → Azure SQL: server name (myserver.database.windows.net, or myserver.database.windows.net,1433), database, user, password. The credentials are stored encrypted and scoped to the workspace.

    4. Ask. "Which acquisition month has the best 90-day repeat rate?" is now a question the agent can answer from your own order table.

    If something is wrong, the error says what: a blocked firewall reports the IP Azure saw, a failed login names the user and database, and a missing permission tells you which GRANT to run.


    Why read-only, and why a dedicated user

    This connector touches customer data, so the defaults are conservative. The database user is the real boundary — it's the one you control — and get_server_info tells you (and the agent) if the login you connected can write. The statement check and the forced rollback are there so a creative query can't turn into a write even if the user had more rights than intended. Queries only run when the agent calls them; nothing is copied out of your database ahead of time.

    Postgres, MySQL and Snowflake would follow the same shape. If yours is one of them, wish for it — databases now go into the build queue instead of getting a "no REST API" refusal.