{"record":{"id":"81284ee6235d522e","repo":"apache/shardingsphere","slug":"statement-is-not-supported-by-the-mcp-contract","errorCode":null,"errorMessage":"Statement is not supported by the MCP contract.","messagePattern":"Statement is not supported by the MCP contract\\.","errorType":"exception","errorClass":"MCPUnsupportedSQLStatementException","httpStatus":null,"severity":"error","filePath":"mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPStatementAnalyzer.java","lineNumber":82,"sourceCode":"    \n    ClassificationResult analyze(final String sql, final MCPDatabaseCapability databaseCapability) {\n        String databaseType = databaseCapability.getDatabaseType();\n        SQLStatementScanner scanner = new SQLStatementScanner(databaseType, sql);\n        String actualSql = scanner.sql();\n        String leadingSql = scanner.leadingSql();\n        String upperLeadingSql = leadingSql.toUpperCase(Locale.ENGLISH);\n        SQLStatementSafetyValidator safetyValidator = new SQLStatementSafetyValidator();\n        safetyValidator.checkLeadingStatement(upperLeadingSql, scanner.containsExecutableComment());\n        if (isSavepointStatement(upperLeadingSql)) {\n            return analyzeSavepointStatement(actualSql, leadingSql, upperLeadingSql);\n        }\n        if (isTransactionControlStatement(upperLeadingSql)) {\n            return createTCLResult(SupportedMCPStatement.TRANSACTION_CONTROL, extractTransactionStatementType(upperLeadingSql), actualSql, \"\");\n        }\n        SQLStatement sqlStatement = parse(actualSql, databaseType);\n        safetyValidator.checkParsedStatement(sqlStatement);\n        if (sqlStatement instanceof TCLStatement) {\n            throw new MCPUnsupportedSQLStatementException();\n        }\n        boolean ruleDistSQL = isRuleDistSQL(sqlStatement);\n        String leadingKeyword = scanner.extractLeadingKeyword();\n        SupportedMCPStatement statementClass = resolveStatementClass(sqlStatement, leadingKeyword, ruleDistSQL);\n        String statementType = resolveStatementType(sqlStatement, statementClass, leadingKeyword);\n        return new ClassificationResult(statementClass, statementType, actualSql, \"\", new SQLStatementObjectExtractor().extract(sqlStatement), ruleDistSQL);\n    }\n    \n    private ClassificationResult analyzeSavepointStatement(final String actualSql, final String leadingSql, final String upperLeadingSql) {\n        String savepointName = extractSavepointName(leadingSql);\n        ShardingSpherePreconditions.checkState(!savepointName.isEmpty(), () -> new MCPInvalidRequestException(\"Savepoint name is required.\"));\n        return createTCLResult(SupportedMCPStatement.SAVEPOINT, extractTransactionStatementType(upperLeadingSql), actualSql, savepointName);\n    }\n    \n    private ClassificationResult createTCLResult(final SupportedMCPStatement statementClass, final String statementType, final String sql, final String savepointName) {\n        return new ClassificationResult(statementClass, statementType, sql, savepointName, Set.of(), false);\n    }\n    ","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPStatementAnalyzer.java#L64-L100","documentation":"In MCPStatementAnalyzer.analyze, a statement that parses successfully but turns out to be a TCLStatement (transaction control other than the recognized leading-keyword forms handled earlier, e.g. SET TRANSACTION or dialect-specific transaction SQL) throws MCPUnsupportedSQLStatementException ('Statement is not supported by the MCP contract.'). Only BEGIN/START TRANSACTION/COMMIT/ROLLBACK and SAVEPOINT forms recognized by the leading-keyword fast paths are supported; other TCL shapes fall through to this guard.","triggerScenarios":"Sending SET TRANSACTION ..., SET SESSION CHARACTERISTICS, or other parseable TCL statements that bypass isTransactionControlStatement/isSavepointStatement keyword checks and surface as parsed TCLStatement instances.","commonSituations":"Boilerplate connection scripts that issue SET TRANSACTION ISOLATION LEVEL ...; ORM-generated session setup SQL; copying transaction management SQL into MCP tool calls instead of using the transaction tools.","solutions":["Remove SET TRANSACTION / session-configuration statements from the SQL sent to MCP execution tools.","Manage isolation and transaction boundaries through the dedicated transaction control tool/path (COMMIT/ROLLBACK/SAVEPOINT forms).","Configure isolation at the datasource level instead of per-statement."],"exampleFix":"// before\nawait tools.call('database_gateway_execute_update', { sql: 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', execution_mode: 'execute' }); // unsupported\n\n// after: set isolation on the datasource, not via MCP SQL\nawait tools.call('database_gateway_execute_query', { sql: 'SELECT * FROM t' });","handlingStrategy":"validation","validationCode":"const UNSUPPORTED_TCL = /^\\s*SET\\s+(TRANSACTION|SESSION|CHARACTERISTICS|CONSTRAINT|CONSTRAINTS)\\b/i;\nif (UNSUPPORTED_TCL.test(sql)) {\n  throw new Error('Session/transaction configuration SQL is unsupported; configure the datasource instead.');\n}\nreturn tools.call('database_gateway_execute_update', { sql, execution_mode });","typeGuard":"function isSupportedTransactionSql(sql) {\n  return /^\\s*(BEGIN(\\s+WORK)?|START\\s+TRANSACTION|COMMIT(\\s+WORK)?|ROLLBACK(\\s+WORK)?(\\s+TO\\s+SAVEPOINT\\s+\\S+)?|SAVEPOINT\\s+\\S+|RELEASE\\s+SAVEPOINT\\s+\\S+)\\s*;?\\s*$/i.test(sql);\n}","tryCatchPattern":"try {\n  return await tools.call('database_gateway_execute_update', { sql, execution_mode });\n} catch (e) {\n  if (/not supported by the MCP contract/.test(e.message) && /^\\s*SET\\s/i.test(sql)) {\n    // drop the SET TRANSACTION statement; move setting to datasource config\n    return { skipped: sql };\n  }\n  throw e;\n}","preventionTips":["Keep transaction/session configuration out of MCP-bound SQL.","Use only the recognized BEGIN/COMMIT/ROLLBACK/SAVEPOINT forms via the transaction tool.","Configure isolation levels on the JDBC datasource."],"tags":["mcp","sql","transactions","parser","unsupported"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}