Add Effect stdio MCP entrypoint

This commit is contained in:
elpresidank 2026-06-02 08:59:53 -05:00
parent 0fb10aca73
commit e311315556
5 changed files with 136 additions and 16 deletions

View file

@ -8,7 +8,7 @@
"build": "bunx --bun tsc",
"dev": "tsc --watch",
"clean": "rm -rf dist",
"test": "bunx --bun vitest run --passWithNoTests"
"test": "bunx --bun vitest run --passWithNoTests --exclude=dist/**"
},
"dependencies": {
"@trustgraph/base": "workspace:*",

View file

@ -0,0 +1,51 @@
import { describe, expect, it } from "vitest";
import {
makeTrustGraphMcpStdioLayer,
runStdio,
TrustGraphMcpToolkit,
} from "../server-effect.js";
const expectedToolNames = [
"text_completion",
"graph_rag",
"document_rag",
"agent",
"embeddings",
"triples_query",
"graph_embeddings_query",
"get_config_all",
"get_config",
"put_config",
"delete_config",
"get_flows",
"get_flow",
"start_flow",
"stop_flow",
"get_documents",
"load_document",
"remove_document",
"get_prompts",
"get_prompt",
"get_knowledge_cores",
"delete_kg_core",
"load_kg_core",
];
describe("Effect MCP server", () => {
it("keeps the canonical Effect toolkit names stable", () => {
expect(Object.keys(TrustGraphMcpToolkit.tools)).toEqual(expectedToolNames);
});
it("exposes an Effect stdio layer and process entrypoint", () => {
expect(
makeTrustGraphMcpStdioLayer({
gatewayUrl: "ws://localhost:8088/api/v1/rpc",
user: "mcp-test",
flowId: "default",
openAiApiKey: "test-key",
}),
).toBeDefined();
expect(runStdio).toEqual(expect.any(Function));
});
});

View file

@ -1,5 +1,6 @@
import {OpenAiClient, OpenAiLanguageModel} from "@effect/ai-openai";
import {BunHttpServer, BunRuntime} from "@effect/platform-bun";
import {NodeRuntime, NodeStdio} from "@effect/platform-node";
import {createTrustGraphSocket, type BaseApi, type Term as ClientTerm} from "@trustgraph/client";
import {Config, Context, Effect, Layer, Redacted} from "effect";
import * as O from "effect/Option";
@ -1725,10 +1726,7 @@ export const TrustGraphMcpHttpApiRoutes = HttpApiBuilder.layer(
const makeTrustGraphMcpHttpLayerFromConfig = (
config: TrustGraphMcpConfigShape,
) => {
const tools = McpServer.toolkit(TrustGraphMcpToolkit).pipe(
Layer.provide(TrustGraphMcpToolkitLive),
Layer.provide(makeOpenAiProviderLayerFromConfig(config)),
)
const tools = makeTrustGraphMcpToolkitLayerFromConfig(config)
return Layer.mergeAll(
TrustGraphMcpHttpApiRoutes,
@ -1744,6 +1742,27 @@ const makeTrustGraphMcpHttpLayerFromConfig = (
)
}
const makeTrustGraphMcpToolkitLayerFromConfig = (
config: TrustGraphMcpConfigShape,
) =>
McpServer.toolkit(TrustGraphMcpToolkit).pipe(
Layer.provide(TrustGraphMcpToolkitLive),
Layer.provide(makeOpenAiProviderLayerFromConfig(config)),
)
const makeTrustGraphMcpStdioLayerFromConfig = (
config: TrustGraphMcpConfigShape,
) =>
makeTrustGraphMcpToolkitLayerFromConfig(config).pipe(
Layer.provide(McpServer.layerStdio({
name: config.name,
version: config.version,
})),
Layer.provide(NodeStdio.layer),
Layer.provide(TrustGraphSocket.layer),
Layer.provide(Layer.succeed(TrustGraphMcpConfig, TrustGraphMcpConfig.of(config))),
)
export const makeTrustGraphMcpHttpServerLayer = (
options: TrustGraphMcpOptions = {},
) =>
@ -1766,6 +1785,19 @@ export const makeTrustGraphMcpHttpLayer = (
),
)
export const makeTrustGraphMcpStdioLayer = (
options: TrustGraphMcpOptions = {},
) =>
Layer.unwrap(
loadTrustGraphMcpConfig(options).pipe(
Effect.map(makeTrustGraphMcpStdioLayerFromConfig),
),
)
export const runHttp = (options: TrustGraphMcpOptions = {}): void => {
Layer.launch(makeTrustGraphMcpHttpServerLayer(options)).pipe(BunRuntime.runMain)
}
export const runStdio = (options: TrustGraphMcpOptions = {}): void => {
Layer.launch(makeTrustGraphMcpStdioLayer(options)).pipe(NodeRuntime.runMain)
}