USQL MCP Server
The USQL MCP Server bridges the Model Context Protocol with the usql CLI, enabling AI assistants to execute SQL queries and database operations across multiple database systems.
Capabilities:
Execute SQL Queries - Run arbitrary SQL statements (SELECT, INSERT, UPDATE, DELETE) with optional prepared statement parameters
Execute Multi-Statement Scripts - Run complete SQL scripts with multiple statements in sequence
List Databases - Discover all databases available on a database server
List Tables - View all tables within a specific database
Describe Table Schema - Get detailed schema information including columns, data types, and constraints
Flexible Connection Management - Connect using full database URLs (e.g., postgres://user:pass@host/db) or pre-configured connection names via environment variables/config.json, with support for default connections
Multiple Output Formats - Return results in JSON (default) or CSV format
Timeout Control - Configure query execution timeouts globally or per-request, with support for unlimited execution time
Multi-Database Support - Works with any database supported by usql (PostgreSQL, MySQL, Oracle, SQLite, SQL Server, and many others)
Raw CLI Output - Returns authentic usql output exactly as it appears on the command line
Easy Integration - Configurable for use with MCP clients such as Claude Desktop, Claude Code, Codex CLI, and GitHub Copilot
Enables execution of SQL queries and database operations against SQLite databases through the usql CLI, including query execution, table listing, and schema inspection.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@USQL MCP Servershow me the top 10 customers by total purchases"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
USQL MCP Server
usql-mcp is a full-featured MCP server that bridges the Model Context Protocol with the usql universal SQL CLI. It enables AI assistants and other MCP clients to query any database that usql supports, with enterprise-ready features like background execution, progress tracking, query safety validation, and intelligent caching.
✨ Key Features
🔌 Universal Database Access: Query PostgreSQL, MySQL, Oracle, SQLite, SQL Server, and 100+ other databases through a single interface
⚡ Background Execution: Long-running queries automatically move to background with job tracking and polling
📊 Progress Reporting: Real-time progress updates for long operations using MCP progress notifications
🛡️ Query Safety: Automatic risk analysis detects dangerous operations (DROP, DELETE without WHERE, etc.)
📚 SQL Workflow Templates: Built-in prompts for common tasks (query optimization, data profiling, migrations)
🗂️ Schema Resources: Browse database schemas through MCP resources (databases, tables, columns)
⚡ Performance: Schema caching and rate limiting for production deployments
🔒 Security: Credential sanitization, configurable operation blocking, audit-ready error messages
Related MCP server: Database MCP Server
MCP Capabilities
This server implements all 4 MCP capabilities:
Tools (8 tools): Execute queries, manage schemas, check job status
Resources: Browse database metadata via
sql://URIsPrompts: SQL workflow templates for common tasks
Progress: Real-time progress for long-running operations
Requirements
Node.js 16 or newer
npmusqlinstalled and available onPATH
Quick Launch with npx
Run the server directly via npx:
npx usql-mcpThis downloads the package and executes the CLI entry point, which runs the MCP server on stdio.
You can also run it directly from the repository using npm's Git support (the prepare script compiles the TypeScript automatically):
npx github:jvm/usql-mcpGetting Started
git clone https://github.com/jvm/usql-mcp.git
cd usql-mcp
npm install
npm run buildThe compiled files live in dist/. They are intentionally not committed—run npm run build whenever you need fresh output.
Configuring Connections
Define connection strings via environment variables (USQL_*) or a config.json file mirroring config.example.json. Each USQL_<NAME>=... entry becomes a reusable connection whose name is the lower-cased <name> portion (USQL_ORACLE1 → oracle1).
Environment Variables
Connection variables (any USQL_* except reserved keys below):
export USQL_POSTGRES="postgres://user:password@localhost:5432/mydb"
export USQL_SQLITE="sqlite:///$(pwd)/data/app.db"
export USQL_ORACLE1="oracle://user:secret@host1:1521/service"Reserved configuration variables:
USQL_CONFIG_PATH- Path to config.jsonUSQL_QUERY_TIMEOUT_MS- Default query timeout (leave unset for unlimited)USQL_DEFAULT_CONNECTION- Default connection name when omitted from tool callsUSQL_BINARY_PATH- Full path to usql binary (if not on PATH)USQL_BACKGROUND_THRESHOLD_MS- Threshold for background execution (default: 30000)USQL_JOB_RESULT_TTL_MS- How long to keep completed job results (default: 3600000 = 1 hour)
Configuration File
Create a config.json with connection details and server settings:
{
"connections": {
"postgres": {
"uri": "postgres://user:password@localhost:5432/mydb",
"description": "Production PostgreSQL database"
},
"sqlite": {
"uri": "sqlite:///path/to/database.db",
"description": "Local SQLite database"
}
},
"defaults": {
"defaultConnection": "postgres",
"queryTimeout": null,
"backgroundThresholdMs": 30000,
"jobResultTtlMs": 3600000,
"allowDestructiveOperations": true,
"blockHighRiskQueries": false,
"blockCriticalRiskQueries": false,
"requireWhereClauseForDelete": false,
"maxResultBytes": 10485760,
"rateLimitRpm": null,
"maxConcurrentRequests": 10,
"schemaCacheTtl": null
}
}Configuration Options:
queryTimeout: Milliseconds before query times out (null = unlimited)backgroundThresholdMs: Queries exceeding this move to background (default: 30000)jobResultTtlMs: How long to retain completed job results (default: 3600000)allowDestructiveOperations: If false, block DROP/TRUNCATE operationsblockHighRiskQueries: Block queries with risk level "high"blockCriticalRiskQueries: Block queries with risk level "critical"requireWhereClauseForDelete: Require WHERE clause on DELETE/UPDATEmaxResultBytes: Maximum result size in bytes (default: 10MB)rateLimitRpm: Requests per minute limit (null = no limit)schemaCacheTtl: Schema cache TTL in milliseconds (null = no caching)
Client Configuration
This section explains how to configure the usql-mcp server in different MCP clients.
Claude Desktop
Claude Desktop uses a configuration file to register MCP servers. The location depends on your operating system:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Add the following configuration to your claude_desktop_config.json:
{
"mcpServers": {
"usql": {
"command": "npx",
"args": ["-y", "usql-mcp"],
"env": {
"USQL_DEFAULT_CONNECTION": "oracle://user:secret@host:1521/service",
"USQL_POSTGRES": "postgres://user:password@localhost:5432/mydb",
"USQL_SQLITE": "sqlite:///path/to/database.db"
}
}
}
}After editing the configuration file, restart Claude Desktop for changes to take effect.
Claude Code
Claude Code (CLI) supports MCP servers through its configuration file located at:
All platforms:
~/.claudercor~/.config/claude/config.json
Add the MCP server to your Claude Code configuration:
{
"mcpServers": {
"usql": {
"command": "npx",
"args": ["-y", "usql-mcp"],
"env": {
"USQL_DEFAULT_CONNECTION": "oracle://user:secret@host:1521/service",
"USQL_POSTGRES": "postgres://user:password@localhost:5432/mydb",
"USQL_SQLITE": "sqlite:///path/to/database.db"
}
}
}
}The server will be available in your Claude Code sessions automatically.
Codex CLI
Codex CLI configuration varies by implementation, but typically uses a similar JSON configuration approach. Create or edit your Codex configuration file (usually ~/.codexrc or as specified in your Codex documentation):
{
"mcp": {
"servers": {
"usql": {
"command": "npx",
"args": ["-y", "usql-mcp"],
"env": {
"USQL_DEFAULT_CONNECTION": "oracle://user:secret@host:1521/service",
"USQL_POSTGRES": "postgres://user:password@localhost:5432/mydb",
"USQL_SQLITE": "sqlite:///path/to/database.db"
}
}
}
}
}Refer to your specific Codex CLI documentation for the exact configuration file location and format.
GitHub Copilot (VS Code)
GitHub Copilot in VS Code can use MCP servers through the Copilot Chat extension settings. Configuration is done through VS Code's settings.json:
Open VS Code Settings (JSON) via:
macOS:
Cmd + Shift + P→ "Preferences: Open User Settings (JSON)"Windows/Linux:
Ctrl + Shift + P→ "Preferences: Open User Settings (JSON)"
Add the MCP server configuration:
{
"github.copilot.chat.mcp.servers": {
"usql": {
"command": "npx",
"args": ["-y", "usql-mcp"],
"env": {
"USQL_DEFAULT_CONNECTION": "oracle://user:secret@host:1521/service",
"USQL_POSTGRES": "postgres://user:password@localhost:5432/mydb",
"USQL_SQLITE": "sqlite:///path/to/database.db"
}
}
}
}After saving the settings, reload VS Code or restart the Copilot extension for changes to take effect.
Environment Variables vs. Configuration
For all clients, you can choose between:
Inline environment variables (shown above) - Connection strings in the config file
System environment variables - Set
USQL_*variables in your shell profile
System environment approach:
# In ~/.bashrc, ~/.zshrc, or equivalent
export USQL_DEFAULT_CONNECTION="oracle://user:secret@host:1521/service"
export USQL_POSTGRES="postgres://user:password@localhost:5432/mydb"
export USQL_SQLITE="sqlite:///path/to/database.db"Then use a simpler client configuration:
{
"mcpServers": {
"usql": {
"command": "npx",
"args": ["-y", "usql-mcp"]
}
}
}Security Best Practices
Avoid hardcoding credentials: Use environment variables or secure credential stores
File permissions: Ensure configuration files with credentials are not world-readable (chmod 600)
Read-only access: Create database users with minimal required permissions for AI queries
Network security: Use SSL/TLS connections for remote databases
Audit logging: Enable database audit logs to track AI-generated queries
Query safety: Enable
blockCriticalRiskQueriesto prevent destructive operationsRate limiting: Set
rateLimitRpmto prevent abuse in multi-user environments
Tools Catalogue
Core SQL Tools
Tool | Purpose | Key Inputs |
| Run an arbitrary SQL statement |
|
| Execute a multi-statement script |
|
| List databases available on the server |
|
| List tables in the current database |
|
| Inspect table metadata via |
|
Background Job Management
Tool | Purpose | Key Inputs |
| Check status of a background job |
|
| Cancel a running background job |
|
Server Information
Tool | Purpose | Key Inputs |
| Get server configuration and stats | None (read-only) |
Resources
Access database metadata through MCP resources:
sql://connections- List all available connectionssql://{connection}/databases- List databases on a connectionsql://{connection}/{database}/tables- List tables in a databasesql://{connection}/{database}/table/{name}- Get detailed table schema
Example usage:
Read resource: sql://postgres/production/tables
Read resource: sql://postgres/production/table/usersPrompts
Built-in SQL workflow templates:
analyze_performance - Analyze query performance and suggest optimizations
profile_data_quality - Profile data quality (nulls, duplicates, distributions)
generate_migration - Generate database migration scripts
explain_schema - Create comprehensive schema documentation
optimize_query - Optimize a slow-running query
debug_slow_query - Systematically debug slow queries
Example usage:
Use prompt: analyze_performance
connection: postgres
query: SELECT * FROM large_table WHERE status = 'active'Background Execution
Queries that exceed the backgroundThresholdMs (default: 30 seconds) automatically move to background execution:
Initial Response: Tool returns a
job_idand status messagePolling: Use
get_job_statuswithwait_secondsto check progressResults: When complete,
get_job_statusreturns the full resultProgress: Real-time progress percentage (0-100) for running jobs
Cleanup: Jobs are automatically cleaned up after
jobResultTtlMs(default: 1 hour)
Example workflow:
// Initial query (takes >30s)
execute_query → {
"status": "background",
"job_id": "abc-123",
"message": "Query is taking longer than 30000ms. Use get_job_status to check progress.",
"started_at": "2025-01-15T10:30:00Z"
}
// Check status (waits up to 10s)
get_job_status(job_id: "abc-123", wait_seconds: 10) → {
"status": "running",
"job_id": "abc-123",
"progress": 45, // 45% complete
"elapsed_ms": 15000
}
// Eventually completes
get_job_status(job_id: "abc-123", wait_seconds: 10) → {
"status": "completed",
"job_id": "abc-123",
"result": { "format": "json", "content": "[...]" },
"elapsed_ms": 45000
}Query Safety Analysis
Every query is automatically analyzed for safety risks:
Risk Levels:
Low: Safe read-only queries
Medium: Modifying operations with WHERE clauses
High: Complex queries with many JOINs, missing indexes
Critical: Destructive operations (DROP, TRUNCATE, DELETE without WHERE)
Response includes analysis:
{
"format": "json",
"content": "[...]",
"safety_analysis": {
"risk_level": "critical",
"warnings": ["DELETE operation without WHERE clause"],
"dangerous_operations": ["DELETE"],
"complexity_score": 2,
"recommendations": ["Add WHERE clause to limit deletion scope"]
}
}Configuration options:
allowDestructiveOperations: false- Block all destructive operationsblockHighRiskQueries: true- Block queries with "high" riskblockCriticalRiskQueries: true- Block queries with "critical" riskrequireWhereClauseForDelete: true- Require WHERE on DELETE/UPDATE
Response Format
Successful calls return the exact stdout produced by usql, paired with the format indicator:
{
"format": "json", // or "csv"
"content": "[{\"id\":1,\"name\":\"Alice\"}]",
"elapsed_ms": 234,
"safety_analysis": {
"risk_level": "low",
"warnings": [],
"dangerous_operations": [],
"complexity_score": 1,
"recommendations": []
}
}Background job responses:
{
"status": "background",
"job_id": "uuid-string",
"message": "Query is taking longer than 30000ms. It will continue running in the background.",
"started_at": "2025-01-15T10:30:00.000Z",
"elapsed_ms": 30001
}If usql exits with a non-zero code, the handler forwards the message through the MCP error shape, keeping details like the sanitized connection string and original stderr.
Performance Features
Schema Caching
Enable caching to reduce subprocess overhead for metadata queries:
{
"defaults": {
"schemaCacheTtl": 300000 // 5 minutes
}
}Cached operations:
list_databaseslist_tablesdescribe_tableResource reads
Cache statistics available via get_server_info:
{
"schema_cache_stats": {
"hits": 42,
"misses": 8,
"size": 15,
"hit_rate": 0.840
}
}Rate Limiting
Protect your databases from abuse:
{
"defaults": {
"rateLimitRpm": 60, // 60 requests per minute
"maxConcurrentRequests": 10
}
}When limit exceeded:
{
"error": "RateLimitExceeded",
"message": "Rate limit exceeded: 60 requests per minute. Try again in 45 seconds.",
"details": {
"limit": 60,
"current": 60,
"resetInSeconds": 45
}
}Development
npm run dev– TypeScript compile in watch modenpm run build– emit ESM output todist/npm run lint– ESLint/Prettier rulesnpm run test– Jest unit tests (519 tests, comprehensive coverage)npm run type-check– stricttsc --noEmit
Debug logging follows the namespace in DEBUG=usql-mcp:*.
Architecture
See CLAUDE.md for coding agents guidelines and architecture documentation.
Key components:
Tools (
src/tools/) - MCP tool implementationsResources (
src/resources/) - MCP resource handlersPrompts (
src/prompts/) - SQL workflow templatesBackground Jobs (
src/usql/job-manager.ts) - Async execution trackingQuery Safety (
src/utils/query-safety-analyzer.ts) - Risk analysisCaching (
src/cache/schema-cache.ts) - Performance optimizationProgress (
src/notifications/progress-notifier.ts) - Real-time updates
Testing
# Run all tests
npm test
# Run specific test file
npm test -- execute-query.test.ts
# Run with coverage
npm test -- --coverage
# Integration tests (require usql installed)
npm test -- integrationTest coverage:
519 passing tests
Unit tests for all tools, utilities, and managers
Integration tests with real SQLite databases
Request tracking, pagination, and protocol compliance tests
Contributing
See CONTRIBUTING.md for contributor guidelines and CLAUDE.md for coding agents guidelines. Open an issue before large changes so we can keep the tooling lean and aligned with the MCP ecosystem.
License
MIT License - see LICENSE for details.
Credits
Built on top of the excellent usql universal database CLI by Kenneth Shaw and the Model Context Protocol by Anthropic.
Available Tools
5 toolsdescribe_tableA
Get detailed schema information for a specific table (columns, types, constraints)
| Name | Required | Description | Default |
|---|---|---|---|
| connection_string | No | Database connection URL or configured connection name (e.g., "oracle" for USQL_ORACLE) | |
| database | No | Optional database name (if not specified in connection) | |
| output_format | No | Output format for results (default: json) | |
| table | Yes | Table name to describe | |
| timeout_ms | No | Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden but lacks behavioral details. It doesn't disclose whether this is a read-only operation, what permissions are required, whether it's cached, rate limits, or what happens with invalid table names. The description only states what information is returned, not how the tool behaves.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core purpose. Every word contributes value - 'Get detailed schema information' establishes the action, 'for a specific table' specifies scope, and '(columns, types, constraints)' provides concrete examples of what's returned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with no annotations and no output schema, the description is adequate but incomplete. It explains what the tool does but lacks behavioral context and output format details. The schema handles parameter documentation well, but the description doesn't compensate for missing annotation coverage about safety, permissions, or error behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents all 5 parameters. The description doesn't add any parameter-specific information beyond what's in the schema descriptions. It mentions 'table' generically but doesn't provide additional context about table naming, case sensitivity, or schema qualification.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Get detailed schema information') and target resource ('for a specific table'), with explicit details about what information is returned ('columns, types, constraints'). It distinguishes from sibling tools like 'list_tables' (which lists tables) and 'execute_query' (which runs queries).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when detailed table schema is needed, but provides no explicit guidance on when to use this versus alternatives like 'list_tables' (which might provide basic table info) or 'execute_query' (which could query schema tables). No exclusions or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_queryC
Execute a SQL query against a database and return results
| Name | Required | Description | Default |
|---|---|---|---|
| connection_string | No | Database connection URL or configured connection name. Can be a full URL (e.g., "postgres://user:pass@localhost/db") or a connection name from env vars (e.g., "oracle" for USQL_ORACLE, "postgres" for USQL_POSTGRES) | |
| output_format | No | Output format for query results (default: json) | |
| parameters | No | Optional query parameters for prepared statements | |
| query | Yes | SQL query to execute (SELECT, INSERT, UPDATE, DELETE, etc.) | |
| timeout_ms | No | Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It mentions 'return results' but doesn't disclose critical behavioral traits: whether queries can modify data (INSERT/UPDATE/DELETE), authentication requirements, error handling, rate limits, or result size limitations. For a tool that could be destructive, this lack of transparency is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that directly states the tool's function. It's front-loaded with the core purpose and avoids unnecessary elaboration. Every word earns its place, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of database query execution (potential for data modification, security implications) and the absence of both annotations and output schema, the description is incomplete. It doesn't address safety, permissions, result formatting details, or error conditions, leaving significant gaps for an AI agent to navigate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, providing detailed documentation for all 5 parameters. The description adds minimal value beyond the schema, only implying that queries can include various SQL statements (SELECT, INSERT, etc.). It doesn't explain parameter interactions or provide additional context, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'execute' and resource 'SQL query against a database', specifying the action and target. It distinguishes from siblings like 'describe_table' or 'list_tables' by focusing on query execution rather than metadata retrieval. However, it doesn't explicitly differentiate from 'execute_script', which might have overlapping functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'execute_script' or other siblings. It doesn't mention prerequisites (e.g., database connectivity), appropriate query types, or scenarios where other tools might be better suited. Usage context is implied but not articulated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_scriptA
Execute a multi-statement SQL script against a database. All statements are executed in sequence.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_string | No | Database connection URL or configured connection name (e.g., "oracle" for USQL_ORACLE) | |
| output_format | No | Output format for results (default: json) | |
| script | Yes | Multi-line SQL script with one or more SQL statements separated by semicolons | |
| timeout_ms | No | Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses the sequential execution behavior, which is valuable. However, it lacks critical details like transaction handling (e.g., auto-commit, rollback on error), permissions required, or potential side-effects (e.g., data modification), leaving gaps for a mutation-capable tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core purpose ('Execute a multi-statement SQL script against a database') and adds essential behavioral context ('All statements are executed in sequence') without any wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations and no output schema, the description is incomplete for a tool that can mutate data. It lacks details on error handling, result format (beyond output_format param), or transactional behavior, which are crucial for safe usage. However, the purpose and basic execution flow are clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are well-documented in the schema. The description adds no additional parameter semantics beyond implying 'script' contains multiple statements, which is already covered. Baseline 3 is appropriate as the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('execute'), resource ('multi-statement SQL script'), and target ('against a database'), with explicit mention of sequential execution. It distinguishes from sibling tools like execute_query (likely single statement) and describe_table/list_tables (metadata queries).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for multi-statement scripts (vs. single statements), providing clear context. However, it doesn't explicitly state when NOT to use it (e.g., for single queries) or name alternatives like execute_query, leaving some ambiguity compared to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_databasesC
List all databases available on a database server
| Name | Required | Description | Default |
|---|---|---|---|
| connection_string | No | Database connection URL or configured connection name (e.g., "oracle" for USQL_ORACLE env var, or full URL like "postgres://localhost") | |
| output_format | No | Output format for results (default: json) | |
| timeout_ms | No | Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions listing databases but fails to describe what 'available' means (e.g., accessible vs. all), potential permissions required, rate limits, or output structure. This leaves significant gaps for a tool that interacts with a database server.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence that efficiently conveys the core purpose without unnecessary words. It's front-loaded and appropriately sized for a simple listing tool, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of database operations and the lack of annotations or output schema, the description is incomplete. It doesn't cover behavioral aspects like error handling, authentication needs, or result format details, which are crucial for an AI agent to use this tool effectively in context with its siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so the input schema fully documents all three parameters. The description adds no additional parameter information beyond what's in the schema, resulting in a baseline score of 3 as the schema handles the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List') and resource ('all databases available on a database server'), making the purpose immediately understandable. However, it doesn't differentiate this tool from sibling tools like 'list_tables' or 'describe_table' beyond the resource type, which keeps it from a perfect score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'list_tables' or 'describe_table', nor does it mention prerequisites such as needing a valid connection. It simply states what the tool does without context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesC
List all tables in a database
| Name | Required | Description | Default |
|---|---|---|---|
| connection_string | No | Database connection URL or configured connection name (e.g., "oracle" for USQL_ORACLE) | |
| database | No | Optional database name to list tables from (if not specified in connection) | |
| output_format | No | Output format for results (default: json) | |
| timeout_ms | No | Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden but only states the basic action without disclosing behavioral traits. It doesn't mention whether this is a read-only operation, potential performance impacts, error handling, or what the output looks like (structure, pagination, etc.).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with zero wasted words. It's front-loaded with the core purpose and appropriately sized for a simple list operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 4 parameters, no annotations, and no output schema, the description is insufficient. It doesn't explain return values, error conditions, or behavioral constraints, leaving significant gaps in understanding how to use the tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema fully documents all 4 parameters. The description adds no additional parameter semantics beyond implying a database context, which is already covered by the schema. This meets the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('List') and resource ('all tables in a database'), making the purpose immediately understandable. However, it doesn't differentiate from sibling tools like 'list_databases' or 'describe_table', which would require specifying scope or output differences.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'list_databases' (for databases instead of tables) or 'describe_table' (for detailed table metadata). It also doesn't mention prerequisites such as needing a valid connection string or database access.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
5 tool updates
v1.0.0- First observed
describe_table - First observed
execute_query - First observed
execute_script - First observed
list_databases - First observed
list_tables
TDQS
Each tool has a clearly distinct purpose with no overlap: describe_table focuses on table schema details, execute_query runs single queries, execute_script handles multi-statement scripts, list_databases enumerates databases, and list_tables enumerates tables. The descriptions make it easy for an agent to select the right tool for each task without confusion.
All tool names follow a consistent verb_noun pattern (e.g., describe_table, execute_query, list_databases) using snake_case throughout. This predictable naming scheme makes the tool set easy to navigate and understand at a glance.
With 5 tools, this server is well-scoped for its purpose of SQL database interaction. Each tool earns its place by covering essential operations: listing resources, describing schemas, and executing queries/scripts, without being too sparse or bloated.
The tool set provides strong coverage for core SQL operations, including listing databases/tables, describing schemas, and executing queries/scripts. A minor gap exists in CRUD lifecycle coverage—there are no explicit tools for creating, updating, or deleting databases or tables—but agents can work around this using execute_query or execute_script for such operations.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Query, join, profile, clean and convert CSV/JSON/Parquet with server-side DuckDB over MCP.
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables LLMs and agents to interact with relational databases (SQL Server, MySQL, PostgreSQL) through MCP tools. Supports executing queries, inserting records, listing tables, and exposing database schemas with secure credential management.-
- AlicenseNot gradedqualityCmaintenanceProvides universal database operations for AI assistants through MCP, supporting 40+ databases including PostgreSQL, MySQL, MongoDB, Redis, and SQLite with built-in introspection tools for schema exploration.8MIT
- AlicenseBqualityCmaintenanceEnables AI agents to interact with Microsoft SQL Server databases via MCP, supporting table listing, schema retrieval, and CRUD operations.31MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage and query SQLite databases through MCP tools, supporting CRUD operations, schema management, and saved views.3MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jvm/usql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server