Databases
Step-by-step connection and configuration for MongoDB, PostgreSQL, MySQL, Redis, ClickHouse, Snowflake, BigQuery, DynamoDB, Supabase and Neon.
Ten integrations that let the agent look up the row behind a ticket. Every one of them should be given a credential that cannot write; where the server enforces that itself, this page says so, and where it does not, it says that too.
MongoDB
mongodb · runs mongodb-mcp-server via npx · read-only enforced by the server's
--readOnly flag, which blocks writes and admin commands.
Overview, prompts and the tool list: /integrations/mongodb.
Create a read-only user. In mongosh, against the database the tickets are about:
db.getSiblingDB("admin").createUser({
user: "triagic",
pwd: "…",
roles: [{ role: "read", db: "orders" }]
})Note which database the user is defined in: that is the authSource, and it's the
commonest cause of a rejected login.
Assemble the connection string, including that auth source:
mongodb+srv://triagic:…@cluster0.abc.mongodb.net/orders?authSource=admin. For Atlas,
add the machine's egress IP to the cluster's IP access list first.
Put TLS in the URI too. There are no separate certificate fields, because the driver reads all of it from the connection string:
| Parameter | What it does |
|---|---|
tls=true | Force TLS. Already implied by mongodb+srv://. |
tlsCAFile=/path/ca.pem | Verify against a private CA. Note the capital CA. |
tlsCertificateKeyFile=/path/client.pem | A client certificate and its key, in one PEM. |
tlsCertificateKeyFilePassword=… | Only if that key is encrypted. |
tlsAllowInvalidCertificates=true | Connect without checking the certificate. Encrypted, unverified. |
authSource=admin | The database the user is defined in. |
authMechanism=MONGODB-X509 | Authenticate with the client certificate itself. |
authMechanism=MONGODB-AWS | Authenticate with AWS IAM credentials. |
Paths are on the machine running Triagic, not the portal's host.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| Connection string | yes | The full URI above, credentials and TLS parameters included. Stored encrypted, returned masked. |
| Read-only | no, defaults on | Leave on. It is the server's own write block; turning it off is a deliberate act. |
Verify. The desktop proves the credential with list-databases before reporting
running.
| If it reports | It usually means |
|---|---|
connection string is not valid | Not the URI: this is also what the server says when the host simply isn't reachable. Check the host and port answer from that machine, and that an SRV or replica-set name resolves, before editing anything. |
authentication failed / bad auth | The username or password was rejected, or authSource points at the wrong database. |
PostgreSQL
postgres · runs Triagic's own read-only Postgres server, which ships inside the app
and is started with node · read-only three ways: one statement per call, a
SELECT-style first keyword, and a read-only transaction that is always rolled back.
Overview, prompts and the tool list: /integrations/postgres.
Triagic writes this server itself. The published package it replaced is archived, and
its read-only transaction could be escaped by sending COMMIT; followed by a second
statement. No maintained alternative enforces read-only for plain Postgres.
| Tool | What it does |
|---|---|
list_schemas | The schemas the role can see. System schemas are left out. |
list_tables | Tables and views, across every schema or scoped to one, with an optional LIKE pattern on the name. Stops at 500 and says so. |
describe_table | Columns, indexes and constraints for one table or view, named bare or as schema.table. A bare name is looked up in public. |
query | One read-only statement: SELECT, WITH, VALUES, TABLE, SHOW or EXPLAIN. 30 second timeout, 500 rows at most. |
Three things keep query read-only. The statement must start with one of those
keywords, so COMMIT, SET, DO and CALL never reach the database. It is sent over
the protocol that carries exactly one statement, and Postgres itself refuses a second.
And it runs inside BEGIN TRANSACTION READ ONLY, which is rolled back whatever
happens. None of that replaces the read-only role in the first step below.
Create a read-only role.
CREATE ROLE triagic LOGIN PASSWORD '…';
GRANT CONNECT ON DATABASE billing TO triagic;
GRANT USAGE ON SCHEMA public TO triagic;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO triagic;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO triagic;The last line is the one people forget: without it, tables created later are invisible.
Put certificates in the URL. There are no separate certificate fields: the driver reads these from the connection string and loads each file from disk when it connects.
| Parameter | What it does |
|---|---|
sslrootcert=/path/ca.pem | Verify the server against a private CA. |
sslcert=/path/client.crt | A client certificate. |
sslkey=/path/client.key | Its private key. |
Paths are on the machine running Triagic, not the portal's host.
Know that this driver reads sslmode more strictly than psql does.
Without uselibpqcompat=true in the URL, it treats sslmode=prefer, require and
verify-ca as aliases for verify-full: all three verify the certificate chain and
the hostname. libpq's require means "encrypt, don't verify", so a URL copied out of
an RDS or Supabase console that connects fine with psql can fail here on certificate
verification, with nothing pointing at the difference.
Two ways out: add uselibpqcompat=true to get libpq's meanings back, or turn off
Verify TLS certificate, which replaces the sslmode entirely.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| Connection URL | yes | postgres://triagic:…@host:5432/billing, plus any sslrootcert / sslcert / sslkey. Any sslmode you set is replaced by the toggle below. |
| Verify TLS certificate | no, defaults on | Turn off for managed Postgres (RDS, DigitalOcean, Supabase) and internal clusters whose certificate is signed by a private CA. Traffic stays encrypted. |
Verify. Health check is SELECT 1.
| If it reports | It usually means |
|---|---|
self-signed certificate in certificate chain, unable to verify local issuer | The certificate isn't signed by a CA that machine trusts, which is usual for managed Postgres. Turn off Verify TLS certificate, set sslrootcert= to the provider's CA bundle, or install that bundle on the machine. The failure appears on the health check, not at startup, because the driver connects lazily. |
Hostname/IP does not match certificate | sslmode=require in the URL, which this driver reads as verify-full. Add uselibpqcompat=true, or use sslrootcert= with the name the certificate actually carries. |
only SELECT, WITH, VALUES, TABLE, SHOW, EXPLAIN statements run here | The agent tried a statement that is not a read. Nothing was sent to the database. |
cannot insert multiple commands into a prepared statement | Two statements in one call. Postgres refused the second; the first did not run either. |
password authentication failed | The user or password in the URL. A password with special characters has to be percent-encoded inside the URL. |
The connection URL travels to the server in an environment variable, not on the command line, so the password does not appear in the machine's process list.
MySQL
mysql · runs Triagic's own read-only MySQL server, which ships inside the app and is
started with node · read-only by construction: four fixed tools, and no tool that
runs a statement you write.
Overview, prompts and the tool list: /integrations/mysql.
This is the one integration in the catalog that isn't a published package. Every
published MySQL MCP server puts discovery behind a general execute_sql tool that runs
UPDATE and DELETE as readily as SELECT, so Triagic writes this server itself:
| Tool | What it does |
|---|---|
list_databases | Every database the credentials can reach, with character set and collation. MySQL's own system schemas are left out. |
list_tables | Tables and views, across every reachable database or scoped to one, with an optional LIKE pattern on the name. Stops at 500 tables and says so. |
describe_table | Columns, indexes and foreign keys for one table, named bare or as database.table. |
sample_table | A few rows from a table: 10 by default, 50 at most. |
Three things keep it read-only. Every statement in the server is fixed text, and what
the agent supplies reaches MySQL only as a bound parameter. There's no general SQL
tool to hand a statement to. And each connection opens with
SET SESSION TRANSACTION READ ONLY, so the server itself would refuse a write.
Create a read-only user. The user's grants decide which databases and tables the
agent can see at all: information_schema only shows a user what they hold a
privilege on.
CREATE USER 'triagic'@'%' IDENTIFIED BY '…';
GRANT SELECT ON shop.* TO 'triagic'@'%';Repeat the GRANT for each database the agent should reach. MySQL grants are per
host, so 'triagic'@'%' and 'triagic'@'localhost' are different users.
Decide how much the connection should check the server's certificate.
Leaving TLS mode on Driver default encrypts the connection whenever the server offers TLS, and does not check the certificate. Fine inside a private network, not enough across one. Required also checks the certificate, against the trust store of the machine running Triagic.
For a server whose certificate comes from a private CA, put that CA's bundle on the machine and choose Verify CA, or Verify CA and hostname if the name you connect to is the name on the certificate. Those two modes are the only ones that read CA certificate path; under Required it is ignored. Checking the hostname needs a hostname in Host: with a bare IP address the name check is skipped.
Fill the form. This one takes the parts, not a URL.
| Field | Required | What to put |
|---|---|---|
| Host | yes | Hostname or IP reachable from the member's machine. |
| Port | no, defaults 3306 | |
| User | yes | triagic |
| Password | no | Blank is accepted, and sent, for a passwordless user. |
| Default database | no | Leave blank to work across every database the credentials can reach. Setting one only makes it the default for a table named without a database; the agent can still list, describe and sample the others. |
| TLS mode | no, defaults to the driver's | See above. Disabled turns encryption off entirely. |
| CA certificate path | no | Absolute path on the machine running Triagic, or paste the file itself. Read only under the two Verify modes. |
Verify. Health check is a list_databases call. It connects, authenticates and
reads information_schema, so a wrong password, an unreachable host and a user with
no grants all fail it.
| If it reports | It usually means |
|---|---|
Access denied for user, ER_ACCESS_DENIED_ERROR | MySQL rejected the credentials. Check User and Password, and that the user may connect from this machine's address: 'user'@'%' and 'user'@'localhost' are separate grants. |
ER_NOT_SUPPORTED_AUTH_MODE, or a message naming caching_sha2_password | The account uses caching_sha2_password and the connection is unencrypted. Set TLS mode to Required or higher. |
self-signed certificate, unable to verify local issuer | The certificate isn't signed by a CA that machine trusts. Set TLS mode to Driver default to connect anyway, still encrypted, or point CA certificate path at the provider's CA bundle and use one of the Verify modes. |
no columns for db.table or no table db.table | The table doesn't exist, or these credentials hold no privilege on it. MySQL shows a user only what they're granted, so the two look the same from here. |
no database for "table" | A table was named without a database and no Default database is set. Qualify it as database.table, or set the field. |
Redis
redis · runs redis-mcp-server (the official redis/mcp-redis) via uvx ·
read-only enforced by a pinned tool allowlist: only the server's read tools are
exposed. The write tools (set, hset, delete, expire, lpush, json_set,
zadd, xadd, publish, …) are dropped at connect time, and so are the reads that
mutate on the way: lpop/rpop (destructive) and consumer-group reads that move
the pending-entries list.
Overview, prompts and the tool list: /integrations/redis.
Credentials go through environment variables, so nothing here is visible in the process list.
Create a restricted ACL user so the guarantee holds server-side too, not only in the allowlist:
ACL SETUSER triagic on >… ~* +@read +@keyspace+@read grants every read command and nothing else; +@keyspace adds SCAN, TYPE
and DBSIZE, which the tools and the health check use. On a managed Redis without
ACLs, the shared default user works; the allowlist is then the only boundary.
Fill the form. This one takes the parts, not a URL.
| Field | Required | What to put |
|---|---|---|
| Host | yes | Hostname or IP reachable from the member's machine. |
| Port | no, defaults 6379 | |
| Username | no | triagic for the ACL user above. Blank uses the default user. |
| Password | no | |
| Database number | no, defaults 0 | |
| Use TLS | no | Turn on to encrypt the connection. Verified against this machine's trust store unless a CA path is set below. |
| CA certificate path | no | Absolute path on the machine running Triagic, for a server certificate signed by a private CA. Only read when TLS is on. |
| Verify TLS certificate | no, defaults on | Turn off for a self-signed certificate. Traffic stays encrypted but the certificate is not checked. Only read when TLS is on. |
Verify. Health check is dbsize, a single DBSIZE, cheap and read-only. It
fails on a wrong password where merely starting the server would not.
| If it reports | It usually means |
|---|---|
NOAUTH / Authentication required | The server wants a password and none was sent. |
WRONGPASS | Password rejected, or Username names an ACL user that doesn't exist. A blank username authenticates as default. |
NOPERM | The ACL user lacks a command category the tools need. Grant +@read +@keyspace as above. |
Connection refused / timeout | Host or port wrong, or the server isn't reachable from that member's machine. |
certificate verify failed | The certificate isn't trusted by that machine. Set CA certificate path, or turn off Verify TLS certificate if it is self-signed. |
ClickHouse
clickhouse · runs mcp-clickhouse via uvx · read-only twice over: writes are
disabled in the server, and each query is sent with ClickHouse's own readonly
setting where the user's grants allow it.
Overview, prompts and the tool list: /integrations/clickhouse.
Create a read-only user.
CREATE USER triagic IDENTIFIED BY '…' SETTINGS readonly = 1;
GRANT SELECT ON events.* TO triagic;Optionally create a role, and name it on the form.
A role is applied with SET ROLE before every query, which makes it a per-statement
bound rather than a description of the account. That is the strongest read-only
control ClickHouse offers here. It holds even where the user's own grants are wider,
and you can tighten it later without touching the user.
CREATE ROLE readonly_analyst;
GRANT SELECT ON events.* TO readonly_analyst;
GRANT readonly_analyst TO triagic;For a private CA, install its certificate in this machine's OS trust store. There is no CA path to set on the form: the server reads the operating system's trust store directly, so a certificate installed there is honoured and one sitting in a file is not.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| Host | yes | abc123.us-east-1.aws.clickhouse.cloud, or your own hostname. |
| Port | no | Leave blank and it follows TLS: 8443 with, 8123 without. |
| User | yes | triagic, or default on a fresh Cloud service. |
| Password | no | Blank is allowed for a passwordless user. |
| Database | no | Default database for queries. Blank browses them all. |
| Role | no | readonly_analyst, applied with SET ROLE on every query. Blank uses the user's default roles. |
| Use TLS | no, defaults on | Turn off only for a plain-HTTP cluster, typically self-hosted on 8123. |
| Certificate hostname | no | Only when the certificate names a different host than the one you connect to: behind a load balancer, or reached by IP. |
| Verify TLS certificate | no, defaults on | For a private CA, install the certificate in the OS trust store instead of turning this off. |
Verify. Health check is list_databases.
| If it reports | It usually means |
|---|---|
Code: 516 / Authentication failed | The user or password was rejected. Remember ClickHouse Cloud always requires TLS on 8443. |
Code: 511 / unknown role | Role names a role that does not exist, or one the user has not been granted. |
| A certificate hostname mismatch | The certificate names a different host than the one you connect to. Set Certificate hostname to the name on the certificate. |
Snowflake
snowflake · runs Triagic's own read-only Snowflake server, which ships inside the app
and is started with node · it talks to Snowflake's SQL REST API, which runs one
statement per call. Snowflake has no read-only session, so the role's grants are the
real boundary.
Overview, prompts and the tool list: /integrations/snowflake.
| Tool | What it does |
|---|---|
list_databases | SHOW DATABASES. Needs no warehouse, which is why it is the health check. |
list_schemas | Schemas in one database. |
list_tables | Tables and views in one database, optionally one schema, with a case-insensitive pattern on the name. |
describe_table | Columns of one table or view. |
query | One read-only statement: SELECT, WITH, SHOW, DESCRIBE, DESC or EXPLAIN. 500 rows at most. |
Two things stand between the agent and a write before the role does. The statement
must start with one of those keywords and may not define an anonymous procedure or chain
statements with ->>. And every request tells the REST API to accept exactly one
statement, so a second one is refused.
Create a role that can only read, and a service user for it.
CREATE ROLE triagic_reader;
GRANT USAGE ON WAREHOUSE analytics_wh TO ROLE triagic_reader;
GRANT USAGE ON DATABASE prod TO ROLE triagic_reader;
GRANT USAGE ON ALL SCHEMAS IN DATABASE prod TO ROLE triagic_reader;
GRANT SELECT ON ALL TABLES IN DATABASE prod TO ROLE triagic_reader;
CREATE USER triagic TYPE = SERVICE DEFAULT_ROLE = triagic_reader;
GRANT ROLE triagic_reader TO USER triagic;Put triagic_reader in the Role field as well. The form sends it with every
statement, so the queries run read-only even if someone later changes the user's
default role.
Pick how it signs in. An account password does not work: Snowflake's SQL API takes a token or a key pair only.
Programmatic access token. Create one for the user under Settings →
Authentication → Programmatic access tokens, scoped to triagic_reader. Snowflake
only accepts a token from a user covered by a network policy, even though creating the
token needs none:
CREATE NETWORK POLICY triagic_np ALLOWED_IP_LIST = ('0.0.0.0/0');
ALTER USER triagic SET NETWORK_POLICY = triagic_np;Scope ALLOWED_IP_LIST to the egress range of the machine running Triagic where you
can.
Key pair. No network policy needed. Generate a PKCS#8 key, register the public half, and point the form at the private half:
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out snowflake_rsa_key.p8 -nocrypt
openssl rsa -in snowflake_rsa_key.p8 -pubout -out snowflake_rsa_key.pubALTER USER triagic SET RSA_PUBLIC_KEY = '<contents of snowflake_rsa_key.pub without the BEGIN and END lines>';Fill the form.
| Field | Required | What to put |
|---|---|---|
| Account identifier | yes | Just the identifier: myorg-myaccount, or a locator plus region like xy12345.us-east-1. Never the full …snowflakecomputing.com URL. |
| User | yes | triagic |
| Authentication | no, defaults to token | Programmatic access token or Key pair. |
| Programmatic access token | with token auth | The token, not the account password. |
| Private key path | with key pair | Path to the .p8 file on each machine running Triagic, or paste the file itself. |
| Private key passphrase | no | Only for an encrypted key. |
| Warehouse | yes | Queries need one. list_databases works without it; SELECTs do not. |
| Role | no | triagic_reader. Blank means the user's default role. |
| Database | no | Default database, or leave blank and fully qualify names in queries. |
| Schema | no |
Verify. Health check is list_databases.
| If it reports | It usually means |
|---|---|
394400 / Programmatic access token is invalid | The token was created for a different user, has expired, or the user has no network policy (see above). |
390303, Invalid OAuth access token, or a bare HTTP 401 | An account password in the token field. Create a programmatic access token, or switch Authentication to Key pair. |
390101 / JWT token is invalid | The public key is not registered on this exact user, User is not the login name, or the machine's clock is off. The signed token is valid for an hour. |
fetch failed, ENOTFOUND, HTTP 404 or is not a valid Snowflake account | Almost always the account identifier, not the network. The dotted myorg.my_account form is the classic mistake; use myorg-my_account. |
000606 / No active warehouse | Set Warehouse to one the role has USAGE on. |
only SELECT, WITH, SHOW, DESCRIBE, DESC, EXPLAIN statements run here | The agent tried a statement that is not a read. Nothing was sent to Snowflake. |
BigQuery
bigquery · runs mcp-server-bigquery via uvx.
Overview, prompts and the tool list: /integrations/bigquery.
Writes are not blocked here
The query tool runs whatever SQL it is given. IAM is the only control, so the service account's roles are the boundary.
Create a service account with exactly two roles: BigQuery Data Viewer (roles/bigquery.dataViewer) to read, and BigQuery Job User (roles/bigquery.jobUser) to run queries. Nothing else.
Download its JSON key and place it on the machine that runs Triagic, at an absolute
path readable by the desktop app, e.g. /opt/triagic/bigquery-sa.json. Skip this if
that machine already has Application Default Credentials configured.
For impersonation or workload-identity federation, switch to Application Default Credentials.
The key-file path accepts a plain service-account key and nothing else. It's read by
a loader that refuses impersonated_service_account and external_account JSON
outright. If your organization issues either of those, choose Application Default
Credentials and give the same file under Credentials file path, where it is read
by the general Google credentials loader that understands all three formats.
Leaving that path blank uses whatever gcloud auth application-default login already
left on the machine.
Decide which datasets the agent may see. Naming them is the one least-privilege control this server offers that does not mean minting a narrower service account: nothing outside the list is visible, whatever the account could otherwise reach. Leave it blank and every dataset in the project is exposed.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| Project ID | yes | my-project-123 |
| Location | yes, defaults US | Where the datasets live: a multi-region (US, EU) or a region like europe-west9. A mismatch returns no results rather than an error. |
| Authentication method | no, defaults key file | Application Default Credentials for impersonation or workload-identity federation. |
| Service account key path | no | Absolute path to the JSON above. Plain service-account keys only. Blank falls back to Application Default Credentials. |
| Credentials file path | no | With ADC: a service-account key, impersonation config, or federation config. Blank uses the machine's own gcloud login. |
| Limit to datasets | no | analytics_prod,billing, comma-separated. Blank exposes every dataset. |
Verify. Health check is list-tables.
| If it reports | It usually means |
|---|---|
Could not automatically determine credentials | No Google credentials on that machine. Set the key path, or run gcloud auth application-default login there. |
403 / Access Denied | A missing role: it needs both Data Viewer and Job User on this project. |
| A type or format error about the key file | An impersonation or federation JSON given to Service account key path, which only takes plain service-account keys. Switch to Application Default Credentials. |
| A dataset you expect is missing | Limit to datasets is set and does not name it. |
DynamoDB
dynamodb · runs awslabs.aws-api-mcp-server via uvx, locked to read-only
operations · every command is matched against AWS's read-only action list before it
runs, local file access is refused outright, and upstream telemetry is off.
Overview, prompts and the tool list: /integrations/dynamodb.
Create an IAM user with AmazonDynamoDBReadOnlyAccess, or a policy granting
dynamodb:List*, dynamodb:Describe*, dynamodb:Query, dynamodb:Scan and
dynamodb:GetItem on the tables you need. Generate an access key for it.
Or point at a named profile instead. Choosing Named profile reads the credential
from the ~/.aws/config of the machine running Triagic, which is the only way to reach
assume-role, IAM Identity Center (SSO), credential_process or MFA. See
AWS CloudWatch for the profile shapes.
This server also injects --profile <name> into every CLI command it generates, so the
profile is what the command itself runs as, not only what the SDK signs with.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| Authentication method | no, defaults Access keys | Named profile for assume-role, SSO, credential_process or MFA. |
| AWS access key ID | yes, with Access keys | AKIA… |
| AWS secret access key | yes, with Access keys | |
| Session token | no, with Access keys | Only for temporary (STS) credentials. |
| Profile name | yes, with Named profile | The name inside [profile …] in that machine's ~/.aws/config. |
| Region | yes, defaults us-east-1 | DynamoDB tables are per-region, so this has to be the region the table lives in. |
| CA certificate path | no | Only where a TLS-intercepting proxy sits in front of the AWS endpoints. |
Verify. No health check runs for this one: the underlying tool returns AWS errors as successful results with an error field, so a check could not tell a working credential from a denied one. It is start-checked only; the first real tool call is what proves the credential.
| If it reports | It usually means |
|---|---|
InvalidClientTokenId, SignatureDoesNotMatch | Key ID and secret aren't a matching pair, or the key is inactive. Temporary credentials also need Session token filled in. |
The config profile (…) could not be found | No such profile in the ~/.aws/config of the machine running Triagic. That machine, not the portal host. |
Token has expired and refresh failed | An SSO profile whose session has lapsed. Run aws sso login --profile … on that machine. |
AccessDenied | Credentials are valid, the IAM policy is not. |
ResourceNotFoundException | Right credentials, wrong Region. |
…is a write operation | Expected. This integration refuses writes before they reach AWS. |
Supabase
supabase · runs @supabase/mcp-server-supabase via npx with --read-only ·
SQL executes inside a read-only transaction, and the migration, branching, storage and
edge-function deploy tools are not offered at all.
Overview, prompts and the tool list: /integrations/supabase.
The tool surface is deliberately narrowed to three feature groups: database (list tables, extensions, migrations, run SQL), debugging (query logs, security and performance advisors) and docs. Account-level tools are excluded on purpose: they reach across projects, which would undo the per-project scoping below.
Generate a personal access token at supabase.com/dashboard/account/tokens. It inherits its owner's organization access, so create it from an account that is a member of the organization owning the project, ideally a dedicated one.
The project's anon and service_role keys are a different credential and are not
accepted here.
Find the project ref. Project Settings → General → Reference ID, a
20-character string. It is also the subdomain of the project's …supabase.co URL.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| Personal access token | yes | sbp_… |
| Project ref | yes | The reference ID. One configuration is one project; add a second instance for a second project. |
Verify. Health check is list_tables, which runs real SQL through the platform
API, so it fails on both a bad token and a project the token cannot reach.
| If it reports | It usually means |
|---|---|
401 / invalid token | Not a personal access token. It must start sbp_ and come from the account tokens page. |
403 | The token's owner is not a member of the organization that owns this project. |
404 / project not found | Wrong ref. Use the 20-character reference ID, not the project's display name. |
cannot execute … in a read-only transaction | Expected, and deliberate. |
Neon
neon · a hosted endpoint at https://mcp.neon.tech/mcp, reached with your Neon
API key as the bearer. Nothing runs locally, and the session is opened with
?readonly=true, so the server itself refuses writes, migrations and project
management.
Overview, prompts and the tool list: /integrations/neon.
Covers projects, branches, table schemas, read-only SQL, slow queries and query plans.
Create an API key at console.neon.tech → Account settings → API keys. An organization API key scopes access to that organization's projects. Prefer it over a personal key, which sees everything the account can.
A database password or connection string is a different credential and is not accepted here.
Optionally find the project ID. Project Settings → General → Project ID,
e.g. wispy-salad-12345678. Setting it scopes the session to that one project;
leaving it blank reaches every project the key can see.
Fill the form.
| Field | Required | What to put |
|---|---|---|
| API key | yes | napi_… |
| Project ID | no | The ID from Project Settings, not the project's display name. |
Verify. Health check is list_projects, a cheap authenticated read that fails
on a bad or revoked key.
| If it reports | It usually means |
|---|---|
401 | Not an API key, or a revoked one. It comes from Account settings → API keys and starts napi_. |
403 | An organization key pointed at a project outside that organization. |
404 | Project ID doesn't resolve. Use the ID, not the display name, or leave it blank. |
| refused write | Expected, and deliberate: the session is read-only. |
Connecting data sources
How an integration is configured, what has to be installed on the machine that runs it, and the whole catalog with a link to the per-integration steps.
Observability
Step-by-step connection and configuration for Sentry, Prometheus, OpenSearch, Elasticsearch, Datadog, Grafana, PagerDuty, Splunk, New Relic, PostHog, Dynatrace and Honeycomb.