@cardor/heimdall-mcp 0.1.0

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.
@@ -0,0 +1,109 @@
1
+ // src/store/SqliteStore.ts
2
+ import { createClient } from "@libsql/client";
3
+ import { and, between, eq, sql } from "drizzle-orm";
4
+ import { drizzle } from "drizzle-orm/libsql";
5
+
6
+ // src/schema/sqlite.schema.ts
7
+ import { integer, real, sqliteTable, text } from "drizzle-orm/sqlite-core";
8
+ var spans = sqliteTable("mcp_spans", {
9
+ id: text("id").primaryKey(),
10
+ traceId: text("trace_id").notNull(),
11
+ spanId: text("span_id").notNull(),
12
+ parentId: text("parent_id"),
13
+ name: text("name").notNull(),
14
+ status: text("status").notNull(),
15
+ startedAt: text("started_at").notNull(),
16
+ endedAt: text("ended_at").notNull(),
17
+ durationMs: integer("duration_ms").notNull(),
18
+ attributes: text("attributes", { mode: "json" }),
19
+ events: text("events", { mode: "json" })
20
+ });
21
+ var metrics = sqliteTable("mcp_metrics", {
22
+ id: integer("id").primaryKey({ autoIncrement: true }),
23
+ toolName: text("tool_name").notNull(),
24
+ callCount: integer("call_count").default(0),
25
+ errorCount: integer("error_count").default(0),
26
+ avgDuration: real("avg_duration"),
27
+ updatedAt: text("updated_at").notNull()
28
+ });
29
+
30
+ // src/store/SqliteStore.ts
31
+ var SqliteStore = class {
32
+ db;
33
+ constructor(url) {
34
+ const client = createClient({ url });
35
+ this.db = drizzle(client);
36
+ }
37
+ async init() {
38
+ await this.db.run(sql`
39
+ CREATE TABLE IF NOT EXISTS mcp_spans (
40
+ id TEXT NOT NULL PRIMARY KEY,
41
+ trace_id TEXT NOT NULL,
42
+ span_id TEXT NOT NULL,
43
+ parent_id TEXT,
44
+ name TEXT NOT NULL,
45
+ status TEXT NOT NULL,
46
+ started_at TEXT NOT NULL,
47
+ ended_at TEXT NOT NULL,
48
+ duration_ms INTEGER NOT NULL,
49
+ attributes TEXT,
50
+ events TEXT
51
+ )
52
+ `);
53
+ await this.db.run(sql`
54
+ CREATE TABLE IF NOT EXISTS mcp_metrics (
55
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
56
+ tool_name TEXT NOT NULL,
57
+ call_count INTEGER DEFAULT 0,
58
+ error_count INTEGER DEFAULT 0,
59
+ avg_duration REAL,
60
+ updated_at TEXT NOT NULL
61
+ )
62
+ `);
63
+ }
64
+ async save(span) {
65
+ await this.db.insert(spans).values({
66
+ id: span.id,
67
+ traceId: span.traceId,
68
+ spanId: span.spanId,
69
+ parentId: span.parentId,
70
+ name: span.name,
71
+ status: span.status,
72
+ startedAt: span.startedAt.toISOString(),
73
+ endedAt: span.endedAt.toISOString(),
74
+ durationMs: span.durationMs,
75
+ attributes: span.attributes ?? null,
76
+ events: span.events ?? null
77
+ }).onConflictDoNothing();
78
+ }
79
+ async query(filters) {
80
+ const conditions = [];
81
+ if (filters.traceId) conditions.push(eq(spans.traceId, filters.traceId));
82
+ if (filters.spanId) conditions.push(eq(spans.spanId, filters.spanId));
83
+ if (filters.name) conditions.push(eq(spans.name, filters.name));
84
+ if (filters.status) conditions.push(eq(spans.status, filters.status));
85
+ if (filters.from && filters.to) {
86
+ conditions.push(between(spans.startedAt, filters.from.toISOString(), filters.to.toISOString()));
87
+ }
88
+ const rows = await this.db.select().from(spans).where(conditions.length ? and(...conditions) : void 0).limit(filters.limit ?? 100);
89
+ return rows.map((r) => ({
90
+ id: r.id,
91
+ traceId: r.traceId,
92
+ spanId: r.spanId,
93
+ parentId: r.parentId ?? void 0,
94
+ name: r.name,
95
+ status: r.status,
96
+ startedAt: new Date(r.startedAt),
97
+ endedAt: new Date(r.endedAt),
98
+ durationMs: r.durationMs,
99
+ attributes: r.attributes,
100
+ events: r.events
101
+ }));
102
+ }
103
+ async close() {
104
+ }
105
+ };
106
+ export {
107
+ SqliteStore
108
+ };
109
+ //# sourceMappingURL=SqliteStore-HMGNDB3O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store/SqliteStore.ts","../src/schema/sqlite.schema.ts"],"sourcesContent":["import { createClient } from '@libsql/client'\nimport { and, between, eq, sql } from 'drizzle-orm'\nimport { drizzle } from 'drizzle-orm/libsql'\n\nimport { spans } from '@/schema/sqlite.schema'\n\nimport type { TraceStore } from './TraceStore'\nimport type { McpSpan, SpanFilters } from '@/types'\n\nexport class SqliteStore implements TraceStore {\n private db\n\n constructor(url: string) {\n const client = createClient({ url })\n this.db = drizzle(client)\n }\n\n async init(): Promise<void> {\n await this.db.run(sql`\n CREATE TABLE IF NOT EXISTS mcp_spans (\n id TEXT NOT NULL PRIMARY KEY,\n trace_id TEXT NOT NULL,\n span_id TEXT NOT NULL,\n parent_id TEXT,\n name TEXT NOT NULL,\n status TEXT NOT NULL,\n started_at TEXT NOT NULL,\n ended_at TEXT NOT NULL,\n duration_ms INTEGER NOT NULL,\n attributes TEXT,\n events TEXT\n )\n `)\n await this.db.run(sql`\n CREATE TABLE IF NOT EXISTS mcp_metrics (\n id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n tool_name TEXT NOT NULL,\n call_count INTEGER DEFAULT 0,\n error_count INTEGER DEFAULT 0,\n avg_duration REAL,\n updated_at TEXT NOT NULL\n )\n `)\n }\n\n async save(span: McpSpan): Promise<void> {\n await this.db.insert(spans).values({\n id: span.id,\n traceId: span.traceId,\n spanId: span.spanId,\n parentId: span.parentId,\n name: span.name,\n status: span.status,\n startedAt: span.startedAt.toISOString(),\n endedAt: span.endedAt.toISOString(),\n durationMs: span.durationMs,\n attributes: span.attributes ?? null,\n events: span.events ?? null,\n }).onConflictDoNothing()\n }\n\n async query(filters: SpanFilters): Promise<McpSpan[]> {\n const conditions = []\n if (filters.traceId) conditions.push(eq(spans.traceId, filters.traceId))\n if (filters.spanId) conditions.push(eq(spans.spanId, filters.spanId))\n if (filters.name) conditions.push(eq(spans.name, filters.name))\n if (filters.status) conditions.push(eq(spans.status, filters.status))\n if (filters.from && filters.to) {\n conditions.push(between(spans.startedAt, filters.from.toISOString(), filters.to.toISOString()))\n }\n\n const rows = await this.db\n .select()\n .from(spans)\n .where(conditions.length ? and(...conditions) : undefined)\n .limit(filters.limit ?? 100)\n\n return rows.map((r) => ({\n id: r.id,\n traceId: r.traceId,\n spanId: r.spanId,\n parentId: r.parentId ?? undefined,\n name: r.name,\n status: r.status as McpSpan['status'],\n startedAt: new Date(r.startedAt),\n endedAt: new Date(r.endedAt),\n durationMs: r.durationMs,\n attributes: r.attributes as Record<string, unknown> | undefined,\n events: r.events as McpSpan['events'],\n }))\n }\n\n async close(): Promise<void> {}\n}\n","import { integer, real, sqliteTable, text } from 'drizzle-orm/sqlite-core'\n\nexport const spans = sqliteTable('mcp_spans', {\n id: text('id').primaryKey(),\n traceId: text('trace_id').notNull(),\n spanId: text('span_id').notNull(),\n parentId: text('parent_id'),\n name: text('name').notNull(),\n status: text('status').notNull(),\n startedAt: text('started_at').notNull(),\n endedAt: text('ended_at').notNull(),\n durationMs: integer('duration_ms').notNull(),\n attributes: text('attributes', { mode: 'json' }),\n events: text('events', { mode: 'json' }),\n})\n\nexport const metrics = sqliteTable('mcp_metrics', {\n id: integer('id').primaryKey({ autoIncrement: true }),\n toolName: text('tool_name').notNull(),\n callCount: integer('call_count').default(0),\n errorCount: integer('error_count').default(0),\n avgDuration: real('avg_duration'),\n updatedAt: text('updated_at').notNull(),\n})\n"],"mappings":"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","names":[]}