# Database MCP Server (`constant_quadruped/database-mcp-server`) Actor

MCP Server for AI database access. Connect to PostgreSQL, MySQL, or SQLite. Query data, inspect schemas, list tables, describe columns, view indexes and foreign keys. 11 tools for complete database intelligence. Works with Claude Desktop and any MCP client.

- **URL**: https://apify.com/constant\_quadruped/database-mcp-server.md
- **Developed by:** [CQ](https://apify.com/constant_quadruped) (community)
- **Categories:** MCP servers, Developer tools, AI
- **Stats:** 6 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Database MCP Server

MCP Server for AI database access. Connect to PostgreSQL, MySQL, or SQLite. Query data, inspect schemas, manage tables. 11 tools for complete database intelligence.

### Features

- **Multi-database** - PostgreSQL, MySQL, SQLite
- **Query execution** - SELECT with automatic LIMIT protection
- **Schema inspection** - Tables, columns, foreign keys, indexes
- **Safe operations** - Separate read (query) and write (execute) tools
- **Cloud-ready** - Secure connections via Apify infrastructure

### Input Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `tool` | string | Database tool to execute |
| `dbType` | string | `postgresql`, `mysql`, or `sqlite` |
| `connectionString` | string | Full connection URI |
| `host` | string | Database host |
| `port` | integer | Database port |
| `database` | string | Database name |
| `user` | string | Username |
| `password` | string | Password (secret) |
| `ssl` | boolean | Enable SSL (default: true) |
| `query` | string | SQL query to execute |
| `tableName` | string | Table for describe/info operations |
| `limit` | integer | Max rows to return (default: 1000) |
| `timeout` | integer | Query timeout in ms (default: 30000) |
| `sqliteUrl` | string | URL to SQLite database file |
| `sqliteData` | string | Base64-encoded SQLite database |

### Tools

| Tool | Description |
|------|-------------|
| `db.connect` | Connect to database |
| `db.disconnect` | Close connection |
| `db.query` | Execute SELECT (read-only) |
| `db.execute` | Execute INSERT/UPDATE/DELETE/DDL |
| `db.list_tables` | List all tables |
| `db.describe_table` | Get column definitions |
| `db.get_schema` | Full schema (all tables) |
| `db.list_databases` | List databases on server |
| `db.table_info` | Row count, size statistics |
| `db.foreign_keys` | Foreign key relationships |
| `db.indexes` | Index information |

### Examples

#### Connect to PostgreSQL

```json
{
  "tool": "db.connect",
  "dbType": "postgresql",
  "connectionString": "postgresql://user:pass@host:5432/dbname"
}
```

Or with individual parameters:

```json
{
  "tool": "db.connect",
  "dbType": "postgresql",
  "host": "your-host.com",
  "port": 5432,
  "database": "mydb",
  "user": "myuser",
  "password": "mypassword",
  "ssl": true
}
```

#### Connect to MySQL

```json
{
  "tool": "db.connect",
  "dbType": "mysql",
  "host": "your-mysql-host.com",
  "port": 3306,
  "database": "mydb",
  "user": "myuser",
  "password": "mypassword"
}
```

#### Connect to SQLite (URL)

```json
{
  "tool": "db.connect",
  "dbType": "sqlite",
  "sqliteUrl": "https://example.com/database.db"
}
```

#### Query Data

```json
{
  "tool": "db.query",
  "dbType": "postgresql",
  "connectionString": "postgresql://...",
  "query": "SELECT * FROM users WHERE active = true",
  "limit": 100
}
```

#### Get Schema

```json
{
  "tool": "db.get_schema",
  "dbType": "postgresql",
  "connectionString": "postgresql://..."
}
```

#### Describe Table

```json
{
  "tool": "db.describe_table",
  "dbType": "postgresql",
  "connectionString": "postgresql://...",
  "tableName": "users"
}
```

#### Execute Statement

```json
{
  "tool": "db.execute",
  "dbType": "postgresql",
  "connectionString": "postgresql://...",
  "query": "INSERT INTO logs (message) VALUES ('Hello World')"
}
```

### Output

Results are pushed to the run's **dataset** (not a live socket). Every run emits a `server_info` record first (version, tool list, supported databases); if you pass a `tool`, a `tool_result` record follows. Failures are pushed as `error` records — the run still completes.

| Field | Type | Description |
|-------|------|-------------|
| `type` | string | Record type: `server_info`, `tool_result`, or `error` |
| `tool` | string | Tool that was executed (on `tool_result`) |
| `status` | string | `success` or `error` |
| `data` | object | Result data (e.g. `rows`, `fields`, or connection/schema info) |
| `rowCount` | integer | Rows returned or affected |
| `executionTime` | integer | Tool execution time in ms |
| `errors` | array | Error entries `[{ code, message }]` on failures |

#### Success Response

```json
{
  "type": "tool_result",
  "tool": "db.query",
  "status": "success",
  "data": {
    "rows": [...],
    "fields": ["column1", "column2"]
  },
  "rowCount": 10,
  "executionTime": 45
}
```

#### Error Response

```json
{
  "type": "tool_result",
  "tool": "db.query",
  "status": "error",
  "errors": [
    { "code": "TOOL_ERROR", "message": "relation \"users\" does not exist" }
  ]
}
```

### MCP Integration

This Actor is a **request/response tool dispatcher**: you invoke it with a `tool` in the input and read the result from the run's dataset. It is not a long-lived stdio/SSE MCP server on its own. To call it as a tool from an MCP client (Claude Desktop, etc.), connect **Apify's Actors MCP server**, which exposes your Actors as MCP tools:

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--actors", "constant_quadruped/database-mcp-server"],
      "env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
    }
  }
}
```

#### Apify Client (JavaScript)

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('constant_quadruped/database-mcp-server').call({
  tool: 'db.query',
  dbType: 'postgresql',
  connectionString: 'postgresql://user:pass@host:5432/db',
  query: 'SELECT * FROM users LIMIT 10'
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Apify Client (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")

run = client.actor("constant_quadruped/database-mcp-server").call(run_input={
    "tool": "db.query",
    "dbType": "postgresql",
    "connectionString": "postgresql://user:pass@host:5432/db",
    "query": "SELECT * FROM users LIMIT 10"
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use Cases

- **Data exploration** - Understand database structure
- **Report generation** - Query data for AI reports
- **Schema documentation** - Auto-generate database docs
- **Data migration** - Inspect source and target schemas
- **Debugging** - Query logs and metrics tables

### Security

- Passwords and connection strings marked as secrets
- SSL enabled by default for PostgreSQL and MySQL
- Query results limited to prevent memory issues
- Separate read (query) and write (execute) operations

### Limitations

- **One tool per run.** Each Actor run dispatches a single `tool` call and returns its result in the dataset. It is not a persistent MCP server process — chain multiple runs, or connect via Apify's Actors MCP server (above), for multi-step sessions.
- **Connections are not persisted across runs.** A run auto-connects from the credentials you pass and tears the connection down at exit. A `connectionId` from `db.connect` is only reusable within that same run.
- **`db.query` is read-only.** It accepts `SELECT`/`WITH`/`SHOW`/`EXPLAIN`/`PRAGMA` only and auto-appends `LIMIT` when absent. Use `db.execute` for `INSERT`/`UPDATE`/`DELETE`/DDL.
- **You supply the database.** The Actor connects to a database *you* provide and reach; it stores no credentials or data between runs and cannot reach hosts your network/proxy can't.
- **SQLite from file/URL is loaded into the run.** Very large SQLite databases are bounded by the run's memory and timeout.
- **SQLite driver is optional.** `better-sqlite3` is an optional dependency; SQLite support requires it to be present in the build image.

### License

MIT

# Actor input Schema

## `tool` (type: `string`):

Database tool to execute

## `dbType` (type: `string`):

Type of database to connect to

## `connectionString` (type: `string`):

Database connection string (e.g., postgresql://user:pass@host:5432/dbname)

## `host` (type: `string`):

Database host (alternative to connection string)

## `port` (type: `integer`):

Database port

## `database` (type: `string`):

Name of the database to connect to

## `user` (type: `string`):

Database username

## `password` (type: `string`):

Database password

## `ssl` (type: `boolean`):

Enable SSL connection

## `query` (type: `string`):

SQL query to execute

## `tableName` (type: `string`):

Table name for describe/info operations

## `limit` (type: `integer`):

Maximum rows to return (default: 1000)

## `timeout` (type: `integer`):

Query timeout in milliseconds

## `sqliteData` (type: `string`):

Base64-encoded SQLite database file

## `sqliteUrl` (type: `string`):

URL to SQLite database file

## Actor input object example

```json
{
  "dbType": "postgresql",
  "host": "localhost",
  "ssl": true,
  "limit": 1000,
  "timeout": 30000
}
```

# Actor output Schema

## `results` (type: `string`):

Database query results and operation outputs

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("constant_quadruped/database-mcp-server").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("constant_quadruped/database-mcp-server").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call constant_quadruped/database-mcp-server --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,constant_quadruped/database-mcp-server"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ScMbl7Azf9xC64kJw/builds/rsfWAcB8w5yv6Uubh/openapi.json
