@rex0220/kintone-sql-tools 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38428,7 +38428,7 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38428
38428
  }
38429
38429
  return toSelectPayload(result);
38430
38430
  }
38431
- async function mutateBatch(input, validation, dmlMaxRows2) {
38431
+ async function mutateBatch(input, validation, dmlMaxRows) {
38432
38432
  if (!validation.containsDml) {
38433
38433
  throw new Error("ArgumentError: batch contains no DML statements. Use ksql_query.");
38434
38434
  }
@@ -38447,9 +38447,9 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38447
38447
  if ((s.statementType === "UPDATE" || s.statementType === "DELETE") && !s.hasWhere) {
38448
38448
  throw new Error(`ArgumentError: ${s.statementType} without WHERE is blocked by ksql_mutate.${at}`);
38449
38449
  }
38450
- if (s.insertValuesCount !== null && s.insertValuesCount > dmlMaxRows2) {
38450
+ if (s.insertValuesCount !== null && s.insertValuesCount > dmlMaxRows) {
38451
38451
  throw new Error(
38452
- `ArgumentError: INSERT rows (${s.insertValuesCount}) exceed dmlMaxRows (${dmlMaxRows2}).${at}`
38452
+ `ArgumentError: INSERT rows (${s.insertValuesCount}) exceed dmlMaxRows (${dmlMaxRows}).${at}`
38453
38453
  );
38454
38454
  }
38455
38455
  staticInsertTotal += s.insertValuesCount ?? 0;
@@ -38463,7 +38463,7 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38463
38463
  const runtime = await createRuntime(serverOptions, {
38464
38464
  sql: input.sql,
38465
38465
  profile: input.profile,
38466
- maxRecords: dmlMaxRows2 + 1,
38466
+ maxRecords: dmlMaxRows + 1,
38467
38467
  fetchParallel: input.fetchParallel,
38468
38468
  onLimit: DEFAULT_ON_LIMIT,
38469
38469
  timeout: input.timeout
@@ -38477,8 +38477,8 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38477
38477
  // 合計タイムアウト(解決済みの runtime.timeout。per-request と同値)
38478
38478
  timeoutMs: runtime.timeout,
38479
38479
  confirm: async (count, operation) => {
38480
- if (count > dmlMaxRows2) {
38481
- throw new Error(`ArgumentError: ${operation} affected rows (${count}) exceed dmlMaxRows (${dmlMaxRows2}).`);
38480
+ if (count > dmlMaxRows) {
38481
+ throw new Error(`ArgumentError: ${operation} affected rows (${count}) exceed dmlMaxRows (${dmlMaxRows}).`);
38482
38482
  }
38483
38483
  totalAffected += count;
38484
38484
  if (dmlTotalMaxRows !== void 0 && totalAffected > dmlTotalMaxRows) {
@@ -38492,27 +38492,32 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38492
38492
  return toBatchQueryPayload(batchResult);
38493
38493
  }
38494
38494
  async function mutate(input) {
38495
- const dmlMaxRows2 = requireDmlApproval(input, "ksql_mutate");
38495
+ const dmlMaxRows = requireDmlApproval(input, "ksql_mutate");
38496
38496
  const validation = await validate(input);
38497
38497
  if (validation.batch) {
38498
- return mutateBatch(input, validation, dmlMaxRows2);
38498
+ return mutateBatch(input, validation, dmlMaxRows);
38499
38499
  }
38500
38500
  if (!validation.isDml) {
38501
38501
  throw new Error(`ArgumentError: ${validation.statementType} is not allowed by ksql_mutate. Use ksql_query.`);
38502
38502
  }
38503
- if (validation.statementType === "INSERT_SELECT" || validation.statementType === "UPSERT_SELECT") {
38503
+ if (validation.statementType === "INSERT_SELECT") {
38504
+ throw new Error(
38505
+ "ArgumentError: INSERT_SELECT is not supported by ksql_mutate as a single statement. Wrap it in a batch: CREATE TEMP TABLE #t AS SELECT ...; INSERT INTO APPx (...) SELECT ... FROM #t;"
38506
+ );
38507
+ }
38508
+ if (validation.statementType === "UPSERT_SELECT") {
38504
38509
  throw new Error(`ArgumentError: ${validation.statementType} is not supported by ksql_mutate yet.`);
38505
38510
  }
38506
38511
  if ((validation.statementType === "UPDATE" || validation.statementType === "DELETE") && !validation.hasWhere) {
38507
38512
  throw new Error(`ArgumentError: ${validation.statementType} without WHERE is blocked by ksql_mutate.`);
38508
38513
  }
38509
- if (validation.insertValuesCount !== null && validation.insertValuesCount > dmlMaxRows2) {
38510
- throw new Error(`ArgumentError: INSERT rows (${validation.insertValuesCount}) exceed dmlMaxRows (${dmlMaxRows2}).`);
38514
+ if (validation.insertValuesCount !== null && validation.insertValuesCount > dmlMaxRows) {
38515
+ throw new Error(`ArgumentError: INSERT rows (${validation.insertValuesCount}) exceed dmlMaxRows (${dmlMaxRows}).`);
38511
38516
  }
38512
38517
  const runtime = await createRuntime(serverOptions, {
38513
38518
  sql: input.sql,
38514
38519
  profile: input.profile,
38515
- maxRecords: dmlMaxRows2 + 1,
38520
+ maxRecords: dmlMaxRows + 1,
38516
38521
  fetchParallel: input.fetchParallel,
38517
38522
  onLimit: DEFAULT_ON_LIMIT,
38518
38523
  timeout: input.timeout
@@ -38523,8 +38528,8 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38523
38528
  onLimitReached: runtime.onLimit,
38524
38529
  cacheContext: runtime.cacheContext,
38525
38530
  confirm: async (count, operation) => {
38526
- if (count > dmlMaxRows2) {
38527
- throw new Error(`ArgumentError: ${operation} affected rows (${count}) exceed dmlMaxRows (${dmlMaxRows2}).`);
38531
+ if (count > dmlMaxRows) {
38532
+ throw new Error(`ArgumentError: ${operation} affected rows (${count}) exceed dmlMaxRows (${dmlMaxRows}).`);
38528
38533
  }
38529
38534
  return true;
38530
38535
  }
@@ -38631,13 +38636,13 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38631
38636
  result: result2
38632
38637
  };
38633
38638
  }
38634
- const dmlMaxRows2 = requireDmlApproval(input, "ksql_run_saved_query", "for DML saved queries");
38639
+ const dmlMaxRows = requireDmlApproval(input, "ksql_run_saved_query", "for DML saved queries");
38635
38640
  const result = await mutate({
38636
38641
  sql: saved.sql,
38637
38642
  profile: profile2,
38638
38643
  allowDml: true,
38639
38644
  confirmText: "yes",
38640
- dmlMaxRows: dmlMaxRows2,
38645
+ dmlMaxRows,
38641
38646
  fetchParallel: input.fetchParallel,
38642
38647
  timeout: input.timeout
38643
38648
  });
@@ -38685,48 +38690,43 @@ function createKsqlMcpTools(serverOptions, deps = {}) {
38685
38690
  }
38686
38691
 
38687
38692
  // src/mcp/schemas.ts
38688
- var profile = external_exports.string().min(1).optional();
38689
- var maxRecords = external_exports.number().int().positive().optional();
38690
- var fetchParallel = external_exports.number().int().min(1).max(10).optional();
38691
- var onLimit = external_exports.enum(["error", "truncate"]).optional();
38692
- var timeout = external_exports.number().int().positive().optional();
38693
- var dmlMaxRows = external_exports.number().int().positive();
38694
- var savedQueryName = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/);
38695
- var savedQueryTags = external_exports.array(external_exports.string().min(1)).optional();
38693
+ var profile = external_exports.string().min(1).describe("kintone connection profile name from ksql.config.json (default: the server's default profile).").optional();
38694
+ var maxRecords = external_exports.number().int().positive().describe("Maximum records fetched per SELECT (default 500).").optional();
38695
+ var fetchParallel = external_exports.number().int().min(1).max(10).describe("Number of parallel kintone record-fetch requests (1-10).").optional();
38696
+ var onLimit = external_exports.enum(["error", "truncate"]).describe("Behavior when maxRecords is exceeded: 'error' rejects, 'truncate' returns the first maxRecords rows (default 'error').").optional();
38697
+ var timeout = external_exports.number().int().positive().describe("Request timeout in milliseconds. For multi-statement batches this also acts as the total batch deadline.").optional();
38698
+ var savedQueryName = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/).describe("Saved query name (alphanumeric, '_' and '-', up to 64 chars).");
38699
+ var savedQueryTags = external_exports.array(external_exports.string().min(1)).describe("Tags for organizing saved queries.").optional();
38696
38700
  var validateInputSchema = external_exports.object({
38697
- sql: external_exports.string().min(1),
38701
+ sql: external_exports.string().min(1).describe("kSQL text to validate. May contain multiple ;-separated statements (batch) and temp tables (#name)."),
38698
38702
  profile
38699
38703
  });
38700
38704
  var explainInputSchema = external_exports.object({
38701
- sql: external_exports.string().min(1),
38705
+ sql: external_exports.string().min(1).describe("kSQL text to explain. May contain multiple ;-separated statements (batch) and temp tables (#name)."),
38702
38706
  profile
38703
38707
  });
38704
38708
  var queryInputSchema = external_exports.object({
38705
- sql: external_exports.string().min(1),
38709
+ sql: external_exports.string().min(1).describe("Read-only kSQL text. May contain multiple ;-separated statements (batch) with temp tables, e.g. CREATE TEMP TABLE #t AS SELECT ...; SELECT ... FROM #t;"),
38706
38710
  profile,
38707
38711
  maxRecords,
38708
38712
  fetchParallel,
38709
38713
  onLimit,
38710
38714
  timeout,
38711
- /** バッチ(複文)専用: 実行時エラー後も後続文を実行する(既定 false = fail-fast) */
38712
- continueOnError: external_exports.boolean().optional(),
38713
- /** バッチ(複文)専用: 返却する結果セットの合計行数上限(既定なし) */
38714
- maxTotalRecords: external_exports.number().int().positive().optional()
38715
+ continueOnError: external_exports.boolean().describe("Batch (multi-statement) only: keep executing subsequent statements after a runtime error (default false = fail-fast).").optional(),
38716
+ maxTotalRecords: external_exports.number().int().positive().describe("Batch (multi-statement) only: cap on total rows returned across all result sets (default: unlimited).").optional()
38715
38717
  });
38716
38718
  var mutateInputSchema = external_exports.object({
38717
- sql: external_exports.string().min(1),
38719
+ sql: external_exports.string().min(1).describe("DML kSQL text. May contain multiple ;-separated statements (batch) with temp tables, e.g. CREATE TEMP TABLE #t AS SELECT ...; INSERT INTO APPx (...) SELECT ... FROM #t;"),
38718
38720
  profile,
38719
- allowDml: external_exports.literal(true),
38720
- confirmText: external_exports.literal("yes"),
38721
- dmlMaxRows,
38721
+ allowDml: external_exports.literal(true).describe("Must be true to acknowledge that this call writes to kintone."),
38722
+ confirmText: external_exports.literal("yes").describe('Must be the literal string "yes" to confirm execution.'),
38723
+ dmlMaxRows: external_exports.number().int().positive().describe("Per-statement cap on affected rows. The call fails before writing if any statement would exceed it."),
38722
38724
  fetchParallel,
38723
38725
  timeout,
38724
- /** バッチ(複文)専用: バッチ合計の影響行数上限(既定なし = 文ごとの dmlMaxRows のみ)
38725
- * なお DML バッチに continueOnError は存在しない(常に fail-fast) */
38726
- dmlTotalMaxRows: dmlMaxRows.optional()
38726
+ dmlTotalMaxRows: external_exports.number().int().positive().describe("Batch (multi-statement) only: cap on total affected rows across the whole batch (default: per-statement dmlMaxRows only). DML batches always run fail-fast.").optional()
38727
38727
  });
38728
38728
  var describeAppInputSchema = external_exports.object({
38729
- app: external_exports.number().int().positive(),
38729
+ app: external_exports.number().int().positive().describe("kintone app ID to describe."),
38730
38730
  profile,
38731
38731
  maxRecords,
38732
38732
  fetchParallel,
@@ -38743,12 +38743,12 @@ var showAppsInputSchema = external_exports.object({
38743
38743
  var listQueriesInputSchema = external_exports.object({});
38744
38744
  var saveQueryInputSchema = external_exports.object({
38745
38745
  name: savedQueryName,
38746
- title: external_exports.string().min(1).optional(),
38747
- description: external_exports.string().min(1).optional(),
38748
- sql: external_exports.string().min(1),
38749
- defaultProfile: external_exports.string().min(1),
38750
- readOnly: external_exports.boolean(),
38751
- allowProfileOverride: external_exports.boolean().optional(),
38746
+ title: external_exports.string().min(1).describe("Human-readable title.").optional(),
38747
+ description: external_exports.string().min(1).describe("What the query does and when to use it.").optional(),
38748
+ sql: external_exports.string().min(1).describe("kSQL text to save (single statement only)."),
38749
+ defaultProfile: external_exports.string().min(1).describe("Profile the saved query runs against by default."),
38750
+ readOnly: external_exports.boolean().describe("true for read-only queries; false marks the saved query as DML (requires mutate safety inputs at run time)."),
38751
+ allowProfileOverride: external_exports.boolean().describe("Allow overriding the profile at run time (default false).").optional(),
38752
38752
  tags: savedQueryTags
38753
38753
  });
38754
38754
  var savedQueryNameInputSchema = external_exports.object({
@@ -38761,9 +38761,9 @@ var runSavedQueryInputSchema = external_exports.object({
38761
38761
  fetchParallel,
38762
38762
  onLimit,
38763
38763
  timeout,
38764
- allowDml: external_exports.literal(true).optional(),
38765
- confirmText: external_exports.literal("yes").optional(),
38766
- dmlMaxRows: dmlMaxRows.optional()
38764
+ allowDml: external_exports.literal(true).describe("Required for DML saved queries: must be true to acknowledge writes.").optional(),
38765
+ confirmText: external_exports.literal("yes").describe('Required for DML saved queries: must be the literal string "yes".').optional(),
38766
+ dmlMaxRows: external_exports.number().int().positive().describe("Required for DML saved queries: per-statement cap on affected rows.").optional()
38767
38767
  });
38768
38768
  var validateInputShape = validateInputSchema.shape;
38769
38769
  var explainInputShape = explainInputSchema.shape;
@@ -38812,10 +38812,11 @@ Options:
38812
38812
  -h, --help Show help
38813
38813
  `);
38814
38814
  }
38815
+ var SERVER_VERSION = true ? "1.4.1" : "0.0.0-dev";
38815
38816
  function createServer(args) {
38816
38817
  const server = new McpServer({
38817
38818
  name: "ksql-mcp",
38818
- version: "1.0.0"
38819
+ version: SERVER_VERSION
38819
38820
  });
38820
38821
  const tools = createKsqlMcpTools({
38821
38822
  configPath: args.configPath,
@@ -38833,12 +38834,12 @@ function createServer(args) {
38833
38834
  }, tools.explainTool);
38834
38835
  server.registerTool("ksql_query", {
38835
38836
  title: "Run read-only kSQL",
38836
- description: "Execute read-only kSQL statements such as SELECT, WITH, UNION, EXPLAIN, SHOW APPS, and DESCRIBE. DML is rejected.",
38837
+ description: "Execute read-only kSQL: SELECT, WITH, UNION, EXPLAIN, SHOW APPS, DESCRIBE. Supports multi-statement batches with temp tables (CREATE TEMP TABLE #t AS SELECT ...; SELECT ... FROM #t;). DML is rejected.",
38837
38838
  inputSchema: queryInputShape
38838
38839
  }, tools.queryTool);
38839
38840
  server.registerTool("ksql_mutate", {
38840
38841
  title: "Run mutating kSQL",
38841
- description: "Execute DML kSQL with explicit allowDml, confirmText, and dmlMaxRows safety controls. INSERT_SELECT and UPSERT_SELECT are rejected.",
38842
+ description: "Execute DML kSQL with explicit allowDml, confirmText, and dmlMaxRows safety controls. Supports multi-statement DML batches with temp tables. INSERT INTO app ... SELECT is allowed in a batch when it selects only from temp tables (CREATE TEMP TABLE #t AS SELECT ...; INSERT INTO APPx (...) SELECT ... FROM #t;). Standalone INSERT_SELECT and UPSERT_SELECT are rejected.",
38842
38843
  inputSchema: mutateInputShape
38843
38844
  }, tools.mutateTool);
38844
38845
  server.registerTool("ksql_describe_app", {
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rex0220/kintone-sql-tools",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "kintone SQL plugin and CLI tools (ksql)",
5
5
  "publishConfig": {
6
6
  "access": "public"