Imp.MCP (Imp v0.5.0)

Copy Markdown View Source

Imports the tools of authorized MCP servers as ordinary Imp.Tool values.

connect/2 dials each server, lists its tools and returns them with their source provenance and one cleanup function. Imported tools validate required fields and basic JSON-schema-style property constraints. Tool schemas follow the MCP specification dialect: the input contract is the camelCase "inputSchema" key (MCP spec, Tool definition) and "description" is optional.

Imported tools default to result_mode: :text, matching DSPy's MCP tool boundary: one text block becomes a string, multiple text blocks become a list, and non-text blocks are returned when no text is present. Set result_mode: :structured to return structuredContent exactly when the server includes it—even when its value is nil, false, 0, or empty—and fall back to the text conversion only when that field is absent. MCP error results become {:error, {:mcp_tool_error, original_envelope}} before either conversion. The original structured failure and content remain available; uncertainty about an effect must not be collapsed into a retryable refusal. A call that got no answer from its tool returns {:error, %Imp.MCP.CallFailure{}}, whose outcome says whether it was refused, never sent, or sent with no trustworthy answer.

Summary

Functions

Connects authorized MCP servers; returns tools with source metadata and cleanup.

The words a model reads for a failed MCP tool call.

Functions

connect(servers, opts \\ [])

@spec connect([Imp.MCP.Connections.descriptor()], keyword()) ::
  {:ok, Imp.MCP.Import.t()} | {:error, term()}

Connects authorized MCP servers; returns tools with source metadata and cleanup.

servers is a list of descriptor maps, local ("command") or remote ("url"); see Imp.MCP.Connections for their shape and every option.

server = %{"name" => "files", "command" => "my-mcp-server", "args" => ["--stdio"]}
{:ok, import} = Imp.MCP.connect([server], trusted_servers: [server])
agent = Imp.react("question -> answer", import.tools, lm: lm)

failure_text(reason)

@spec failure_text(term()) :: String.t()

The words a model reads for a failed MCP tool call.

An error result ({:mcp_tool_error, envelope}) is the text its tool wrote: MCP spec, CallToolResult, puts what went wrong in the content, for the model to read. Its text items are joined; its structured content stands in as plain data when there is no text. For an Imp.MCP.CallFailure, a JSON-RPC error is the server's message, and otherwise the sentence follows its outcome: a refused call says the server refused it, a call whose credential was refused says so, a call that was not sent says so, and a call whose outcome is unknown says it got no answer, why, and that it may have been carried out, because a timeout, a closed or failed connection, a broken stream, or a server that stopped waiting for its tool does not say whether the tool ran, and a write that did run must not read as one that did not.

This is only what is read. The error term itself, which the loop records, keeps the whole envelope or reason.

iex> failure = %Imp.MCP.CallFailure{
...>   outcome: :unknown,
...>   index: 0,
...>   server_name: "kite",
...>   tool_name: "reply",
...>   reason: :timeout
...> }
iex> Imp.MCP.failure_text(failure)
"no answer came back; it timed out, so it may have been carried out."