@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.
- package/dist/index.js +266 -17
- 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
|
-
|
|
890
|
-
const
|
|
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
|
|
895
|
-
|
|
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
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
42
|
-
"@vornrun/shared": "0.5.
|
|
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"
|