2026-06-01 16:22:25 -05:00
|
|
|
import {BunHttpServer, BunRuntime} from "@effect/platform-bun";
|
2026-06-02 08:59:53 -05:00
|
|
|
import {NodeRuntime, NodeStdio} from "@effect/platform-node";
|
2026-06-11 06:29:29 -05:00
|
|
|
import {
|
|
|
|
|
createTrustGraphSocket,
|
|
|
|
|
makeTrustGraphGatewayClientScoped,
|
|
|
|
|
type BaseApi,
|
|
|
|
|
type Term as ClientTerm,
|
|
|
|
|
type TrustGraphGatewayClient,
|
|
|
|
|
} from "@trustgraph/client";
|
2026-06-06 11:01:17 -05:00
|
|
|
import {Config, Context, Effect, Layer} from "effect";
|
2026-06-02 00:22:04 -05:00
|
|
|
import * as O from "effect/Option";
|
|
|
|
|
import * as Predicate from "effect/Predicate";
|
2026-06-06 11:01:17 -05:00
|
|
|
import {McpServer, Tool, Toolkit} from "effect/unstable/ai";
|
|
|
|
|
import {HttpRouter} from "effect/unstable/http";
|
2026-06-01 16:22:25 -05:00
|
|
|
import {HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, HttpApiSchema, OpenApi} from "effect/unstable/httpapi";
|
|
|
|
|
import * as S from "effect/Schema";
|
|
|
|
|
|
2026-06-02 00:22:04 -05:00
|
|
|
const annotateTool = <Name extends string, Config extends {
|
|
|
|
|
readonly parameters: S.Top
|
|
|
|
|
readonly success: S.Top
|
|
|
|
|
readonly failure: S.Top
|
|
|
|
|
readonly failureMode: Tool.FailureMode
|
|
|
|
|
}, Requirements>(
|
|
|
|
|
tool: Tool.Tool<Name, Config, Requirements>,
|
2026-06-01 16:22:25 -05:00
|
|
|
annotations: {
|
|
|
|
|
readonly title: string
|
|
|
|
|
readonly readOnly: boolean
|
|
|
|
|
readonly destructive: boolean
|
|
|
|
|
readonly idempotent: boolean
|
|
|
|
|
readonly openWorld: boolean
|
|
|
|
|
readonly strict?: boolean
|
|
|
|
|
},
|
2026-06-02 00:22:04 -05:00
|
|
|
): Tool.Tool<Name, Config, Requirements> =>
|
2026-06-01 16:22:25 -05:00
|
|
|
tool
|
|
|
|
|
.annotate(Tool.Title, annotations.title)
|
|
|
|
|
.annotate(Tool.Readonly, annotations.readOnly)
|
|
|
|
|
.annotate(Tool.Destructive, annotations.destructive)
|
|
|
|
|
.annotate(Tool.Idempotent, annotations.idempotent)
|
|
|
|
|
.annotate(Tool.OpenWorld, annotations.openWorld)
|
2026-06-02 00:22:04 -05:00
|
|
|
.annotate(Tool.Strict, annotations.strict ?? true)
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
class PromptSummary extends S.Class<PromptSummary>("PromptSummary")(
|
|
|
|
|
{
|
|
|
|
|
id: S.String.annotateKey({
|
|
|
|
|
description: "Stable prompt template identifier used with get_prompt",
|
|
|
|
|
}),
|
|
|
|
|
name: S.String.annotateKey({
|
|
|
|
|
description: "Human-readable prompt template name",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const IriTerm = S.Struct({
|
|
|
|
|
t: S.Literals(["i"]).annotateKey({
|
|
|
|
|
description: "Term type discriminator for an IRI node",
|
|
|
|
|
}),
|
|
|
|
|
i: S.String.annotateKey({
|
|
|
|
|
description: "IRI value for the graph node or predicate",
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const BlankTerm = S.Struct({
|
|
|
|
|
t: S.Literals(["b"]).annotateKey({
|
|
|
|
|
description: "Term type discriminator for a blank node",
|
|
|
|
|
}),
|
|
|
|
|
d: S.String.annotateKey({
|
|
|
|
|
description: "Blank node identifier",
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const LiteralTerm = S.Struct({
|
|
|
|
|
t: S.Literals(["l"]).annotateKey({
|
|
|
|
|
description: "Term type discriminator for a literal value",
|
|
|
|
|
}),
|
|
|
|
|
v: S.String.annotateKey({
|
|
|
|
|
description: "Literal lexical value",
|
|
|
|
|
}),
|
|
|
|
|
dt: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Optional literal datatype IRI",
|
|
|
|
|
}),
|
|
|
|
|
ln: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Optional literal language tag",
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const ReifiedTripleTerm = S.Struct({
|
|
|
|
|
t: S.Literals(["t"]).annotateKey({
|
|
|
|
|
description: "Term type discriminator for a reified triple",
|
|
|
|
|
}),
|
|
|
|
|
tr: S.optionalKey(S.Json).annotateKey({
|
|
|
|
|
description: "Optional embedded triple payload",
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const Term = S.Union([IriTerm, BlankTerm, LiteralTerm, ReifiedTripleTerm])
|
|
|
|
|
|
|
|
|
|
const Triple = S.Struct({
|
|
|
|
|
s: Term.annotateKey({
|
|
|
|
|
description: "Triple subject term",
|
|
|
|
|
}),
|
|
|
|
|
p: Term.annotateKey({
|
|
|
|
|
description: "Triple predicate term",
|
|
|
|
|
}),
|
|
|
|
|
o: Term.annotateKey({
|
|
|
|
|
description: "Triple object term",
|
|
|
|
|
}),
|
|
|
|
|
g: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Optional named graph or collection identifier",
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const ToolTextResult = S.String.annotateKey({
|
|
|
|
|
description: "Human-readable text result returned by the tool",
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const TrustGraphJsonPayload = S.Json.annotateKey({
|
|
|
|
|
description: "JSON-safe payload returned by the TrustGraph gateway",
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const ToolErrorMessage = S.String.annotateKey({
|
|
|
|
|
description: "Concise human-readable error message suitable for explaining the failure to a user",
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export const makeMcpServer = (
|
|
|
|
|
name: string,
|
|
|
|
|
version: string,
|
|
|
|
|
) => McpServer.layer(
|
|
|
|
|
{
|
|
|
|
|
version,
|
|
|
|
|
name,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class TextCompletionSuccess extends S.Class<TextCompletionSuccess>("TextCompletionSuccess")(
|
|
|
|
|
{
|
|
|
|
|
text: ToolTextResult,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class TextCompletionError extends S.TaggedErrorClass<TextCompletionError>()(
|
|
|
|
|
"TextCompletionError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class TextCompletionParameters extends S.Class<TextCompletionParameters>("TextCompletionParameters")(
|
|
|
|
|
{
|
|
|
|
|
system: S.String.annotateKey({
|
|
|
|
|
description: "System prompt",
|
|
|
|
|
}),
|
|
|
|
|
prompt: S.String.annotateKey({
|
|
|
|
|
description: "User prompt",
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const TextCompletionTool = annotateTool(
|
|
|
|
|
Tool.make("text_completion", {
|
|
|
|
|
description: "Run a text completion using the configured LLM",
|
|
|
|
|
parameters: TextCompletionParameters,
|
|
|
|
|
success: TextCompletionSuccess,
|
|
|
|
|
failure: TextCompletionError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Text Completion",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GraphRagSuccess extends S.Class<GraphRagSuccess>("GraphRagSuccess")(
|
|
|
|
|
{
|
|
|
|
|
text: ToolTextResult,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GraphRagError extends S.TaggedErrorClass<GraphRagError>()(
|
|
|
|
|
"GraphRagError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GraphRagParameters extends S.Class<GraphRagParameters>("GraphRagParameters")(
|
|
|
|
|
{
|
|
|
|
|
query: S.String.annotateKey({
|
|
|
|
|
description: "Natural language query",
|
|
|
|
|
}),
|
|
|
|
|
entity_limit: S.optionalKey(S.Int).annotateKey({
|
|
|
|
|
description: "Max entities to retrieve"
|
|
|
|
|
}),
|
|
|
|
|
triple_limit: S.optionalKey(S.Int).annotateKey({
|
|
|
|
|
description: "Max triples per entity"
|
|
|
|
|
}),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GraphRagTool = annotateTool(
|
|
|
|
|
Tool.make("graph_rag", {
|
|
|
|
|
description: "Query the knowledge graph using RAG",
|
|
|
|
|
parameters: GraphRagParameters,
|
|
|
|
|
success: GraphRagSuccess,
|
|
|
|
|
failure: GraphRagError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Graph RAG",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class DocumentRagSuccess extends S.Class<DocumentRagSuccess>("DocumentRagSuccess")(
|
|
|
|
|
{
|
|
|
|
|
text: ToolTextResult,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DocumentRagError extends S.TaggedErrorClass<DocumentRagError>()(
|
|
|
|
|
"DocumentRagError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DocumentRagParameters extends S.Class<DocumentRagParameters>("DocumentRagParameters")(
|
|
|
|
|
{
|
|
|
|
|
query: S.String.annotateKey({
|
|
|
|
|
description: "Natural language query",
|
|
|
|
|
}),
|
|
|
|
|
doc_limit: S.optionalKey(S.Int).annotateKey({
|
|
|
|
|
description: "Max documents to retrieve"
|
|
|
|
|
}),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const DocumentRagTool = annotateTool(
|
|
|
|
|
Tool.make("document_rag", {
|
|
|
|
|
description: "Query documents using RAG",
|
|
|
|
|
parameters: DocumentRagParameters,
|
|
|
|
|
success: DocumentRagSuccess,
|
|
|
|
|
failure: DocumentRagError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Document RAG",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class AgentSuccess extends S.Class<AgentSuccess>("AgentSuccess")(
|
|
|
|
|
{
|
|
|
|
|
text: ToolTextResult,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class AgentError extends S.TaggedErrorClass<AgentError>()(
|
|
|
|
|
"AgentError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class AgentParameters extends S.Class<AgentParameters>("AgentParameters")(
|
|
|
|
|
{
|
|
|
|
|
question: S.String.annotateKey({
|
|
|
|
|
description: "Question for the agent"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const AgentTool = annotateTool(
|
|
|
|
|
Tool.make("agent", {
|
|
|
|
|
parameters: AgentParameters,
|
|
|
|
|
success: AgentSuccess,
|
|
|
|
|
failure: AgentError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Ask the TrustGraph agent a question"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "TrustGraph Agent",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class EmbeddingsSuccess extends S.Class<EmbeddingsSuccess>("EmbeddingsSuccess")(
|
|
|
|
|
{
|
|
|
|
|
vectors: S.Finite.pipe(S.Array, S.Array).annotateKey({
|
|
|
|
|
description: "Embedding vectors in the same order as the input texts",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class EmbeddingsError extends S.TaggedErrorClass<EmbeddingsError>()(
|
|
|
|
|
"EmbeddingsError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class EmbeddingsParameters extends S.Class<EmbeddingsParameters>("EmbeddingsParameters")(
|
|
|
|
|
{
|
|
|
|
|
text: S.Array(S.String).annotateKey({
|
|
|
|
|
description: "Texts to embed"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const EmbeddingsTool = annotateTool(
|
|
|
|
|
Tool.make("embeddings", {
|
|
|
|
|
parameters: EmbeddingsParameters,
|
|
|
|
|
success: EmbeddingsSuccess,
|
|
|
|
|
failure: EmbeddingsError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Generate text embeddings"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Generate Embeddings",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class TriplesQuerySuccess extends S.Class<TriplesQuerySuccess>("TriplesQuerySuccess")(
|
|
|
|
|
{
|
|
|
|
|
triples: S.Array(Triple).annotateKey({
|
|
|
|
|
description: "Knowledge graph triples matching the requested subject, predicate, object, collection, and limit filters",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class TriplesQueryError extends S.TaggedErrorClass<TriplesQueryError>()(
|
|
|
|
|
"TriplesQueryError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class TriplesQueryParameters extends S.Class<TriplesQueryParameters>("TriplesQueryParameters")(
|
|
|
|
|
{
|
|
|
|
|
s: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Subject IRI"
|
|
|
|
|
}),
|
|
|
|
|
p: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Predicate IRI"
|
|
|
|
|
}),
|
|
|
|
|
o: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Object IRI or literal"
|
|
|
|
|
}),
|
|
|
|
|
limit: S.optionalKey(S.Int).annotateKey({
|
|
|
|
|
description: "Max results"
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const TriplesQueryTool = annotateTool(
|
|
|
|
|
Tool.make("triples_query", {
|
|
|
|
|
parameters: TriplesQueryParameters,
|
|
|
|
|
success: TriplesQuerySuccess,
|
|
|
|
|
failure: TriplesQueryError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Query the knowledge graph for triples matching a pattern"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Triples Query",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GraphEmbeddingsQuerySuccess extends S.Class<GraphEmbeddingsQuerySuccess>("GraphEmbeddingsQuerySuccess")(
|
|
|
|
|
{
|
|
|
|
|
entities: S.Array(
|
|
|
|
|
S.Struct({
|
|
|
|
|
entity: S.NullOr(Term).annotateKey({
|
|
|
|
|
description: "Matched graph entity term, or null when the backend could not resolve one",
|
|
|
|
|
}),
|
|
|
|
|
score: S.Finite.annotateKey({
|
|
|
|
|
description: "Similarity score returned by the vector index",
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
|
).annotateKey({
|
|
|
|
|
description: "Entities most similar to the query vector, with higher scores indicating stronger similarity",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GraphEmbeddingsQueryError extends S.TaggedErrorClass<GraphEmbeddingsQueryError>()(
|
|
|
|
|
"GraphEmbeddingsQueryError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GraphEmbeddingsQueryParameters extends S.Class<GraphEmbeddingsQueryParameters>("GraphEmbeddingsQueryParameters")(
|
|
|
|
|
{
|
|
|
|
|
query: S.String.annotateKey({
|
|
|
|
|
description: "Text to find similar entities for"
|
|
|
|
|
}),
|
|
|
|
|
limit: S.optionalKey(S.Int).annotateKey({
|
|
|
|
|
description: "Max results"
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GraphEmbeddingsQueryTool = annotateTool(
|
|
|
|
|
Tool.make("graph_embeddings_query", {
|
|
|
|
|
parameters: GraphEmbeddingsQueryParameters,
|
|
|
|
|
success: GraphEmbeddingsQuerySuccess,
|
|
|
|
|
failure: GraphEmbeddingsQueryError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Find entities similar to a text query using vector embeddings"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Graph Embeddings Query",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetConfigAllSuccess extends S.Class<GetConfigAllSuccess>("GetConfigAllSuccess")(
|
|
|
|
|
{
|
|
|
|
|
config: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetConfigAllError extends S.TaggedErrorClass<GetConfigAllError>()(
|
|
|
|
|
"GetConfigAllError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetConfigAllParameters extends S.Class<GetConfigAllParameters>("GetConfigAllParameters")(
|
|
|
|
|
{}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetConfigAllTool = annotateTool(
|
|
|
|
|
Tool.make("get_config_all", {
|
|
|
|
|
parameters: GetConfigAllParameters,
|
|
|
|
|
success: GetConfigAllSuccess,
|
|
|
|
|
failure: GetConfigAllError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Get all configuration values"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get All Config",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class GetConfigSuccess extends S.Class<GetConfigSuccess>("GetConfigSuccess")(
|
|
|
|
|
{
|
|
|
|
|
config: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetConfigError extends S.TaggedErrorClass<GetConfigError>()(
|
|
|
|
|
"GetConfigError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetConfigParameters extends S.Class<GetConfigParameters>("GetConfigParameters")(
|
|
|
|
|
{
|
|
|
|
|
keys: S.Array(
|
|
|
|
|
S.Struct({
|
|
|
|
|
type: S.String.annotateKey({
|
|
|
|
|
description: "Config type"
|
|
|
|
|
}),
|
|
|
|
|
key: S.String.annotateKey({
|
|
|
|
|
description: "Config key"
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
).annotateKey({
|
|
|
|
|
description: "Config keys to retrieve"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetConfigTool = annotateTool(
|
|
|
|
|
Tool.make("get_config", {
|
|
|
|
|
parameters: GetConfigParameters,
|
|
|
|
|
success: GetConfigSuccess,
|
|
|
|
|
failure: GetConfigError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Get specific configuration values"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Config",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class PutConfigSuccess extends S.Class<PutConfigSuccess>("PutConfigSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class PutConfigError extends S.TaggedErrorClass<PutConfigError>()(
|
|
|
|
|
"PutConfigError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class PutConfigParameters extends S.Class<PutConfigParameters>("PutConfigParameters")(
|
|
|
|
|
{
|
|
|
|
|
values: S.Array(
|
|
|
|
|
S.Struct({
|
|
|
|
|
type: S.String.annotateKey({
|
|
|
|
|
description: "Config type"
|
|
|
|
|
}),
|
|
|
|
|
key: S.String.annotateKey({
|
|
|
|
|
description: "Config key"
|
|
|
|
|
}),
|
|
|
|
|
value: S.String.annotateKey({
|
|
|
|
|
description: "Config values (JSON-encoded)"
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
).annotateKey({
|
|
|
|
|
description: "Key-value entries to set"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const PutConfigTool = annotateTool(
|
|
|
|
|
Tool.make("put_config", {
|
|
|
|
|
parameters: PutConfigParameters,
|
|
|
|
|
success: PutConfigSuccess,
|
|
|
|
|
failure: PutConfigError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Set configuration values"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Put Config",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: true,
|
|
|
|
|
idempotent: true,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class DeleteConfigSuccess extends S.Class<DeleteConfigSuccess>("DeleteConfigSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DeleteConfigError extends S.TaggedErrorClass<DeleteConfigError>()(
|
|
|
|
|
"DeleteConfigError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DeleteConfigParameters extends S.Class<DeleteConfigParameters>("DeleteConfigParameters")(
|
|
|
|
|
{
|
|
|
|
|
type: S.String.annotateKey({
|
|
|
|
|
description: "Config type"
|
|
|
|
|
}),
|
|
|
|
|
key: S.String.annotateKey({
|
|
|
|
|
description: "Config key"
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const DeleteConfigTool = annotateTool(
|
|
|
|
|
Tool.make("delete_config", {
|
|
|
|
|
parameters: DeleteConfigParameters,
|
|
|
|
|
success: DeleteConfigSuccess,
|
|
|
|
|
failure: DeleteConfigError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Delete a configuration entry"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Delete Config",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: true,
|
|
|
|
|
idempotent: true,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetFlowSuccess extends S.Class<GetFlowSuccess>("GetFlowSuccess")(
|
|
|
|
|
{
|
|
|
|
|
flow: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetFlowError extends S.TaggedErrorClass<GetFlowError>()(
|
|
|
|
|
"GetFlowError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetFlowParameters extends S.Class<GetFlowParameters>("GetFlowParameters")(
|
|
|
|
|
{
|
|
|
|
|
flow_id: S.String.annotateKey({
|
|
|
|
|
description: "Flow ID to retrieve"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetFlowTool = annotateTool(
|
|
|
|
|
Tool.make("get_flow", {
|
|
|
|
|
parameters: GetFlowParameters,
|
|
|
|
|
success: GetFlowSuccess,
|
|
|
|
|
failure: GetFlowError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Get a specific flow definition"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Flow",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetFlowsSuccess extends S.Class<GetFlowsSuccess>("GetFlowsSuccess")(
|
|
|
|
|
{
|
|
|
|
|
flow_ids: S.Array(S.String).annotateKey({
|
|
|
|
|
description: "Available TrustGraph flow identifiers",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetFlowsError extends S.TaggedErrorClass<GetFlowsError>()(
|
|
|
|
|
"GetFlowsError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetFlowsParameters extends S.Class<GetFlowsParameters>("GetFlowsParameters")(
|
|
|
|
|
{}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetFlowsTool = annotateTool(
|
|
|
|
|
Tool.make("get_flows", {
|
|
|
|
|
parameters: GetFlowsParameters,
|
|
|
|
|
success: GetFlowsSuccess,
|
|
|
|
|
failure: GetFlowsError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "List all available flows"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Flows",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class StartFlowSuccess extends S.Class<StartFlowSuccess>("StartFlowSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class StartFlowError extends S.TaggedErrorClass<StartFlowError>()(
|
|
|
|
|
"StartFlowError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class StartFlowParameters extends S.Class<StartFlowParameters>("StartFlowParameters")(
|
|
|
|
|
{
|
|
|
|
|
flow_id: S.String.annotateKey({
|
|
|
|
|
description: "Flow ID"
|
|
|
|
|
}),
|
|
|
|
|
blueprint_name: S.String.annotateKey({
|
|
|
|
|
description: "Blueprint name"
|
|
|
|
|
}),
|
|
|
|
|
description: S.String.annotateKey({
|
|
|
|
|
description: "Flow description"
|
|
|
|
|
}),
|
|
|
|
|
parameters: S.optionalKey(S.Record(S.String, S.Unknown)).annotateKey({
|
|
|
|
|
description: "Optional flow parameters"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const StartFlowTool = annotateTool(
|
|
|
|
|
Tool.make("start_flow", {
|
|
|
|
|
parameters: StartFlowParameters,
|
|
|
|
|
success: StartFlowSuccess,
|
|
|
|
|
failure: StartFlowError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Start a flow instance"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Start Flow",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class StopFlowSuccess extends S.Class<StopFlowSuccess>("StopFlowSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class StopFlowError extends S.TaggedErrorClass<StopFlowError>()(
|
|
|
|
|
"StopFlowError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class StopFlowParameters extends S.Class<StopFlowParameters>("StopFlowParameters")(
|
|
|
|
|
{
|
|
|
|
|
flow_id: S.String.annotateKey({
|
|
|
|
|
description: "Flow ID to stop"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const StopFlowTool = annotateTool(
|
|
|
|
|
Tool.make("stop_flow", {
|
|
|
|
|
parameters: StopFlowParameters,
|
|
|
|
|
success: StopFlowSuccess,
|
|
|
|
|
failure: StopFlowError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Stop a running flow"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Stop Flow",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: true,
|
|
|
|
|
idempotent: true,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetDocumentsSuccess extends S.Class<GetDocumentsSuccess>("GetDocumentsSuccess")(
|
|
|
|
|
{
|
|
|
|
|
documents: S.Array(S.Json).annotateKey({
|
|
|
|
|
description: "Document metadata records currently registered in the TrustGraph library",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetDocumentsError extends S.TaggedErrorClass<GetDocumentsError>()(
|
|
|
|
|
"GetDocumentsError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetDocumentsParameters extends S.Class<GetDocumentsParameters>("GetDocumentsParameters")(
|
|
|
|
|
{}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetDocumentsTool = annotateTool(
|
|
|
|
|
Tool.make("get_documents", {
|
|
|
|
|
parameters: GetDocumentsParameters,
|
|
|
|
|
success: GetDocumentsSuccess,
|
|
|
|
|
failure: GetDocumentsError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "List all documents in the library"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Documents",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class LoadDocumentSuccess extends S.Class<LoadDocumentSuccess>("LoadDocumentSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class LoadDocumentError extends S.TaggedErrorClass<LoadDocumentError>()(
|
|
|
|
|
"LoadDocumentError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class LoadDocumentParameters extends S.Class<LoadDocumentParameters>("LoadDocumentParameters")(
|
|
|
|
|
{
|
|
|
|
|
document: S.String.annotateKey({
|
|
|
|
|
description: "Base64-encoded document content"
|
|
|
|
|
}),
|
|
|
|
|
mime_type: S.String.annotateKey({
|
|
|
|
|
description: "Document MIME type"
|
|
|
|
|
}),
|
|
|
|
|
title: S.String.annotateKey({
|
|
|
|
|
description: "Document title"
|
|
|
|
|
}),
|
|
|
|
|
comments: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Additional comments"
|
|
|
|
|
}),
|
|
|
|
|
tags: S.String.pipe(S.Array, S.optionalKey).annotateKey({
|
|
|
|
|
description: "Document tags"
|
|
|
|
|
}),
|
|
|
|
|
id: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Optional document ID"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const LoadDocumentTool = annotateTool(
|
|
|
|
|
Tool.make("load_document", {
|
|
|
|
|
parameters: LoadDocumentParameters,
|
|
|
|
|
success: LoadDocumentSuccess,
|
|
|
|
|
failure: LoadDocumentError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Upload a document to the library"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Load Document",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class RemoveDocumentSuccess extends S.Class<RemoveDocumentSuccess>("RemoveDocumentSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class RemoveDocumentError extends S.TaggedErrorClass<RemoveDocumentError>()(
|
|
|
|
|
"RemoveDocumentError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class RemoveDocumentParameters extends S.Class<RemoveDocumentParameters>("RemoveDocumentParameters")(
|
|
|
|
|
{
|
|
|
|
|
id: S.String.annotateKey({
|
|
|
|
|
description: "Document ID to remove"
|
|
|
|
|
}),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const RemoveDocumentTool = annotateTool(
|
|
|
|
|
Tool.make("remove_document", {
|
|
|
|
|
parameters: RemoveDocumentParameters,
|
|
|
|
|
success: RemoveDocumentSuccess,
|
|
|
|
|
failure: RemoveDocumentError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Remove a document from the library"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Remove Document",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: true,
|
|
|
|
|
idempotent: true,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetPromptsSuccess extends S.Class<GetPromptsSuccess>("GetPromptsSuccess")(
|
|
|
|
|
{
|
|
|
|
|
prompts: S.Array(PromptSummary).annotateKey({
|
|
|
|
|
description: "Prompt templates available for retrieval with get_prompt",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetPromptsError extends S.TaggedErrorClass<GetPromptsError>()(
|
|
|
|
|
"GetPromptsError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetPromptsParameters extends S.Class<GetPromptsParameters>("GetPromptsParameters")(
|
|
|
|
|
{}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetPromptsTool = annotateTool(
|
|
|
|
|
Tool.make("get_prompts", {
|
|
|
|
|
parameters: GetPromptsParameters,
|
|
|
|
|
success: GetPromptsSuccess,
|
|
|
|
|
failure: GetPromptsError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "List available prompt templates"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Prompts",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetPromptSuccess extends S.Class<GetPromptSuccess>("GetPromptSuccess")(
|
|
|
|
|
{
|
|
|
|
|
prompt: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetPromptError extends S.TaggedErrorClass<GetPromptError>()(
|
|
|
|
|
"GetPromptError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetPromptParameters extends S.Class<GetPromptParameters>("GetPromptParameters")(
|
|
|
|
|
{
|
|
|
|
|
id: S.String.annotateKey({
|
|
|
|
|
description: "Prompt template ID"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetPromptTool = annotateTool(
|
|
|
|
|
Tool.make("get_prompt", {
|
|
|
|
|
parameters: GetPromptParameters,
|
|
|
|
|
success: GetPromptSuccess,
|
|
|
|
|
failure: GetPromptError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Get a specific prompt template"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Prompt",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class GetKnowledgeCoresSuccess extends S.Class<GetKnowledgeCoresSuccess>("GetKnowledgeCoresSuccess")(
|
|
|
|
|
{
|
|
|
|
|
ids: S.Array(S.String).annotateKey({
|
|
|
|
|
description: "Available knowledge graph core identifiers",
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetKnowledgeCoresError extends S.TaggedErrorClass<GetKnowledgeCoresError>()(
|
|
|
|
|
"GetKnowledgeCoresError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetKnowledgeCoresParameters extends S.Class<GetKnowledgeCoresParameters>("GetKnowledgeCoresParameters")(
|
|
|
|
|
{}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GetKnowledgeCoresTool = annotateTool(
|
|
|
|
|
Tool.make("get_knowledge_cores", {
|
|
|
|
|
parameters: GetKnowledgeCoresParameters,
|
|
|
|
|
success: GetKnowledgeCoresSuccess,
|
|
|
|
|
failure: GetKnowledgeCoresError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "List available knowledge graph cores"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Get Knowledge Cores",
|
|
|
|
|
readOnly: true,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class DeleteKgCoreSuccess extends S.Class<DeleteKgCoreSuccess>("DeleteKgCoreSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DeleteKgCoreError extends S.TaggedErrorClass<DeleteKgCoreError>()(
|
|
|
|
|
"DeleteKgCoreError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DeleteKgCoreParameters extends S.Class<DeleteKgCoreParameters>("DeleteKgCoreParameters")(
|
|
|
|
|
{
|
|
|
|
|
id: S.String.annotateKey({
|
|
|
|
|
description: "Knowledge core ID"
|
|
|
|
|
}),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const DeleteKgCoreTool = annotateTool(
|
|
|
|
|
Tool.make("delete_kg_core", {
|
|
|
|
|
parameters: DeleteKgCoreParameters,
|
|
|
|
|
success: DeleteKgCoreSuccess,
|
|
|
|
|
failure: DeleteKgCoreError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Delete a knowledge graph core"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Delete KG Core",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: true,
|
|
|
|
|
idempotent: true,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class LoadKgCoreSuccess extends S.Class<LoadKgCoreSuccess>("LoadKgCoreSuccess")(
|
|
|
|
|
{
|
|
|
|
|
response: TrustGraphJsonPayload,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class LoadKgCoreError extends S.TaggedErrorClass<LoadKgCoreError>()(
|
|
|
|
|
"LoadKgCoreError",
|
|
|
|
|
{
|
|
|
|
|
message: ToolErrorMessage,
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class LoadKgCoreParameters extends S.Class<LoadKgCoreParameters>("LoadKgCoreParameters")(
|
|
|
|
|
{
|
|
|
|
|
id: S.String.annotateKey({
|
|
|
|
|
description: "Knowledge core ID"
|
|
|
|
|
}),
|
|
|
|
|
flow: S.String.annotateKey({
|
|
|
|
|
description: "Flow to use for loading"
|
|
|
|
|
}),
|
|
|
|
|
collection: S.optionalKey(S.String).annotateKey({
|
|
|
|
|
description: "Collection name"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const LoadKgCoreTool = annotateTool(
|
|
|
|
|
Tool.make("load_kg_core", {
|
|
|
|
|
parameters: LoadKgCoreParameters,
|
|
|
|
|
success: LoadKgCoreSuccess,
|
|
|
|
|
failure: LoadKgCoreError,
|
2026-06-06 11:01:17 -05:00
|
|
|
failureMode: "error",
|
2026-06-01 16:22:25 -05:00
|
|
|
description: "Load a knowledge graph core"
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
title: "Load KG Core",
|
|
|
|
|
readOnly: false,
|
|
|
|
|
destructive: false,
|
|
|
|
|
idempotent: false,
|
|
|
|
|
openWorld: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export const TrustGraphMcpToolkit = Toolkit.make(
|
|
|
|
|
TextCompletionTool,
|
|
|
|
|
GraphRagTool,
|
|
|
|
|
DocumentRagTool,
|
|
|
|
|
AgentTool,
|
|
|
|
|
EmbeddingsTool,
|
|
|
|
|
TriplesQueryTool,
|
|
|
|
|
GraphEmbeddingsQueryTool,
|
|
|
|
|
GetConfigAllTool,
|
|
|
|
|
GetConfigTool,
|
|
|
|
|
PutConfigTool,
|
|
|
|
|
DeleteConfigTool,
|
|
|
|
|
GetFlowsTool,
|
|
|
|
|
GetFlowTool,
|
|
|
|
|
StartFlowTool,
|
|
|
|
|
StopFlowTool,
|
|
|
|
|
GetDocumentsTool,
|
|
|
|
|
LoadDocumentTool,
|
|
|
|
|
RemoveDocumentTool,
|
|
|
|
|
GetPromptsTool,
|
|
|
|
|
GetPromptTool,
|
|
|
|
|
GetKnowledgeCoresTool,
|
|
|
|
|
DeleteKgCoreTool,
|
|
|
|
|
LoadKgCoreTool,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export interface TrustGraphMcpOptions {
|
|
|
|
|
readonly gatewayUrl?: string | undefined
|
|
|
|
|
readonly user?: string | undefined
|
|
|
|
|
readonly token?: string | undefined
|
|
|
|
|
readonly flowId?: string | undefined
|
|
|
|
|
readonly name?: string | undefined
|
|
|
|
|
readonly version?: string | undefined
|
|
|
|
|
readonly mcpPath?: HttpRouter.PathInput | undefined
|
|
|
|
|
readonly port?: number | undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TrustGraphMcpConfigShape {
|
|
|
|
|
readonly gatewayUrl: string
|
|
|
|
|
readonly user: string
|
|
|
|
|
readonly token: string | undefined
|
|
|
|
|
readonly flowId: string
|
|
|
|
|
readonly name: string
|
|
|
|
|
readonly version: string
|
|
|
|
|
readonly mcpPath: HttpRouter.PathInput
|
|
|
|
|
readonly port: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const readNonEmpty = (value: string | undefined): string | undefined =>
|
|
|
|
|
value !== undefined && value.length > 0 ? value : undefined
|
|
|
|
|
|
2026-06-11 06:29:29 -05:00
|
|
|
const gatewayUrlWithToken = (config: TrustGraphMcpConfigShape): string => {
|
|
|
|
|
if (config.token === undefined || config.token.length === 0) return config.gatewayUrl
|
|
|
|
|
const separator = config.gatewayUrl.includes("?") ? "&" : "?"
|
|
|
|
|
return `${config.gatewayUrl}${separator}token=${encodeURIComponent(config.token)}`
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-02 00:22:04 -05:00
|
|
|
const parsePort = (raw: string | undefined): number => {
|
2026-06-01 16:22:25 -05:00
|
|
|
if (raw === undefined) {
|
|
|
|
|
return 3000
|
|
|
|
|
}
|
|
|
|
|
const parsed = Number.parseInt(raw, 10)
|
|
|
|
|
return Number.isFinite(parsed) ? parsed : 3000
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-02 00:22:04 -05:00
|
|
|
export const loadTrustGraphMcpConfig = Effect.fn("loadTrustGraphMcpConfig")(function*(
|
2026-06-01 16:22:25 -05:00
|
|
|
options: TrustGraphMcpOptions = {},
|
2026-06-02 00:22:04 -05:00
|
|
|
) {
|
|
|
|
|
const gatewayUrl = O.getOrUndefined(yield* Config.string("GATEWAY_URL").pipe(Config.option))
|
|
|
|
|
const user = O.getOrUndefined(yield* Config.string("USER_ID").pipe(Config.option))
|
|
|
|
|
const gatewaySecret = O.getOrUndefined(yield* Config.string("GATEWAY_SECRET").pipe(Config.option))
|
|
|
|
|
const token = readNonEmpty(gatewaySecret)
|
|
|
|
|
const flowId = O.getOrUndefined(yield* Config.string("FLOW_ID").pipe(Config.option))
|
|
|
|
|
const port = O.getOrUndefined(yield* Config.string("PORT").pipe(Config.option))
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
gatewayUrl: options.gatewayUrl ?? gatewayUrl ?? "ws://localhost:8088/api/v1/rpc",
|
|
|
|
|
user: options.user ?? user ?? "mcp",
|
|
|
|
|
token: options.token ?? token,
|
|
|
|
|
flowId: options.flowId ?? flowId ?? "default",
|
|
|
|
|
name: options.name ?? "trustgraph",
|
|
|
|
|
version: options.version ?? "0.1.0",
|
|
|
|
|
mcpPath: options.mcpPath ?? "/mcp",
|
|
|
|
|
port: options.port ?? parsePort(readNonEmpty(port)),
|
|
|
|
|
}
|
2026-06-01 16:22:25 -05:00
|
|
|
})
|
|
|
|
|
|
2026-06-02 00:22:04 -05:00
|
|
|
export const resolveTrustGraphMcpConfig = (
|
|
|
|
|
options: TrustGraphMcpOptions = {},
|
|
|
|
|
): TrustGraphMcpConfigShape => Effect.runSync(loadTrustGraphMcpConfig(options))
|
|
|
|
|
|
2026-06-01 16:22:25 -05:00
|
|
|
export class TrustGraphMcpConfig extends Context.Service<TrustGraphMcpConfig, TrustGraphMcpConfigShape>()(
|
|
|
|
|
"@trustgraph/mcp/server-effect/TrustGraphMcpConfig",
|
|
|
|
|
) {
|
|
|
|
|
static readonly layer = (options: TrustGraphMcpOptions = {}) =>
|
2026-06-02 00:22:04 -05:00
|
|
|
Layer.effect(
|
2026-06-01 16:22:25 -05:00
|
|
|
TrustGraphMcpConfig,
|
2026-06-02 00:22:04 -05:00
|
|
|
loadTrustGraphMcpConfig(options).pipe(Effect.map(TrustGraphMcpConfig.of)),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class TrustGraphSocket extends Context.Service<TrustGraphSocket, BaseApi>()(
|
|
|
|
|
"@trustgraph/mcp/server-effect/TrustGraphSocket",
|
|
|
|
|
) {
|
|
|
|
|
static readonly layer = Layer.effect(
|
|
|
|
|
TrustGraphSocket,
|
|
|
|
|
Effect.gen(function*() {
|
|
|
|
|
const config = yield* TrustGraphMcpConfig
|
|
|
|
|
const socket = yield* Effect.acquireRelease(
|
|
|
|
|
Effect.sync(() => createTrustGraphSocket(config.user, config.token, config.gatewayUrl)),
|
|
|
|
|
(socket) => Effect.sync(() => socket.close()),
|
|
|
|
|
)
|
|
|
|
|
return TrustGraphSocket.of(socket)
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-11 06:29:29 -05:00
|
|
|
export class TrustGraphGateway extends Context.Service<TrustGraphGateway, TrustGraphGatewayClient>()(
|
|
|
|
|
"@trustgraph/mcp/server-effect/TrustGraphGateway",
|
|
|
|
|
) {
|
|
|
|
|
static readonly layer = Layer.effect(
|
|
|
|
|
TrustGraphGateway,
|
|
|
|
|
Effect.gen(function*() {
|
|
|
|
|
const config = yield* TrustGraphMcpConfig
|
|
|
|
|
const client = yield* makeTrustGraphGatewayClientScoped({url: gatewayUrlWithToken(config)})
|
|
|
|
|
return TrustGraphGateway.of(client)
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-01 16:22:25 -05:00
|
|
|
const toErrorMessage = (cause: unknown): string => {
|
2026-06-02 00:22:04 -05:00
|
|
|
if (Predicate.isError(cause) && cause.message.length > 0) {
|
2026-06-01 16:22:25 -05:00
|
|
|
return cause.message
|
|
|
|
|
}
|
|
|
|
|
if (typeof cause === "string" && cause.length > 0) {
|
|
|
|
|
return cause
|
|
|
|
|
}
|
2026-06-02 00:22:04 -05:00
|
|
|
if (Predicate.isObject(cause) && Predicate.hasProperty(cause, "message") && Predicate.isString(cause.message) && cause.message.length > 0) {
|
|
|
|
|
return cause.message
|
2026-06-01 16:22:25 -05:00
|
|
|
}
|
|
|
|
|
return "TrustGraph MCP tool failed"
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-11 06:29:29 -05:00
|
|
|
const asRecord = (value: unknown): Record<string, unknown> =>
|
|
|
|
|
Predicate.isObject(value) && !Array.isArray(value) ? value as Record<string, unknown> : {}
|
|
|
|
|
|
|
|
|
|
const stringProperty = (source: unknown, key: string): string | undefined => {
|
|
|
|
|
const value = asRecord(source)[key]
|
|
|
|
|
return Predicate.isString(value) ? value : undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const booleanProperty = (source: unknown, key: string): boolean | undefined => {
|
|
|
|
|
const value = asRecord(source)[key]
|
|
|
|
|
return typeof value === "boolean" ? value : undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const responseErrorMessage = (source: unknown): string | undefined => {
|
|
|
|
|
const error = asRecord(source).error
|
|
|
|
|
if (Predicate.isString(error)) return error
|
|
|
|
|
return stringProperty(error, "message")
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-01 16:22:25 -05:00
|
|
|
const decodeJson = S.decodeUnknownEffect(S.Json)
|
|
|
|
|
const decodeJsonArray = S.decodeUnknownEffect(S.Array(S.Json))
|
|
|
|
|
|
|
|
|
|
const decodeJsonOrFail = <E>(
|
|
|
|
|
value: unknown,
|
|
|
|
|
makeError: (cause: unknown) => E,
|
|
|
|
|
) => decodeJson(value).pipe(
|
|
|
|
|
Effect.mapError(makeError),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const decodeJsonArrayOrFail = <E>(
|
|
|
|
|
value: unknown,
|
|
|
|
|
makeError: (cause: unknown) => E,
|
|
|
|
|
) => decodeJsonArray(value).pipe(
|
|
|
|
|
Effect.mapError(makeError),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const asIriTerm = (value: string | undefined): ClientTerm | undefined =>
|
|
|
|
|
value !== undefined && value.length > 0 ? {t: "i", i: value} : undefined
|
|
|
|
|
|
2026-06-11 06:29:29 -05:00
|
|
|
const runAgentTool = Effect.fn("TrustGraphMcpToolkit.agent")(function*(
|
|
|
|
|
gateway: TrustGraphGatewayClient,
|
|
|
|
|
config: TrustGraphMcpConfigShape,
|
|
|
|
|
question: string,
|
|
|
|
|
) {
|
|
|
|
|
let fullAnswer = ""
|
|
|
|
|
let streamError: AgentError | undefined
|
|
|
|
|
|
|
|
|
|
yield* gateway.runDispatchStream(
|
|
|
|
|
{
|
|
|
|
|
scope: "flow",
|
|
|
|
|
flow: config.flowId,
|
|
|
|
|
service: "agent",
|
|
|
|
|
request: {
|
|
|
|
|
question,
|
|
|
|
|
user: config.user,
|
|
|
|
|
collection: "default",
|
|
|
|
|
streaming: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(chunk) => {
|
|
|
|
|
const resp = asRecord(chunk.response)
|
|
|
|
|
const chunkType = stringProperty(resp, "chunk_type")
|
|
|
|
|
const error = chunkType === "error"
|
|
|
|
|
? responseErrorMessage(resp) ?? "Unknown agent error"
|
|
|
|
|
: responseErrorMessage(resp)
|
|
|
|
|
if (error !== undefined) {
|
|
|
|
|
streamError = AgentError.make({message: error})
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (chunkType === "answer" || chunkType === "final-answer") {
|
|
|
|
|
fullAnswer += stringProperty(resp, "content") ?? ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return chunk.complete === true || booleanProperty(resp, "end_of_dialog") === true
|
|
|
|
|
},
|
|
|
|
|
{timeoutMs: 120_000, retries: 2},
|
|
|
|
|
).pipe(
|
|
|
|
|
Effect.mapError((cause) => AgentError.make({message: toErrorMessage(cause)})),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (streamError !== undefined) {
|
|
|
|
|
return yield* streamError
|
|
|
|
|
}
|
|
|
|
|
return AgentSuccess.make({text: fullAnswer})
|
|
|
|
|
})
|
|
|
|
|
|
2026-06-01 16:22:25 -05:00
|
|
|
export const TrustGraphMcpToolkitLive = TrustGraphMcpToolkit.toLayer(
|
|
|
|
|
Effect.gen(function*() {
|
|
|
|
|
const config = yield* TrustGraphMcpConfig
|
|
|
|
|
const socket = yield* TrustGraphSocket
|
2026-06-11 06:29:29 -05:00
|
|
|
const gateway = yield* TrustGraphGateway
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
return TrustGraphMcpToolkit.of({
|
2026-06-06 11:01:17 -05:00
|
|
|
text_completion: ({system, prompt}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.flow(config.flowId).textCompletion(system, prompt),
|
|
|
|
|
catch: (cause) => TextCompletionError.make({message: toErrorMessage(cause)}),
|
|
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((text) => TextCompletionSuccess.make({text})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
graph_rag: ({query, entity_limit, triple_limit, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () =>
|
|
|
|
|
socket.flow(config.flowId).graphRag(
|
2026-06-01 16:22:25 -05:00
|
|
|
query,
|
|
|
|
|
{
|
|
|
|
|
...(entity_limit !== undefined ? {entityLimit: entity_limit} : {}),
|
|
|
|
|
...(triple_limit !== undefined ? {tripleLimit: triple_limit} : {}),
|
|
|
|
|
},
|
|
|
|
|
collection,
|
2026-06-02 00:22:04 -05:00
|
|
|
),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GraphRagError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((text) => GraphRagSuccess.make({text})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
document_rag: ({query, doc_limit, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () => socket.flow(config.flowId).documentRag(query, doc_limit, collection),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => DocumentRagError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((text) => DocumentRagSuccess.make({text})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
2026-06-11 06:29:29 -05:00
|
|
|
agent: ({question}) => runAgentTool(gateway, config, question),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
embeddings: ({text}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () => socket.flow(config.flowId).embeddings([...text]),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => EmbeddingsError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((vectors) => EmbeddingsSuccess.make({vectors})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
triples_query: ({s, p, o, limit, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () =>
|
|
|
|
|
socket.flow(config.flowId).triplesQuery(
|
2026-06-01 16:22:25 -05:00
|
|
|
asIriTerm(s),
|
|
|
|
|
asIriTerm(p),
|
|
|
|
|
asIriTerm(o),
|
|
|
|
|
limit,
|
|
|
|
|
collection,
|
2026-06-02 00:22:04 -05:00
|
|
|
),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => TriplesQueryError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((triples) => TriplesQuerySuccess.make({triples})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
graph_embeddings_query: ({query, limit, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () => socket.flow(config.flowId).embeddings([query]),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GraphEmbeddingsQueryError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((vectors) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.flow(config.flowId).graphEmbeddingsQuery(
|
|
|
|
|
vectors[0] ?? [],
|
|
|
|
|
limit ?? 10,
|
|
|
|
|
collection,
|
|
|
|
|
),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GraphEmbeddingsQueryError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
})
|
|
|
|
|
),
|
|
|
|
|
Effect.map((entities) => GraphEmbeddingsQuerySuccess.make({entities})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
get_config_all: () =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.config().getConfigAll(),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetConfigAllError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => GetConfigAllError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((config) => GetConfigAllSuccess.make({config})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
get_config: ({keys}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.config().getConfig(keys.map(({type, key}) => ({type, key}))),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetConfigError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => GetConfigError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((config) => GetConfigSuccess.make({config})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
put_config: ({values}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.config().putConfig(values.map(({type, key, value}) => ({type, key, value}))),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => PutConfigError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => PutConfigError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => PutConfigSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
delete_config: ({type, key}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.config().deleteConfig({type, key}),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => DeleteConfigError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => DeleteConfigError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => DeleteConfigSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
get_flows: () =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () => socket.flows().getFlows(),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetFlowsError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((flow_ids) => GetFlowsSuccess.make({flow_ids})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
get_flow: ({flow_id}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.flows().getFlow(flow_id),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetFlowError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => GetFlowError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((flow) => GetFlowSuccess.make({flow})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
start_flow: ({flow_id, blueprint_name, description, parameters}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () =>
|
2026-06-01 16:22:25 -05:00
|
|
|
socket.flows().startFlow(
|
|
|
|
|
flow_id,
|
|
|
|
|
blueprint_name,
|
|
|
|
|
description,
|
|
|
|
|
parameters === undefined ? undefined : {...parameters},
|
|
|
|
|
),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => StartFlowError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => StartFlowError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => StartFlowSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
stop_flow: ({flow_id}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.flows().stopFlow(flow_id),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => StopFlowError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => StopFlowError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => StopFlowSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
get_documents: () =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.librarian().getDocuments(),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetDocumentsError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonArrayOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => GetDocumentsError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((documents) => GetDocumentsSuccess.make({documents})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
load_document: ({document, mime_type, title, comments, tags, id}) =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () =>
|
2026-06-01 16:22:25 -05:00
|
|
|
socket.librarian().loadDocument(
|
|
|
|
|
document,
|
|
|
|
|
mime_type,
|
|
|
|
|
title,
|
|
|
|
|
comments ?? "",
|
|
|
|
|
tags === undefined ? [] : [...tags],
|
|
|
|
|
id,
|
|
|
|
|
),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => LoadDocumentError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => LoadDocumentError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => LoadDocumentSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
remove_document: ({id, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.librarian().removeDocument(id, collection),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => RemoveDocumentError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => RemoveDocumentError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => RemoveDocumentSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
get_prompts: () =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () => socket.config().getPrompts(),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetPromptsError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((prompts) => GetPromptsSuccess.make({prompts})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
get_prompt: ({id}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.config().getPrompt(id),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetPromptError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => GetPromptError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((prompt) => GetPromptSuccess.make({prompt})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
get_knowledge_cores: () =>
|
|
|
|
|
Effect.tryPromise({
|
2026-06-02 00:22:04 -05:00
|
|
|
try: () => socket.knowledge().getKnowledgeCores(),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => GetKnowledgeCoresError.make({message: toErrorMessage(cause)}),
|
2026-06-02 00:22:04 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.map((ids) => GetKnowledgeCoresSuccess.make({ids})),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
delete_kg_core: ({id, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.knowledge().deleteKgCore(id, collection),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => DeleteKgCoreError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => DeleteKgCoreError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => DeleteKgCoreSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
load_kg_core: ({id, flow, collection}) =>
|
|
|
|
|
Effect.tryPromise({
|
|
|
|
|
try: () => socket.knowledge().loadKgCore(id, flow, collection),
|
2026-06-06 10:33:10 -05:00
|
|
|
catch: (cause) => LoadKgCoreError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
}).pipe(
|
|
|
|
|
Effect.flatMap((value) =>
|
|
|
|
|
decodeJsonOrFail(
|
|
|
|
|
value,
|
2026-06-06 10:33:10 -05:00
|
|
|
(cause) => LoadKgCoreError.make({message: toErrorMessage(cause)}),
|
2026-06-01 16:22:25 -05:00
|
|
|
).pipe(
|
2026-06-02 00:22:04 -05:00
|
|
|
Effect.map((response) => LoadKgCoreSuccess.make({response})),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
})
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export class TrustGraphMcpHttpApi extends HttpApi.make("trustgraph-mcp")
|
|
|
|
|
.add(
|
|
|
|
|
HttpApiGroup.make("mcp", {topLevel: true}).add(
|
|
|
|
|
HttpApiEndpoint.get("mcpHealth", "/mcp/health", {
|
|
|
|
|
success: HttpApiSchema.NoContent,
|
|
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
.annotateMerge(
|
|
|
|
|
OpenApi.annotations({
|
|
|
|
|
title: "TrustGraph MCP API",
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
export const TrustGraphMcpHttpApiHandlers = HttpApiBuilder.group(
|
|
|
|
|
TrustGraphMcpHttpApi,
|
|
|
|
|
"mcp",
|
|
|
|
|
Effect.fn(function*(handlers) {
|
|
|
|
|
return handlers.handle("mcpHealth", () => Effect.void)
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export const TrustGraphMcpHttpApiRoutes = HttpApiBuilder.layer(
|
|
|
|
|
TrustGraphMcpHttpApi,
|
|
|
|
|
{
|
|
|
|
|
openapiPath: "/mcp/openapi.json",
|
|
|
|
|
},
|
|
|
|
|
).pipe(
|
|
|
|
|
Layer.provide(TrustGraphMcpHttpApiHandlers),
|
|
|
|
|
)
|
|
|
|
|
|
2026-06-02 00:22:04 -05:00
|
|
|
const makeTrustGraphMcpHttpLayerFromConfig = (
|
|
|
|
|
config: TrustGraphMcpConfigShape,
|
2026-06-01 16:22:25 -05:00
|
|
|
) => {
|
2026-06-06 11:01:17 -05:00
|
|
|
const tools = makeTrustGraphMcpToolkitLayer()
|
2026-06-01 16:22:25 -05:00
|
|
|
|
|
|
|
|
return Layer.mergeAll(
|
|
|
|
|
TrustGraphMcpHttpApiRoutes,
|
|
|
|
|
tools,
|
|
|
|
|
).pipe(
|
|
|
|
|
Layer.provide(McpServer.layerHttp({
|
|
|
|
|
name: config.name,
|
|
|
|
|
version: config.version,
|
|
|
|
|
path: config.mcpPath,
|
|
|
|
|
})),
|
2026-06-11 06:29:29 -05:00
|
|
|
Layer.provide(TrustGraphGateway.layer),
|
2026-06-01 16:22:25 -05:00
|
|
|
Layer.provide(TrustGraphSocket.layer),
|
2026-06-02 00:22:04 -05:00
|
|
|
Layer.provide(Layer.succeed(TrustGraphMcpConfig, TrustGraphMcpConfig.of(config))),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-06 11:01:17 -05:00
|
|
|
const makeTrustGraphMcpToolkitLayer = () =>
|
2026-06-02 08:59:53 -05:00
|
|
|
McpServer.toolkit(TrustGraphMcpToolkit).pipe(
|
|
|
|
|
Layer.provide(TrustGraphMcpToolkitLive),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const makeTrustGraphMcpStdioLayerFromConfig = (
|
|
|
|
|
config: TrustGraphMcpConfigShape,
|
|
|
|
|
) =>
|
2026-06-06 11:01:17 -05:00
|
|
|
makeTrustGraphMcpToolkitLayer().pipe(
|
2026-06-02 08:59:53 -05:00
|
|
|
Layer.provide(McpServer.layerStdio({
|
|
|
|
|
name: config.name,
|
|
|
|
|
version: config.version,
|
|
|
|
|
})),
|
|
|
|
|
Layer.provide(NodeStdio.layer),
|
2026-06-11 06:29:29 -05:00
|
|
|
Layer.provide(TrustGraphGateway.layer),
|
2026-06-02 08:59:53 -05:00
|
|
|
Layer.provide(TrustGraphSocket.layer),
|
|
|
|
|
Layer.provide(Layer.succeed(TrustGraphMcpConfig, TrustGraphMcpConfig.of(config))),
|
|
|
|
|
)
|
|
|
|
|
|
2026-06-01 16:22:25 -05:00
|
|
|
export const makeTrustGraphMcpHttpServerLayer = (
|
|
|
|
|
options: TrustGraphMcpOptions = {},
|
2026-06-02 00:22:04 -05:00
|
|
|
) =>
|
|
|
|
|
Layer.unwrap(
|
|
|
|
|
loadTrustGraphMcpConfig(options).pipe(
|
|
|
|
|
Effect.map((config) =>
|
|
|
|
|
HttpRouter.serve(makeTrustGraphMcpHttpLayerFromConfig(config)).pipe(
|
|
|
|
|
Layer.provide(BunHttpServer.layer({port: config.port})),
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
export const makeTrustGraphMcpHttpLayer = (
|
|
|
|
|
options: TrustGraphMcpOptions = {},
|
|
|
|
|
) =>
|
|
|
|
|
Layer.unwrap(
|
|
|
|
|
loadTrustGraphMcpConfig(options).pipe(
|
|
|
|
|
Effect.map(makeTrustGraphMcpHttpLayerFromConfig),
|
|
|
|
|
),
|
2026-06-01 16:22:25 -05:00
|
|
|
)
|
|
|
|
|
|
2026-06-02 08:59:53 -05:00
|
|
|
export const makeTrustGraphMcpStdioLayer = (
|
|
|
|
|
options: TrustGraphMcpOptions = {},
|
|
|
|
|
) =>
|
|
|
|
|
Layer.unwrap(
|
|
|
|
|
loadTrustGraphMcpConfig(options).pipe(
|
|
|
|
|
Effect.map(makeTrustGraphMcpStdioLayerFromConfig),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
|
2026-06-01 16:22:25 -05:00
|
|
|
export const runHttp = (options: TrustGraphMcpOptions = {}): void => {
|
|
|
|
|
Layer.launch(makeTrustGraphMcpHttpServerLayer(options)).pipe(BunRuntime.runMain)
|
|
|
|
|
}
|
2026-06-02 08:59:53 -05:00
|
|
|
|
|
|
|
|
export const runStdio = (options: TrustGraphMcpOptions = {}): void => {
|
|
|
|
|
Layer.launch(makeTrustGraphMcpStdioLayer(options)).pipe(NodeRuntime.runMain)
|
|
|
|
|
}
|