@vornrun/mcp 0.5.0 → 0.5.2

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.
Files changed (2) hide show
  1. package/dist/index.js +266 -17
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ import Database from "libsql";
39
39
  import path2 from "path";
40
40
  import os from "os";
41
41
  import fs2 from "fs";
42
+ import { randomUUID } from "crypto";
42
43
 
43
44
  // ../server/src/logger.ts
44
45
  import pino from "pino";
@@ -400,7 +401,12 @@ function createSchema() {
400
401
  started_at TEXT NOT NULL,
401
402
  completed_at TEXT,
402
403
  status TEXT NOT NULL DEFAULT 'running',
403
- trigger_task_id TEXT
404
+ trigger_task_id TEXT,
405
+ inputs TEXT,
406
+ connector_item TEXT,
407
+ connector_inbox_id INTEGER,
408
+ connector_inbox_lease_token TEXT,
409
+ connector_inbox_disposition TEXT
404
410
  );
405
411
 
406
412
  CREATE TABLE IF NOT EXISTS workflow_run_nodes (
@@ -438,9 +444,70 @@ function createSchema() {
438
444
 
439
445
  CREATE INDEX IF NOT EXISTS idx_session_events_session ON session_events(session_id, timestamp DESC);
440
446
  CREATE INDEX IF NOT EXISTS idx_session_events_type ON session_events(event_type, timestamp DESC);
447
+
448
+ CREATE TABLE IF NOT EXISTS connector_poll_state (
449
+ workflow_id TEXT PRIMARY KEY REFERENCES workflows(id) ON DELETE CASCADE,
450
+ connection_id TEXT NOT NULL REFERENCES source_connections(id) ON DELETE CASCADE,
451
+ cursor TEXT,
452
+ last_polled_at TEXT,
453
+ last_error TEXT
454
+ );
455
+
456
+ CREATE TABLE IF NOT EXISTS connector_inbox (
457
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
458
+ workflow_id TEXT NOT NULL REFERENCES workflows(id) ON DELETE CASCADE,
459
+ connection_id TEXT NOT NULL REFERENCES source_connections(id) ON DELETE CASCADE,
460
+ connector_id TEXT NOT NULL,
461
+ event_id TEXT NOT NULL,
462
+ event_type TEXT NOT NULL,
463
+ event_timestamp TEXT NOT NULL,
464
+ payload TEXT NOT NULL,
465
+ status TEXT NOT NULL DEFAULT 'pending',
466
+ attempts INTEGER NOT NULL DEFAULT 0,
467
+ available_at TEXT NOT NULL,
468
+ lease_until TEXT,
469
+ lease_token TEXT,
470
+ last_error TEXT,
471
+ created_at TEXT NOT NULL,
472
+ processed_at TEXT,
473
+ UNIQUE (workflow_id, connection_id, event_type, event_id)
474
+ );
475
+
476
+ CREATE INDEX IF NOT EXISTS idx_connector_inbox_ready
477
+ ON connector_inbox(status, available_at, lease_until);
478
+ CREATE INDEX IF NOT EXISTS idx_connector_inbox_connection
479
+ ON connector_inbox(connection_id, created_at);
441
480
  `);
442
481
  migrateSchema(d);
443
482
  verifySchema(d);
483
+ seedLegacyConnectorPollState(d);
484
+ }
485
+ function seedLegacyConnectorPollState(d) {
486
+ const workflows = d.prepare("SELECT id, nodes FROM workflows").all();
487
+ const readConnection = d.prepare(
488
+ "SELECT sync_cursor, last_sync_at FROM source_connections WHERE id = ?"
489
+ );
490
+ const insertState = d.prepare(
491
+ `INSERT OR IGNORE INTO connector_poll_state (
492
+ workflow_id, connection_id, cursor, last_polled_at, last_error
493
+ ) VALUES (?, ?, ?, ?, NULL)`
494
+ );
495
+ for (const workflow of workflows) {
496
+ let nodes;
497
+ try {
498
+ nodes = JSON.parse(workflow.nodes);
499
+ } catch {
500
+ continue;
501
+ }
502
+ const trigger = nodes.find(
503
+ (node) => node.type === "trigger" && node.config?.triggerType === "connectorPoll"
504
+ );
505
+ const connectionId = trigger?.config?.connectionId;
506
+ if (!connectionId) continue;
507
+ const connection = readConnection.get(connectionId);
508
+ if (!connection) continue;
509
+ insertState.run(workflow.id, connectionId, connection.sync_cursor, connection.last_sync_at);
510
+ }
444
511
  }
445
512
  function migrateSchema(d) {
446
513
  const row = d.prepare("SELECT value FROM schema_meta WHERE key = 'schema_version'").get();
@@ -642,6 +709,126 @@ function migrateSchema(d) {
642
709
  })();
643
710
  logger_default.info("[database] migrated schema to version 10 (drop session_logs)");
644
711
  }
712
+ if (version < 11) {
713
+ d.transaction(() => {
714
+ const runCols = d.prepare("PRAGMA table_info(workflow_runs)").all();
715
+ if (!runCols.some((c) => c.name === "inputs")) {
716
+ d.exec("ALTER TABLE workflow_runs ADD COLUMN inputs TEXT");
717
+ }
718
+ d.prepare(
719
+ "INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('schema_version', '11')"
720
+ ).run();
721
+ })();
722
+ logger_default.info("[database] migrated schema to version 11 (workflow run inputs)");
723
+ }
724
+ if (version < 12) {
725
+ d.transaction(() => {
726
+ const runCols = d.prepare("PRAGMA table_info(workflow_runs)").all();
727
+ if (!runCols.some((column) => column.name === "connector_inbox_id")) {
728
+ d.exec("ALTER TABLE workflow_runs ADD COLUMN connector_inbox_id INTEGER");
729
+ }
730
+ if (!runCols.some((column) => column.name === "connector_item")) {
731
+ d.exec("ALTER TABLE workflow_runs ADD COLUMN connector_item TEXT");
732
+ }
733
+ if (!runCols.some((column) => column.name === "connector_inbox_lease_token")) {
734
+ d.exec("ALTER TABLE workflow_runs ADD COLUMN connector_inbox_lease_token TEXT");
735
+ }
736
+ if (!runCols.some((column) => column.name === "connector_inbox_disposition")) {
737
+ d.exec("ALTER TABLE workflow_runs ADD COLUMN connector_inbox_disposition TEXT");
738
+ }
739
+ d.exec(`
740
+ CREATE TABLE IF NOT EXISTS connector_poll_state (
741
+ workflow_id TEXT PRIMARY KEY REFERENCES workflows(id) ON DELETE CASCADE,
742
+ connection_id TEXT NOT NULL REFERENCES source_connections(id) ON DELETE CASCADE,
743
+ cursor TEXT,
744
+ last_polled_at TEXT,
745
+ last_error TEXT
746
+ );
747
+
748
+ CREATE TABLE IF NOT EXISTS connector_inbox (
749
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
750
+ workflow_id TEXT NOT NULL REFERENCES workflows(id) ON DELETE CASCADE,
751
+ connection_id TEXT NOT NULL REFERENCES source_connections(id) ON DELETE CASCADE,
752
+ connector_id TEXT NOT NULL,
753
+ event_id TEXT NOT NULL,
754
+ event_type TEXT NOT NULL,
755
+ event_timestamp TEXT NOT NULL,
756
+ payload TEXT NOT NULL,
757
+ status TEXT NOT NULL DEFAULT 'pending',
758
+ attempts INTEGER NOT NULL DEFAULT 0,
759
+ available_at TEXT NOT NULL,
760
+ lease_until TEXT,
761
+ lease_token TEXT,
762
+ last_error TEXT,
763
+ created_at TEXT NOT NULL,
764
+ processed_at TEXT,
765
+ UNIQUE (workflow_id, event_type, event_id)
766
+ );
767
+
768
+ CREATE INDEX IF NOT EXISTS idx_connector_inbox_ready
769
+ ON connector_inbox(status, available_at, lease_until);
770
+ CREATE INDEX IF NOT EXISTS idx_connector_inbox_connection
771
+ ON connector_inbox(connection_id, created_at);
772
+ `);
773
+ d.prepare(
774
+ "INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('schema_version', '12')"
775
+ ).run();
776
+ })();
777
+ logger_default.info("[database] migrated schema to version 12 (durable connector ingestion)");
778
+ }
779
+ if (version < 13) {
780
+ d.transaction(() => {
781
+ const inboxCols = d.prepare("PRAGMA table_info(connector_inbox)").all();
782
+ if (!inboxCols.some((column) => column.name === "lease_token")) {
783
+ d.exec("ALTER TABLE connector_inbox ADD COLUMN lease_token TEXT");
784
+ }
785
+ d.exec(`
786
+ ALTER TABLE connector_inbox RENAME TO connector_inbox_v12;
787
+
788
+ CREATE TABLE connector_inbox (
789
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
790
+ workflow_id TEXT NOT NULL REFERENCES workflows(id) ON DELETE CASCADE,
791
+ connection_id TEXT NOT NULL REFERENCES source_connections(id) ON DELETE CASCADE,
792
+ connector_id TEXT NOT NULL,
793
+ event_id TEXT NOT NULL,
794
+ event_type TEXT NOT NULL,
795
+ event_timestamp TEXT NOT NULL,
796
+ payload TEXT NOT NULL,
797
+ status TEXT NOT NULL DEFAULT 'pending',
798
+ attempts INTEGER NOT NULL DEFAULT 0,
799
+ available_at TEXT NOT NULL,
800
+ lease_until TEXT,
801
+ lease_token TEXT,
802
+ last_error TEXT,
803
+ created_at TEXT NOT NULL,
804
+ processed_at TEXT,
805
+ UNIQUE (workflow_id, connection_id, event_type, event_id)
806
+ );
807
+
808
+ INSERT INTO connector_inbox (
809
+ id, workflow_id, connection_id, connector_id, event_id, event_type,
810
+ event_timestamp, payload, status, attempts, available_at, lease_until,
811
+ lease_token, last_error, created_at, processed_at
812
+ )
813
+ SELECT
814
+ id, workflow_id, connection_id, connector_id, event_id, event_type,
815
+ event_timestamp, payload, status, attempts, available_at, lease_until,
816
+ lease_token, last_error, created_at, processed_at
817
+ FROM connector_inbox_v12;
818
+
819
+ DROP TABLE connector_inbox_v12;
820
+
821
+ CREATE INDEX idx_connector_inbox_ready
822
+ ON connector_inbox(status, available_at, lease_until);
823
+ CREATE INDEX idx_connector_inbox_connection
824
+ ON connector_inbox(connection_id, created_at);
825
+ `);
826
+ d.prepare(
827
+ "INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('schema_version', '13')"
828
+ ).run();
829
+ })();
830
+ logger_default.info("[database] migrated schema to version 13 (connection-scoped inbox)");
831
+ }
645
832
  }
646
833
  function verifySchema(d) {
647
834
  const expectedByTable = {
@@ -679,6 +866,31 @@ function verifySchema(d) {
679
866
  ddl: "ALTER TABLE agent_commands ADD COLUMN headless_args TEXT"
680
867
  }
681
868
  ],
869
+ workflow_runs: [
870
+ { column: "inputs", ddl: "ALTER TABLE workflow_runs ADD COLUMN inputs TEXT" },
871
+ {
872
+ column: "connector_item",
873
+ ddl: "ALTER TABLE workflow_runs ADD COLUMN connector_item TEXT"
874
+ },
875
+ {
876
+ column: "connector_inbox_id",
877
+ ddl: "ALTER TABLE workflow_runs ADD COLUMN connector_inbox_id INTEGER"
878
+ },
879
+ {
880
+ column: "connector_inbox_lease_token",
881
+ ddl: "ALTER TABLE workflow_runs ADD COLUMN connector_inbox_lease_token TEXT"
882
+ },
883
+ {
884
+ column: "connector_inbox_disposition",
885
+ ddl: "ALTER TABLE workflow_runs ADD COLUMN connector_inbox_disposition TEXT"
886
+ }
887
+ ],
888
+ connector_inbox: [
889
+ {
890
+ column: "lease_token",
891
+ ddl: "ALTER TABLE connector_inbox ADD COLUMN lease_token TEXT"
892
+ }
893
+ ],
682
894
  workflow_run_nodes: [
683
895
  { column: "agent_type", ddl: "ALTER TABLE workflow_run_nodes ADD COLUMN agent_type TEXT" },
684
896
  {
@@ -886,13 +1098,30 @@ function saveConfig(config) {
886
1098
  p.workspaceId ?? "personal"
887
1099
  );
888
1100
  }
889
- d.prepare("DELETE FROM workflows").run();
890
- const insertWorkflow = d.prepare(
1101
+ const workflows = config.workflows ?? [];
1102
+ const workflowIds = new Set(workflows.map((workflow) => workflow.id));
1103
+ const existingWorkflowIds = d.prepare("SELECT id FROM workflows").all();
1104
+ const deleteWorkflow = d.prepare("DELETE FROM workflows WHERE id = ?");
1105
+ for (const { id } of existingWorkflowIds) {
1106
+ if (!workflowIds.has(id)) deleteWorkflow.run(id);
1107
+ }
1108
+ const upsertWorkflow = d.prepare(
891
1109
  `INSERT INTO workflows (id, name, icon, icon_color, nodes, edges, enabled, last_run_at, last_run_status, stagger_delay_ms, workspace_id)
892
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
1110
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1111
+ ON CONFLICT(id) DO UPDATE SET
1112
+ name = excluded.name,
1113
+ icon = excluded.icon,
1114
+ icon_color = excluded.icon_color,
1115
+ nodes = excluded.nodes,
1116
+ edges = excluded.edges,
1117
+ enabled = excluded.enabled,
1118
+ last_run_at = excluded.last_run_at,
1119
+ last_run_status = excluded.last_run_status,
1120
+ stagger_delay_ms = excluded.stagger_delay_ms,
1121
+ workspace_id = excluded.workspace_id`
893
1122
  );
894
- for (const w of config.workflows ?? []) {
895
- insertWorkflow.run(
1123
+ for (const w of workflows) {
1124
+ upsertWorkflow.run(
896
1125
  w.id,
897
1126
  w.name,
898
1127
  w.icon,
@@ -1357,17 +1586,37 @@ function fetchNodesByRunIds(d, runIds) {
1357
1586
  }
1358
1587
  return out;
1359
1588
  }
1589
+ function parseRunInputs(raw) {
1590
+ if (!raw) return void 0;
1591
+ try {
1592
+ const parsed = JSON.parse(raw);
1593
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
1594
+ } catch {
1595
+ return void 0;
1596
+ }
1597
+ }
1360
1598
  function mapRunRows(rows, nodesByRun) {
1361
- return rows.map((r) => ({
1362
- runId: r.id,
1363
- workflowId: r.workflow_id,
1364
- startedAt: r.started_at,
1365
- ...r.completed_at != null && { completedAt: r.completed_at },
1366
- status: r.status,
1367
- ...r.trigger_task_id != null && { triggerTaskId: r.trigger_task_id },
1368
- ...r.workflow_name != null && { workflowName: r.workflow_name },
1369
- nodeStates: nodesByRun.get(r.id) ?? []
1370
- }));
1599
+ return rows.map((r) => {
1600
+ const inputs = parseRunInputs(r.inputs);
1601
+ const connectorItem = parseRunInputs(r.connector_item);
1602
+ return {
1603
+ runId: r.id,
1604
+ workflowId: r.workflow_id,
1605
+ startedAt: r.started_at,
1606
+ ...r.completed_at != null && { completedAt: r.completed_at },
1607
+ status: r.status,
1608
+ ...r.trigger_task_id != null && { triggerTaskId: r.trigger_task_id },
1609
+ ...inputs && { inputs },
1610
+ ...connectorItem && { connectorItem },
1611
+ ...r.connector_inbox_id != null && { connectorInboxId: r.connector_inbox_id },
1612
+ ...r.connector_inbox_lease_token != null && {
1613
+ connectorInboxLeaseToken: r.connector_inbox_lease_token
1614
+ },
1615
+ ...r.connector_inbox_disposition === "processed" || r.connector_inbox_disposition === "retry" ? { connectorInboxDisposition: r.connector_inbox_disposition } : {},
1616
+ ...r.workflow_name != null && { workflowName: r.workflow_name },
1617
+ nodeStates: nodesByRun.get(r.id) ?? []
1618
+ };
1619
+ });
1371
1620
  }
1372
1621
  function listWorkflowRuns(workflowId, limit = 20) {
1373
1622
  const d = getDb();
@@ -2869,7 +3118,7 @@ console.warn = (...args) => _origError("[mcp:warn]", ...args);
2869
3118
  console.error = (...args) => _origError("[mcp:error]", ...args);
2870
3119
  async function main() {
2871
3120
  configManager.init();
2872
- const version = true ? "0.5.0" : createRequire(import.meta.url)("../package.json").version;
3121
+ const version = true ? "0.5.2" : createRequire(import.meta.url)("../package.json").version;
2873
3122
  const server = createMcpServer(version);
2874
3123
  const transport = new StdioServerTransport();
2875
3124
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vornrun/mcp",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Vorn MCP server — task management, git, and workflow tools for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,8 +38,8 @@
38
38
  "zod": "^4.4.3"
39
39
  },
40
40
  "devDependencies": {
41
- "@vornrun/server": "0.5.0",
42
- "@vornrun/shared": "0.5.0",
41
+ "@vornrun/server": "0.5.2",
42
+ "@vornrun/shared": "0.5.2",
43
43
  "tsup": "^8.5.1",
44
44
  "tsx": "^4.23.1",
45
45
  "typescript": "^6.0.3"