Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/docs/database-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ The MCP Database Server provides a set of tools that Claude can use to interact
| `drop_table` | Remove a table from the database | `table_name`: Name of table<br/>`confirm`: Safety flag (must be true) |
| `list_tables` | Get a list of all tables | None |
| `describe_table` | View schema information for a table | `table_name`: Name of table |
| `list_indexes` | List all indexes in the database | None |
| `list_table_indexes` | List indexes for a specific table | `table_name`: Name of table |
| `describe_index` | Get detailed information about an index | `index_name`: Name of index<br/>`table_name`: Table name (optional) |
| `export_query` | Export query results as CSV/JSON | `query`: SQL SELECT statement<br/>`format`: "csv" or "json" |
| `append_insight` | Add a business insight to memo | `insight`: Text of insight |
| `list_insights` | List all business insights | None |
Expand Down Expand Up @@ -49,6 +52,28 @@ Create a new table called "CustomerFeedback" with columns for customer ID, ratin

Claude will use the `create_table` tool to define the new table.

### Index Management

To analyze database indexes for performance optimization:

```
Show me all indexes in the database
```

Claude will use the `list_indexes` tool to display all available indexes.

```
What indexes exist on the Users table?
```

Claude will use the `list_table_indexes` tool to show indexes specific to that table.

```
Give me detailed information about the idx_users_email index
```

Claude will use the `describe_index` tool to provide comprehensive index details.

### Exporting Data

To export query results:
Expand Down
188 changes: 188 additions & 0 deletions docs/docs/index-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Index Management Guide

Database indexes are crucial for query performance optimization. The MCP Database Server provides comprehensive tools to analyze, inspect, and understand your database indexes across all supported database types (SQLite, PostgreSQL, MySQL, and SQL Server).

## Overview

Index management tools help you:
- **Identify existing indexes** across your database
- **Analyze table-specific indexes** for optimization opportunities
- **Get detailed index information** including columns, uniqueness, and type
- **Optimize query performance** by understanding index usage

## Available Index Tools

### list_indexes
Lists all indexes in the database with basic information.

**Parameters:** None

**Example Usage:**
```
Show me all indexes in the database
```

**Sample Output:**
```json
{
"success": true,
"data": [
{
"name": "idx_users_email",
"table_name": "users",
"columns": ["email"],
"unique": true,
"type": "btree"
},
{
"name": "idx_orders_customer_id",
"table_name": "orders",
"columns": ["customer_id"],
"unique": false,
"type": "btree"
}
]
}
```

### list_table_indexes
Lists all indexes for a specific table.

**Parameters:**
- `table_name` (required): Name of the table to analyze

**Example Usage:**
```
What indexes exist on the users table?
```

**Sample Output:**
```json
{
"success": true,
"data": [
{
"name": "PRIMARY",
"table_name": "users",
"columns": ["id"],
"unique": true,
"type": "btree",
"primary": true
},
{
"name": "idx_users_email",
"table_name": "users",
"columns": ["email"],
"unique": true,
"type": "btree"
}
]
}
```

### describe_index
Provides detailed information about a specific index.

**Parameters:**
- `index_name` (required): Name of the index to describe
- `table_name` (optional): Table name for disambiguation

**Example Usage:**
```
Give me detailed information about the idx_users_email index
```

**Sample Output:**
```json
{
"success": true,
"data": {
"name": "idx_users_email",
"table_name": "users",
"unique": true,
"type": "btree",
"columns": [
{
"name": "email",
"position": 1,
"is_descending": false,
"type": "key"
}
],
"definition": "CREATE UNIQUE INDEX idx_users_email ON users (email)"
}
}
```

## Common Use Cases

### Performance Analysis
```
List all indexes and identify which tables might need optimization
```

### Index Audit
```
Show me all unique indexes in the database to understand data constraints
```

### Query Optimization
```
What indexes are available on the orders table for the customer_id column?
```

### Schema Documentation
```
Describe the primary key index on the products table
```

## Database-Specific Features

### SQLite
- Supports basic index information and PRAGMA index_info
- Automatically excludes system indexes (sqlite_*)

### PostgreSQL
- Provides index method information (btree, hash, gin, gist)
- Includes partial index conditions when available
- Shows primary key and unique constraint details

### MySQL
- Displays index types (BTREE, HASH, FULLTEXT)
- Shows column positions in composite indexes
- Includes key length information

### SQL Server
- Provides clustered vs non-clustered index information
- Shows included columns for covering indexes
- Displays index usage statistics when available

## Best Practices

1. **Regular Index Review**: Use `list_indexes` periodically to audit your database indexes

2. **Table-Specific Analysis**: Use `list_table_indexes` when optimizing queries for specific tables

3. **Detailed Investigation**: Use `describe_index` to understand complex composite indexes

4. **Performance Monitoring**: Combine index information with query analysis to identify optimization opportunities

5. **Cross-Database Compatibility**: Index tools work consistently across all supported database types

## Troubleshooting

### Common Issues

**Index Not Found**
- Verify the index name spelling
- Check if the index exists using `list_indexes`
- Ensure you have proper database permissions

**Empty Results**
- Confirm the table exists using `list_tables`
- Check if the table has any indexes defined
- Verify database connection is active

**Permission Errors**
- Ensure your database user has SELECT permissions on system tables
- Check database-specific permission requirements for metadata access
1 change: 1 addition & 0 deletions docs/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const sidebars: SidebarsConfig = {
label: 'Usage',
items: [
'database-tools',
'index-management',
'usage-examples',
],
},
Expand Down
13 changes: 13 additions & 0 deletions src/db/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ export interface DbAdapter {
* @param tableName Table name
*/
getDescribeTableQuery(tableName: string): string;

/**
* Get database-specific query for listing indexes
* @param tableName Optional table name to filter indexes
*/
getListIndexesQuery(tableName?: string): string;

/**
* Get database-specific query for describing an index
* @param indexName Index name
* @param tableName Optional table name for disambiguation
*/
getDescribeIndexQuery(indexName: string, tableName?: string): string;
}

// Import adapters using dynamic imports
Expand Down
25 changes: 24 additions & 1 deletion src/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,27 @@ export function getDescribeTableQuery(tableName: string): string {
throw new Error("Database not initialized");
}
return dbAdapter.getDescribeTableQuery(tableName);
}
}

/**
* Get database-specific query for listing indexes
* @param tableName Optional table name to filter indexes
*/
export function getListIndexesQuery(tableName?: string): string {
if (!dbAdapter) {
throw new Error("Database not initialized");
}
return dbAdapter.getListIndexesQuery(tableName);
}

/**
* Get database-specific query for describing an index
* @param indexName Index name
* @param tableName Optional table name for disambiguation
*/
export function getDescribeIndexQuery(indexName: string, tableName?: string): string {
if (!dbAdapter) {
throw new Error("Database not initialized");
}
return dbAdapter.getDescribeIndexQuery(indexName, tableName);
}
62 changes: 61 additions & 1 deletion src/db/mysql-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,64 @@ export class MysqlAdapter implements DbAdapter {
getDescribeTableQuery(tableName: string): string {
return `DESCRIBE \`${tableName}\``;
}
}

/**
* Get database-specific query for listing indexes
* @param tableName Optional table name to filter indexes
*/
getListIndexesQuery(tableName?: string): string {
let query = `
SELECT
INDEX_NAME as name,
TABLE_NAME as table_name,
COLUMN_NAME as column_name,
NON_UNIQUE as is_unique,
INDEX_TYPE as type
FROM
information_schema.STATISTICS
WHERE
TABLE_SCHEMA = DATABASE()
`;

if (tableName) {
query += ` AND TABLE_NAME = ?`;
}

query += ` ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX`;
return query;
}

/**
* Get database-specific query for describing an index
* @param indexName Index name
* @param tableName Optional table name for disambiguation
*/
getDescribeIndexQuery(indexName: string, tableName?: string): string {
let query = `
SELECT
s.INDEX_NAME as name,
s.TABLE_NAME as table_name,
s.COLUMN_NAME as column_name,
s.NON_UNIQUE as is_unique,
s.INDEX_TYPE as type,
s.SEQ_IN_INDEX as column_position,
s.CARDINALITY,
s.SUB_PART,
s.NULLABLE,
s.INDEX_COMMENT as comment,
CASE WHEN s.NON_UNIQUE = 0 THEN 1 ELSE 0 END as unique_constraint
FROM
information_schema.STATISTICS s
WHERE
s.TABLE_SCHEMA = DATABASE()
AND s.INDEX_NAME = ?
`;

if (tableName) {
query += ` AND s.TABLE_NAME = ?`;
}

query += ` ORDER BY s.SEQ_IN_INDEX`;
return query;
}
}
Loading