File size: 1,906 Bytes
52c6f5c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { idb } from "$lib/remult.js";
import { dequal } from "dequal";
import { Entity, Fields, repo, type MembersOnly } from "remult";
import { projects } from "./projects.svelte";

export type MCPProtocol = "sse" | "http";

export interface MCPServer {
	id: string;
	name: string;
	url: string;
	protocol: MCPProtocol;
	headers?: Record<string, string>;
}

@Entity("mcp_server")
export class MCPServerEntity {
	@Fields.cuid()
	id!: string;

	@Fields.string()
	name!: string;

	@Fields.string()
	url!: string;

	@Fields.string()
	protocol: MCPProtocol = "sse";

	@Fields.json()
	headers?: Record<string, string>;
}

export type MCPServerEntityMembers = MembersOnly<MCPServerEntity>;

export type MCPFormData = {
	name: string;
	url: string;
	protocol: MCPProtocol;
	headers: Record<string, string>;
};

const mcpServersRepo = repo(MCPServerEntity, idb);

class MCPServers {
	#servers: Record<MCPServerEntity["id"], MCPServerEntity> = $state({});

	constructor() {
		mcpServersRepo.find().then(res => {
			res.forEach(server => {
				if (dequal(this.#servers[server.id], server)) return;
				this.#servers[server.id] = server;
			});
		});
	}

	async create(args: Omit<MCPServerEntity, "id">): Promise<string> {
		const server = await mcpServersRepo.save({ ...args });
		this.#servers[server.id] = server;
		return server.id;
	}

	get all() {
		return Object.values(this.#servers);
	}

	get enabled() {
		const currentProject = projects.current;
		if (!currentProject) return [];
		return this.all.filter(server => currentProject.enabledMCPs?.includes(server.id));
	}

	async update(data: MCPServerEntity) {
		if (!data.id) return;
		await mcpServersRepo.upsert({ where: { id: data.id }, set: data });
		this.#servers[data.id] = { ...data };
	}

	async delete(id: string) {
		if (!id) return;
		await mcpServersRepo.delete(id);
		delete this.#servers[id];
	}
}

export const mcpServers = new MCPServers();