relay/testing

Test support: an in-process client, MCP HTTP requests for a mounted handler, and verifiers with fixed answers.

connect(server, context) returns a relay/client.Client wired to the server through its own runtime: no port, no mist, the same wire messages. For other client settings, build the configuration with relay/client.in_process and connect it yourself.

request(method, params) builds the Request(BitArray) a Streamable HTTP client sends, with the protocol metadata and routing headers, for relay/http.handle; body_text reads the response. verifier and unavailable_verifier stand in for a token validator.

import json/blueprint/codec
import relay/client
import relay/server
import relay/testing
import relay/tool

pub fn say_test() {
  let input = {
    use text <- codec.field("text", codec.string(), get: fn(text) { text })
    codec.success(text)
  }
  let say = tool.define("say", input, codec.string())
  let peer = testing.connect(server.new([tool.handle(say, Ok)]), Nil)
  let assert Ok(client.Succeeded("hi", _)) = client.call(peer, say, "hi")
  client.close(peer)
}

Values

pub fn body_text(
  response: response.Response(bytes_tree.BytesTree),
) -> String

A response body as text.

pub fn connect(
  server: server.Server(context),
  context: context,
) -> client.Client

A client connected to server in this VM, with each request’s context. Panics when the runtime cannot start.

pub fn error(reason: client.Reason) -> client.Error

A client.Error with this failure, as if a call with a fresh correlation had failed, for fakes and for testing code that handles errors. Build one with a chosen correlation using client.new_error.

pub fn request(
  method: String,
  params: List(#(String, json.Json)),
) -> request.Request(BitArray)

A Streamable HTTP POST for method with these params, as an MCP client sends it: a fresh request id, the 2026-07-28 metadata, Accept for JSON and event streams, and the Mcp-Method, Mcp-Name and MCP-Protocol-Version headers. The host is 127.0.0.1. A notifications/... method is sent without an id.

pub fn unavailable_verifier() -> authorization.Verifier(principal)

A verifier that can never decide, as when the key set or the introspection endpoint is down.

pub fn verifier(
  tokens: List(#(String, authorization.Attestation(principal))),
) -> authorization.Verifier(principal)

A verifier that accepts exactly these raw tokens, each with its attestation, and rejects every other token.

✨ Search Document