Skip to content

Commit f9a642d

Browse files
committed
feat(database): add MCP tool for fetching database schema #330 and closed #330
- Introduce `DatabaseMcpToolProvider` to handle fetching current database schema. - Move `listSchemas` logic to `DatabaseSchemaAssistant` for reuse. - Update `DatabaseFunctionProvider` to use `DatabaseSchemaAssistant.listSchemas`.
1 parent 4f7b3d1 commit f9a642d

File tree

4 files changed

+45
-24
lines changed

4 files changed

+45
-24
lines changed

exts/ext-database/src/main/kotlin/cc/unitmesh/database/provider/DatabaseFunctionProvider.kt

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import cc.unitmesh.devti.devin.dataprovider.BuiltinCommand
88
import cc.unitmesh.devti.provider.toolchain.ToolchainFunctionProvider
99
import com.intellij.database.model.DasTable
1010
import com.intellij.database.model.RawDataSource
11-
import com.intellij.database.util.DasUtil
12-
import com.intellij.database.util.DbUtil
1311
import com.intellij.openapi.diagnostic.logger
1412
import com.intellij.openapi.project.Project
1513

@@ -33,33 +31,13 @@ class DatabaseFunctionProvider : ToolchainFunctionProvider {
3331
?: throw IllegalArgumentException("[Database]: Invalid Database function name")
3432

3533
return when (databaseFunction) {
36-
DatabaseFunction.Schema -> listSchemas(args, project)
34+
DatabaseFunction.Schema -> DatabaseSchemaAssistant.listSchemas(project)
3735
DatabaseFunction.Table -> executeTableFunction(args, project)
3836
DatabaseFunction.Column -> executeColumnFunction(args, project)
3937
DatabaseFunction.Query -> executeSqlFunction(args, project)
4038
}
4139
}
4240

43-
private fun listSchemas(args: List<Any>, project: Project): String {
44-
val dataSources = DbUtil.getDataSources(project)
45-
if (dataSources.isEmpty) return "[Database]: No database found"
46-
47-
val dataItems = dataSources.mapNotNull {
48-
val tableSchema = DasUtil.getTables(it).toList().mapNotNull<DasTable, String> {
49-
if (it.dasParent?.name == "information_schema") return@mapNotNull null
50-
getTableColumn(it)
51-
}
52-
53-
if (tableSchema.isEmpty()) return@mapNotNull null
54-
val name = it.name.substringBeforeLast('@')
55-
"Database Schema result:\n\n```sql\n-- DATABASE NAME: ${name};\n${tableSchema.joinToString("\n")}\n```\n"
56-
}
57-
58-
if (dataItems.isEmpty()) return "[Database]: No table found"
59-
60-
return dataItems.joinToString("\n")
61-
}
62-
6341
private fun executeTableFunction(args: List<Any>, project: Project): String {
6442
if (args.isEmpty()) {
6543
val dataSource = DatabaseSchemaAssistant.allRawDatasource(project).firstOrNull()
@@ -195,4 +173,4 @@ class DatabaseFunctionProvider : ToolchainFunctionProvider {
195173
?: return emptyList()
196174
return DatabaseSchemaAssistant.getTableByDataSource(database)
197175
}
198-
}
176+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package cc.unitmesh.database.provider
2+
3+
import cc.unitmesh.database.util.DatabaseSchemaAssistant
4+
import cc.unitmesh.devti.mcp.AbstractMcpTool
5+
import cc.unitmesh.devti.mcp.NoArgs
6+
import cc.unitmesh.devti.mcp.Response
7+
import com.intellij.openapi.project.Project
8+
9+
class DatabaseMcpToolProvider : AbstractMcpTool<NoArgs>() {
10+
override val name: String = "get_current_database_schema"
11+
12+
override val description: String = """
13+
Get the current database schema which connect in IntelliJ IDEA.
14+
""".trimIndent()
15+
16+
override fun handle(project: Project, args: NoArgs): Response {
17+
val listSchemas = DatabaseSchemaAssistant.listSchemas(project)
18+
return Response(listSchemas)
19+
}
20+
}

exts/ext-database/src/main/kotlin/cc/unitmesh/database/util/DatabaseSchemaAssistant.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,33 @@ import com.intellij.database.model.RawDataSource
66
import com.intellij.database.psi.DbDataSource
77
import com.intellij.database.psi.DbPsiFacade
88
import com.intellij.database.util.DasUtil
9+
import com.intellij.database.util.DbUtil
910
import com.intellij.openapi.project.Project
1011
import com.intellij.sql.isNullOr
1112

1213
object DatabaseSchemaAssistant {
1314
fun getDataSources(project: Project): List<DbDataSource> = DbPsiFacade.getInstance(project).dataSources.toList()
1415

16+
fun listSchemas(project: Project): String {
17+
val dataSources = DbUtil.getDataSources(project)
18+
if (dataSources.isEmpty) return "[Database]: No database found"
19+
20+
val dataItems = dataSources.mapNotNull {
21+
val tableSchema = DasUtil.getTables(it).toList().mapNotNull<DasTable, String> {
22+
if (it.dasParent?.name == "information_schema") return@mapNotNull null
23+
getTableColumn(it)
24+
}
25+
26+
if (tableSchema.isEmpty()) return@mapNotNull null
27+
val name = it.name.substringBeforeLast('@')
28+
"Database Schema result:\n\n```sql\n-- DATABASE NAME: ${name};\n${tableSchema.joinToString("\n")}\n```\n"
29+
}
30+
31+
if (dataItems.isEmpty()) return "[Database]: No table found"
32+
33+
return dataItems.joinToString("\n")
34+
}
35+
1536
fun allRawDatasource(project: Project): List<RawDataSource> {
1637
val dbPsiFacade = DbPsiFacade.getInstance(project)
1738
return dbPsiFacade.dataSources.map { dataSource ->

exts/ext-database/src/main/resources/cc.unitmesh.database.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,7 @@
3838
<livingDocumentation
3939
language="Oracle"
4040
implementationClass="cc.unitmesh.database.provider.SqlLivingDocumentationProvider"/>
41+
42+
<mcpTool implementation="cc.unitmesh.database.provider.DatabaseMcpToolProvider"/>
4143
</extensions>
4244
</idea-plugin>

0 commit comments

Comments
 (0)