mirror of
https://github.com/sveltejs/ai-tools.git
synced 2026-07-04 03:19:38 +08:00
Compare commits
2 Commits
teemingc-p
...
feat/to-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
543fff6207 | ||
|
|
9de930dddc |
@@ -39,7 +39,6 @@
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.3.2",
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@libsql/client": "^0.14.0",
|
||||
"@modelcontextprotocol/inspector": "^0.16.7",
|
||||
"@sveltejs/adapter-vercel": "^5.6.3",
|
||||
"@sveltejs/kit": "^2.22.0",
|
||||
@@ -53,6 +52,7 @@
|
||||
"globals": "^16.0.0",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-plugin-svelte": "^3.3.3",
|
||||
"remult": "3.3.0-next.1",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"svelte-eslint-parser": "^1.3.2",
|
||||
@@ -62,6 +62,7 @@
|
||||
"vitest": "^3.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@libsql/client": "^0.14.0",
|
||||
"@sveltejs/mcp-schema": "workspace:^",
|
||||
"@sveltejs/mcp-server": "workspace:^",
|
||||
"@tmcp/transport-http": "^0.6.3",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { http_transport } from '$lib/mcp/index.js';
|
||||
import { db } from '$lib/server/db/index.js';
|
||||
import { db, entities } from '$lib/server/db/index.js';
|
||||
|
||||
export async function handle({ event, resolve }) {
|
||||
const mcp_response = await http_transport.respond(event.request, {
|
||||
db,
|
||||
entities,
|
||||
});
|
||||
// we are deploying on vercel the SSE connection will timeout after 5 minutes...for
|
||||
// the moment we are not sending back any notifications (logs, or list changed notifications)
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import { createClient } from '@libsql/client';
|
||||
import { drizzle } from 'drizzle-orm/libsql';
|
||||
import * as schema from './schema.js';
|
||||
import { remult, SqlDatabase } from 'remult';
|
||||
import { TursoDataProvider } from 'remult/remult-turso';
|
||||
// let's disable it for the moment...i can't figure out a way to make it wotk with eslint
|
||||
// eslint-disable-next-line import/extensions
|
||||
import { DATABASE_TOKEN, DATABASE_URL } from '$env/static/private';
|
||||
import { Content } from '../../../shared/entities/Content.js';
|
||||
import { ContentDistilled } from '../../../shared/entities/ContentDistilled.js';
|
||||
import { Distillation } from '../../../shared/entities/Distillation.js';
|
||||
import { DistillationJob } from '../../../shared/entities/DistillationJob.js';
|
||||
if (!DATABASE_URL) throw new Error('DATABASE_URL is not set');
|
||||
if (!DATABASE_TOKEN) throw new Error('DATABASE_TOKEN is not set');
|
||||
|
||||
@@ -13,3 +19,13 @@ const client = createClient({
|
||||
});
|
||||
|
||||
export const db = drizzle(client, { schema, logger: true });
|
||||
|
||||
remult.dataProvider = new SqlDatabase(new TursoDataProvider(client));
|
||||
SqlDatabase.LogToConsole = true;
|
||||
|
||||
export const entities = {
|
||||
Content,
|
||||
ContentDistilled,
|
||||
Distillation,
|
||||
DistillationJob,
|
||||
};
|
||||
|
||||
19
apps/mcp-remote/src/shared/FieldVector.ts
Normal file
19
apps/mcp-remote/src/shared/FieldVector.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Fields, type FieldOptions } from 'remult';
|
||||
|
||||
export function FieldVector<entityType = unknown>(
|
||||
...options: (FieldOptions<entityType, number[]> & { dimensions?: number })[]
|
||||
) {
|
||||
const dimensions = options[0].dimensions ?? 1024;
|
||||
|
||||
return Fields.object<entityType, number[]>(
|
||||
{
|
||||
valueConverter: {
|
||||
fieldTypeInDb: `F32_BLOB(${dimensions})`,
|
||||
toDb: (val) => JSON.stringify(val),
|
||||
toDbSql: (val) => `vector32(${val})`,
|
||||
fromDb: (val: Buffer) => Array.from(new Float32Array(val)),
|
||||
},
|
||||
},
|
||||
...options,
|
||||
);
|
||||
}
|
||||
35
apps/mcp-remote/src/shared/entities/Content.ts
Normal file
35
apps/mcp-remote/src/shared/entities/Content.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Entity, Fields } from 'remult';
|
||||
import { FieldVector } from '../FieldVector';
|
||||
|
||||
@Entity<Content>('content', {
|
||||
allowApiCrud: true,
|
||||
dbName: 'content',
|
||||
})
|
||||
export class Content {
|
||||
@Fields.integer()
|
||||
id!: number;
|
||||
|
||||
@Fields.string()
|
||||
path!: string;
|
||||
|
||||
@Fields.string()
|
||||
filename!: string;
|
||||
|
||||
@Fields.string()
|
||||
content!: string;
|
||||
|
||||
@Fields.integer()
|
||||
size_bytes!: number;
|
||||
|
||||
@FieldVector({ allowNull: true })
|
||||
embeddings: number[] | null = null;
|
||||
|
||||
@Fields.string()
|
||||
metadata = '{}';
|
||||
|
||||
@Fields.integer()
|
||||
created_at!: number;
|
||||
|
||||
@Fields.integer()
|
||||
updated_at!: number;
|
||||
}
|
||||
35
apps/mcp-remote/src/shared/entities/ContentDistilled.ts
Normal file
35
apps/mcp-remote/src/shared/entities/ContentDistilled.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Entity, Fields } from 'remult';
|
||||
import { FieldVector } from '../FieldVector';
|
||||
|
||||
@Entity<ContentDistilled>('content_distilled', {
|
||||
allowApiCrud: true,
|
||||
dbName: 'content_distilled',
|
||||
})
|
||||
export class ContentDistilled {
|
||||
@Fields.integer()
|
||||
id!: number;
|
||||
|
||||
@Fields.string()
|
||||
path!: string;
|
||||
|
||||
@Fields.string()
|
||||
filename!: string;
|
||||
|
||||
@Fields.string()
|
||||
content!: string;
|
||||
|
||||
@Fields.integer()
|
||||
size_bytes!: number;
|
||||
|
||||
@FieldVector({ allowNull: true })
|
||||
embeddings: number[] | null = null;
|
||||
|
||||
@Fields.string()
|
||||
metadata = '{}';
|
||||
|
||||
@Fields.integer()
|
||||
created_at!: number;
|
||||
|
||||
@Fields.integer()
|
||||
updated_at!: number;
|
||||
}
|
||||
36
apps/mcp-remote/src/shared/entities/Distillation.ts
Normal file
36
apps/mcp-remote/src/shared/entities/Distillation.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Entity, Field, Fields } from "remult"
|
||||
import { Relations } from "remult"
|
||||
import { DistillationJob } from "./DistillationJob.js"
|
||||
|
||||
@Entity<Distillation>("distillations", {
|
||||
allowApiCrud: true,
|
||||
dbName: "distillations",
|
||||
})
|
||||
export class Distillation {
|
||||
@Fields.integer()
|
||||
id!: number
|
||||
|
||||
@Fields.string()
|
||||
preset_name!: string
|
||||
|
||||
@Fields.string()
|
||||
version!: string
|
||||
|
||||
@Fields.string()
|
||||
content!: string
|
||||
|
||||
@Fields.integer()
|
||||
size_kb!: number
|
||||
|
||||
@Fields.integer()
|
||||
document_count!: number
|
||||
|
||||
@Fields.integer({ allowNull: true })
|
||||
distillation_job_id?: number
|
||||
|
||||
@Relations.toOne(() => DistillationJob, { field: "distillation_job_id" })
|
||||
distillation_job?: DistillationJob
|
||||
|
||||
@Fields.integer()
|
||||
created_at!: number
|
||||
}
|
||||
64
apps/mcp-remote/src/shared/entities/DistillationJob.ts
Normal file
64
apps/mcp-remote/src/shared/entities/DistillationJob.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Entity, Fields } from 'remult';
|
||||
import { Relations } from 'remult';
|
||||
import { Distillation } from './Distillation.js';
|
||||
|
||||
@Entity<DistillationJob>('distillation_jobs', {
|
||||
allowApiCrud: true,
|
||||
dbName: 'distillation_jobs',
|
||||
})
|
||||
export class DistillationJob {
|
||||
@Fields.integer()
|
||||
id!: number;
|
||||
|
||||
@Fields.string()
|
||||
preset_name!: string;
|
||||
|
||||
@Fields.string({ allowNull: true })
|
||||
batch_id?: string;
|
||||
|
||||
@Fields.string()
|
||||
status!: string;
|
||||
|
||||
@Fields.string()
|
||||
model_used!: string;
|
||||
|
||||
@Fields.integer()
|
||||
total_files!: number;
|
||||
|
||||
@Fields.integer()
|
||||
processed_files = 0;
|
||||
|
||||
@Fields.integer()
|
||||
successful_files = 0;
|
||||
|
||||
@Fields.boolean()
|
||||
minimize_applied = false;
|
||||
|
||||
@Fields.integer()
|
||||
total_input_tokens = 0;
|
||||
|
||||
@Fields.integer()
|
||||
total_output_tokens = 0;
|
||||
|
||||
@Fields.integer({ allowNull: true })
|
||||
started_at?: number;
|
||||
|
||||
@Fields.integer({ allowNull: true })
|
||||
completed_at?: number;
|
||||
|
||||
@Fields.string({ allowNull: true })
|
||||
error_message?: string;
|
||||
|
||||
@Fields.string()
|
||||
metadata = '{}';
|
||||
|
||||
@Fields.integer()
|
||||
created_at!: number;
|
||||
|
||||
@Fields.integer()
|
||||
updated_at!: number;
|
||||
|
||||
// Relations toMany
|
||||
@Relations.toMany(() => Distillation)
|
||||
distillations?: Distillation[];
|
||||
}
|
||||
@@ -9,7 +9,8 @@
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
"moduleResolution": "bundler",
|
||||
"experimentalDecorators": true
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"@sveltejs/kit": "^2.42.2",
|
||||
"@types/eslint-scope": "^8.3.2",
|
||||
"@types/estree": "^1.0.8",
|
||||
"@typescript-eslint/types": "^8.44.0"
|
||||
"@typescript-eslint/types": "^8.44.0",
|
||||
"remult": "3.3.0-next.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { McpServer } from 'tmcp';
|
||||
import { setup_prompts, setup_resources, setup_tools } from './handlers/index.js';
|
||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql';
|
||||
import type { Schema } from '@sveltejs/mcp-schema';
|
||||
import type { ClassType } from 'remult';
|
||||
|
||||
export const server = new McpServer(
|
||||
{
|
||||
@@ -21,7 +22,7 @@ export const server = new McpServer(
|
||||
instructions:
|
||||
'This is the official Svelte MCP server. It MUST be used whenever svelte development is involved. It can provide official documentation, code examples and correct your code. After you correct the component call this tool again to confirm all the issues are fixed.',
|
||||
},
|
||||
).withContext<{ db: LibSQLDatabase<Schema> }>();
|
||||
).withContext<{ db: LibSQLDatabase<Schema>; entities: Record<string, ClassType<unknown>> }>();
|
||||
|
||||
export type SvelteMcp = typeof server;
|
||||
|
||||
|
||||
30
pnpm-lock.yaml
generated
30
pnpm-lock.yaml
generated
@@ -25,7 +25,7 @@ importers:
|
||||
version: 10.1.8(eslint@9.36.0(jiti@2.6.0))
|
||||
eslint-plugin-import:
|
||||
specifier: ^2.32.0
|
||||
version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0))
|
||||
version: 2.32.0(eslint@9.36.0(jiti@2.6.0))
|
||||
eslint-plugin-svelte:
|
||||
specifier: ^3.12.3
|
||||
version: 3.12.4(eslint@9.36.0(jiti@2.6.0))(svelte@5.39.6)(ts-node@10.9.2(@types/node@24.5.2)(typescript@5.9.2))
|
||||
@@ -50,6 +50,9 @@ importers:
|
||||
|
||||
apps/mcp-remote:
|
||||
dependencies:
|
||||
'@libsql/client':
|
||||
specifier: ^0.14.0
|
||||
version: 0.14.0
|
||||
'@sveltejs/mcp-schema':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/mcp-schema
|
||||
@@ -69,9 +72,6 @@ importers:
|
||||
'@eslint/js':
|
||||
specifier: ^9.36.0
|
||||
version: 9.36.0
|
||||
'@libsql/client':
|
||||
specifier: ^0.14.0
|
||||
version: 0.14.0
|
||||
'@modelcontextprotocol/inspector':
|
||||
specifier: ^0.16.7
|
||||
version: 0.16.8(@types/node@24.5.2)(typescript@5.9.2)
|
||||
@@ -111,6 +111,9 @@ importers:
|
||||
prettier-plugin-svelte:
|
||||
specifier: ^3.3.3
|
||||
version: 3.4.0(prettier@3.6.2)(svelte@5.39.6)
|
||||
remult:
|
||||
specifier: 3.3.0-next.1
|
||||
version: 3.3.0-next.1
|
||||
svelte:
|
||||
specifier: ^5.0.0
|
||||
version: 5.39.6
|
||||
@@ -193,6 +196,9 @@ importers:
|
||||
'@typescript-eslint/types':
|
||||
specifier: ^8.44.0
|
||||
version: 8.44.1
|
||||
remult:
|
||||
specifier: 3.3.0-next.1
|
||||
version: 3.3.0-next.1
|
||||
|
||||
packages/mcp-stdio:
|
||||
dependencies:
|
||||
@@ -3219,6 +3225,9 @@ packages:
|
||||
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
remult@3.3.0-next.1:
|
||||
resolution: {integrity: sha512-41psdKqvkch17x/lOT4fJ9iE5Ee1MchZ1yrlWGCV8oSsXhdp9H8/eIay2LPp62c3YBx9CgcZgpwwXVmRnzoWdw==}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -5775,17 +5784,16 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0)):
|
||||
eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0)):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)
|
||||
eslint: 9.36.0(jiti@2.6.0)
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0)):
|
||||
eslint-plugin-import@2.32.0(eslint@9.36.0(jiti@2.6.0)):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.9
|
||||
@@ -5796,7 +5804,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 9.36.0(jiti@2.6.0)
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0))
|
||||
eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0))
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
@@ -5807,8 +5815,6 @@ snapshots:
|
||||
semver: 6.3.1
|
||||
string.prototype.trimend: 1.0.9
|
||||
tsconfig-paths: 3.15.0
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
@@ -6730,6 +6736,10 @@ snapshots:
|
||||
gopd: 1.2.0
|
||||
set-function-name: 2.0.2
|
||||
|
||||
remult@3.3.0-next.1:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
Reference in New Issue
Block a user