McpTools
Harness tools over MCP: register a conversation’s tools (or any list, such as an extension’s tools) with an
effect/ai McpServer, so an MCP client can list and call them.
import { CodingTools, type Ids, McpTools } from "@effective-harness/core"import * as McpProtocol from "effect/ai/McpProtocol"import * as McpServer from "effect/ai/McpServer"import * as Layer from "effect/Layer"
declare const conversationId: Ids.ConversationId
// Serve the root conversation's coding tools over stdio, in its environment and working directory.const Mcp = McpTools.layer({ conversationId, tools: CodingTools.CodingTools.tools }).pipe( Layer.provideMerge(McpServer.layerStdio({ name: "harness", version: "1.0.0", protocols: [McpProtocol.v2025_11_25] })))A call runs the tool’s execute directly, not as a durable pi.tool task: nothing is written to the conversation’s
transcript, the beforeTool / afterTool hooks do not run, and a crash does not replay the call. The ToolCall
service it gets builds the conversation’s environment (ExecEnvBuilder, with the agent’s cwd), commits through
the Session without task attribution, reads committed state, collects diagnostics into the result (as the harness
renders them) and ignores streamed output and details. Its taskId is 0 and conversation is not available.
Without tools, the conversation’s agent is resolved at registration for the listing and again at each call, so a
call uses the current version of a tool, and a tool the agent no longer offers answers with an error result.
Since v0.0.0
Options (interface)
Section titled “Options (interface)”What to expose.
Signature
export interface Options { /** The conversation whose environment, state and (without `tools`) agent the calls use. */ readonly conversationId: ConversationId /** Expose these tools instead of the conversation's resolved ones, for example an extension's `tools`. */ readonly tools?: ReadonlyArray<Tool.Any> | undefined}Since v0.0.0
Services (type alias)
Section titled “Services (type alias)”The services a call runs with.
Signature
type Services = Session.Session | Registry | Settings | ExecEnvBuilderSince v0.0.0
Register the tools when the layer is built, providing McpServer.McpServer.layer (shared with the transport layer
that serves it, such as McpServer.layerStdio or McpServer.layerHttp).
Signature
declare const layer: (options: Options) => Layer.Layer<never, ReadError, Services>Since v0.0.0
register
Section titled “register”Register the tools with the McpServer in context.
Signature
declare const register: (options: Options) => Effect.Effect<void, ReadError, McpServer.McpServer | Services>Since v0.0.0
toCallToolResult
Section titled “toCallToolResult”A tool’s result as an MCP CallToolResult: text and image parts in order, then the diagnostics as the harness
renders them (<harness> block).
Signature
declare const toCallToolResult: ( result: Tool.Result & { readonly diagnostics?: ReadonlyArray<ToolDiagnostic> }) => McpSchema.CallToolResultSince v0.0.0