Skip to main content
Glama

agent-as-model

A true MCP server where the agent is the model and the API key.

mcp-name: io.github.fernandogarzaaa/agent-as-model

Install

uvx agent-as-model

One-click install for VS Code:

Install in VS Code

The deep link carries the server's real install config ({"name":"agent-as-model","command":"uvx","args":["agent-as-model"]}) URL-encoded in the vscode:mcp/install? handler, the format from the official VS Code MCP developer guide.

Host scope: sampling-capable hosts only

This server does its work through MCP sampling, so one-click install and the guides below are scoped to sampling-capable hosts: VS Code, Goose, fast-agent, and opencode. Claude Code and Cursor are excluded until they implement sampling. The manual Claude Code instructions further down stay for anyone who wants to experiment anyway.

Goose

Add to ~/.config/goose/config.yaml (or use goose configure and pick Add Extension, Command-line Extension):

extensions:
  agent-as-model:
    enabled: true
    type: stdio
    name: agent-as-model
    cmd: uvx
    args: ["agent-as-model"]
    timeout: 300

fast-agent

Add under mcp.servers in fastagent.config.yaml, then include agent-as-model in your agent's servers=[...] list:

mcp:
  servers:
    agent-as-model:
      transport: "stdio"
      command: "uvx"
      args: ["agent-as-model"]

opencode

opencode mcp add agent-as-model -- uvx agent-as-model

Or in opencode.json (project root or ~/.config/opencode/opencode.json):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "agent-as-model": {
      "type": "local",
      "command": ["uvx", "agent-as-model"]
    }
  }
}

Manual

Claude Code (kept as manual instructions; excluded from one-click until sampling is implemented):

claude mcp add agent-as-model -- uvx agent-as-model

Any client that takes MCP JSON, paste this:

{
  "mcpServers": {
    "agent-as-model": {
      "command": "uvx",
      "args": ["agent-as-model"]
    }
  }
}

Requires Python 3.10+ and a host that declares the MCP sampling capability. No API keys, ever.

From a local checkout: python -m agent_as_model. From the repo without installing: uvx --from git+https://github.com/fernandogarzaaa/agent-as-model agent-as-model.

Related MCP server: harness_to_mcp

The idea

AI products usually demand a model API key before they do anything useful. This server flips that around. The tools speak the request shapes products already use, and the intelligence comes from the agent on the other end of the MCP connection. The agent is the model. The agent is the key.

Tools

chat_complete — OpenAI chat-completions-shaped request, completion text back.

{
  "messages": [
    {"role": "system", "content": "You are terse."},
    {"role": "user", "content": "Explain MCP sampling."}
  ],
  "model": "agent-default",
  "temperature": 0.7,
  "max_tokens": 500
}

messages_create — Anthropic messages-shaped request, completion text back. system accepts a string or a list of text blocks. Message content accepts a string or a list of text blocks.

responses_create — OpenAI Responses API-shaped request, Responses API response object back. input is a string (one user message) or a list of input items {role, content}: role is user, assistant, system, or developer; content is a string or a list of text parts ({type: "input_text"|"text", input_text: "..."}). System and developer items fold into the system prompt alongside instructions, which leads. Non-text parts are rejected. max_tokens keeps the name from the other tools (the Responses API calls it max_output_tokens). output_schema, tools, tool_choice, and persona behave exactly as on the other completion tools.

The returned object is {"id": "resp_<unique>", "object": "response", "model": <the model alias passed in>, "output": [...]}. A plain-text host answer becomes a single message item with one output_text block. When the host answers by calling tools, the accompanying text (when non-empty) becomes a message item and each tool call becomes a function_call item: {"type": "function_call", "id": "fc_<call id>", "call_id": "<host tool-call id>", "name": "...", "arguments": "<JSON>"}; the host's tool-call id maps to call_id and the object id is derived from it.

generate — raw prompt string in, completion text out, same host model, no chat formatting. The thin path for callers that do not need chat shapes: the prompt is sent as a single user sampling message with no system prompt and no role translation. model, temperature, and max_tokens behave exactly as on the other tools; there are no tools, output_schema, or tool_choice parameters, because those are chat-tool features and generate is zero overhead. It does accept the optional persona contract, which is request/response validation only and adds no sampling overhead.

list_models — returns the one model this server offers: agent-default, an alias for the host agent's own model.

Structured output — the three chat-shaped completion tools accept an optional output_schema (a JSON Schema object with root type object). When given, the sampling request carries exactly one tool whose input schema is that schema, marked as the required tool choice: the host must answer by invoking the tool, so its tool-use input is the structured completion. The server validates that input against the schema and returns it as JSON text. A host answer that violates the schema fails loudly; bad output is never returned silently. The schema itself is validated up front, so a malformed schema is the caller's error, not a mid-flow surprise.

Tool-use passthrough — the three chat-shaped completion tools also accept tools, a list of tool definitions ({name, description, input_schema} with input_schema a JSON Schema object with root type object), and tool_choice (auto/required/none, default auto). The definitions are validated up front (non-empty unique names, valid object schemas) and forwarded to the host's model in the sampling request on both protocol eras. Forwarding is fenced by the host's sampling.tools capability: a host that does not advertise it gets a tool-free request instead, the degradation is logged server-side as a warning, and the call returns plain text. When the host answers by calling tools, the tool returns JSON text in this stable shape (keys sorted): {"text": "...", "tool_calls": [{"id": "...", "input": {...}, "name": "..."}]}. A plain-text host answer returns text as before. Passing both tools and output_schema is an error: output_schema is already implemented as one required tool, so combining them is contradictory.

Personas — all four completion tools (chat_complete, messages_create, responses_create, and generate) accept an optional persona ({name, input_schema, output_schema}). The server is stateless: there is no persona registry, the host supplies the persona per call, and the same validation runs on both protocol eras. Before anything is sent, the persona itself is validated (name required and non-empty; input_schema and output_schema, when given, must be valid JSON Schema objects with root type object), and the tool's request arguments are validated against input_schema when given. The validated request object is the tool's parameter set with defaults applied, minus persona itself: messages, model, temperature, max_tokens, output_schema, tools, tool_choice for chat_complete (plus system for messages_create), and prompt, model, temperature, max_tokens for generate. After the host answers, the completion text must parse as JSON validating against output_schema when given; invalid output fails loudly, naming the persona. Unlike output_schema, a persona's output_schema does not change the sampling request (no required tool is injected): the host answers in plain text and the server parses it. Passing both output_schema and persona.output_schema is an error: the two are contradictory sources of the structured-output contract.

Continuing a conversation — the server keeps no session state, so multi-turn continuations are host-owned. All four completion tools accept an optional previous_response_id, and every completion response carries a cursor you pass back to continue. The cursor is cur_ + sha256 over the canonical JSON {"model","tool","transcript"} (sorted keys, compact separators), the transcript being the conversation through the assistant turn: a tamper-evident commitment, deterministic, so you can recompute it yourself. Pass "" to start a chain. To continue, pass the accumulated history back in (including the previous assistant turn, exactly as received) with the previous turn's cursor: the server recomputes the cursor over your history and fails loud, naming expected vs received, if it does not match. A responses_create response id (resp_...) anchors a new chain instead of failing, since opaque ids commit to nothing. When previous_response_id is given, the text tools return {"completion": "<text>", "response_id": "cur_<...>"} instead of plain text; responses_create carries the cursor in its id field. Omit previous_response_id and everything behaves exactly as before. To branch from an earlier turn, truncate the history to that turn and pass its cursor. On generate (no structured history channel) a cur_ cursor fails loud rather than silently skipping verification; pass "" to mint a cursor over the current prompt and completion.

How it works

  1. A product (or agent) calls chat_complete with ordinary chat messages.

  2. The server translates them into a completion payload and asks the host to complete it. On pre-2026 connections this is a direct sampling/createMessage request. On 2026-07-28+ the server returns a multi-round-trip InputRequiredResult carrying the full payload instead of calling the sampling API, and the completion arrives on the retry round. One tool body serves both eras.

  3. The host agent generates the completion with its own model and the server returns the text. The model argument is passed to the host as a model hint only; agent-default means "your own model".

Honest caveats

  • Sampling is deprecated upstream (SEP-2577, spec 2026-07-28, earliest removal 2027-07-28). The official migration path is provider API keys. This project exists because the agent-as-model architecture is the point, not the keys. The era-portable form used here is the sanctioned way to keep it working across both spec eras.

  • The host is in charge. Sampling runs under the host's consent and policy. On pre-2026-07-28 connections a host without the sampling capability gets a clear MISSING_REQUIRED_CLIENT_CAPABILITY error, not a silent failure. The 2026-07-28+ MRTR path needs no sampling capability at all.

  • Latency is one host model call per tool call. This is a thinking endpoint, not a fast one.

  • Tool calls are passed through, never executed. The server forwards tool definitions to the host's model and returns the host's tool calls as JSON; it never runs them. Images and audio in either direction are still rejected with explicit errors, not silently dropped.

Roadmap

  • Provider-key fallback for hosts without sampling (opt-in, per-call choice stays with the user).

  • Structured output via the toolChoice-required trick (shipped: output_schema on both completion tools, server-side validation with the jsonschema package).

  • Tool-use passthrough (shipped: tools/tool_choice on both completion tools, fenced by the host's sampling.tools capability with explicit plain-text degradation, documented JSON result shape).

  • More product shapes as tools (embeddings-shaped requests cannot be sampled meaningfully; out of scope by design).

Development

python3 -m pytest tests/ -q
python3 -m ruff format . && python3 -m ruff check .

125 tests, all green: message translation unit tests plus end-to-end runs of the full MCP loop (tool call to sampled completion) against a scripted host on both the modern multi-round-trip era and the legacy direct-sampling era, including the structured-output paths (single required tool in the sampling params and MRTR payload, validation success, and loud validation failure), the tool-use passthrough paths (tools and tool_choice forwarded on both eras, capability-absent degradation to plain text with an explicit logged warning, documented JSON result shape, and the tools/output_schema conflict), the generate tool (single user message with no system prompt and no tools on both eras, param pass-through, tool listing, description), the persona paths (persona advertised on all three completion tools, request-side validation success and rejection-before-sending, response-side validation success and loud failure, malformed-persona rejection, the output_schema/persona.output_schema conflict, identical behavior on both eras), and the host-owned session cursor protocol (pinned canonical cursor computation; chain start; verified multi-turn continuation happy path on both eras with cross-era cursor agreement; tampered history failing loud naming expected vs received across edited user turn, edited assistant turn, and changed model; malformed cursor formats; the opaque resp_ id anchoring a new chain; legacy return shapes untouched when previous_response_id is omitted; responses_create id-as-cursor on the cursor path; the generate thin-path verification limit; branch-by-truncation; MRTR round-one verification before any InputRequiredResult is returned).

Available Tools

5 tools
chat_completeA

Generate a chat completion from an OpenAI chat-completions-shaped request. The completion is produced by the host agent's own model: direct MCP sampling on pre-2026-07-28 connections, an MRTR InputRequiredResult carrying the request payload on 2026-07-28+. When output_schema is given, the request carries exactly one required tool whose input schema is that schema, and the validated structured completion is returned as JSON text. When tools is given, the tool definitions are forwarded to the host's model with tool_choice, but only if the host advertised the sampling.tools capability: otherwise the tools are dropped (a warning is logged server-side) and the call degrades to a plain-text completion. When the host answers by calling tools, the returned text is JSON: {"text": "...", "tool_calls": [{"id": "...", "input": {...}, "name": "..."}]} (keys sorted). A plain-text host answer returns text as before. tools and output_schema cannot be combined. An optional persona {name, input_schema, output_schema} registers a per-call contract: the request arguments are validated against input_schema before anything is sent, and the host's completion text must parse as JSON validating against output_schema. The server is stateless and keeps no persona registry. persona.output_schema and output_schema cannot be combined. Session cursors: the server keeps no session state. To continue a conversation, pass the accumulated history back in and the previous turn's cursor as previous_response_id: '' starts a cursor chain (nothing verified), 'cur_<64 hex>' continues a verified chain (checked against the history passed back; mismatch fails loud naming expected vs received), 'resp_<32 hex>' (a responses_create response id) anchors a new chain at the passed history. When previous_response_id is given, the completion returns as JSON '{"completion": "", "response_id": "cur_<...>"}' instead of plain text; when omitted the tool returns plain text exactly as before. The cursor is 'cur_' + sha256 over canonical JSON '{"model","tool","transcript"}' (sorted keys, compact separators), the transcript being the conversation through the assistant turn, so the caller can recompute it. Re-supply previous_response_id on the MRTR retry round on 2026-07-28+ connections, like persona. No API key is used or needed: the connected agent is the model.

NameRequiredDescriptionDefault
modelNoModel alias; agent-default means the host's own model.agent-default
toolsNoOptional tool definitions to forward to the host's model. Each is {name, description, input_schema} where input_schema is a JSON Schema object with root type 'object'. Forwarded only when the host advertised the sampling.tools capability; otherwise dropped with a server-side warning and the call degrades to plain text.
personaNoOptional persona contract for this call: {name, input_schema, output_schema}. name is required and non-empty; the server is stateless and keeps no persona registry. When input_schema is given, the request arguments (messages, model, temperature, max_tokens, output_schema, tools, tool_choice, previous_response_id) are validated against it before anything is sent. When output_schema is given, the host's completion text must parse as JSON validating against it. persona.output_schema and output_schema cannot be combined.
messagesYesChat messages; system roles become the system prompt.
max_tokensNoMaximum tokens to generate.
temperatureNoSampling temperature, if the host honors it.
tool_choiceNoOptional tool-choice mode, forwarded with tools; defaults to 'auto' when tools are given.
output_schemaNoOptional JSON Schema (root type object). When given, the sampling request carries exactly one required tool with this input schema and the completion is validated against it before returning.
previous_response_idNoOptional session cursor for host-owned multi-turn continuations. The server keeps no session state: pass the accumulated history back in messages and the previous turn's cursor here. '' starts a cursor chain (nothing verified); 'cur_<64 hex>' continues a verified chain, checked against the history passed back (mismatch fails loud, naming expected vs received); 'resp_<32 hex>' (a responses_create response id) anchors a new chain at the passed history. When given, the completion returns as JSON '{"completion": "<text>", "response_id": "cur_<...>"}' instead of plain text; when omitted the tool returns plain text exactly as before.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden and does so thoroughly: it discloses that the host agent's model performs sampling, how pre-2026-07-28 and 2026-07-28+ connections differ, capability-based degradation when sampling.tools is absent, server-side warnings, statelessness, persona validation, cursor verification behavior, and exact return-shape differences.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, but it is a very long, dense block without structure, and some concepts such as statelessness and previous_response_id behavior are repeated. Most sentences earn their place given the tool's complexity, but readability and conciseness are weaker than ideal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given nine parameters, an output schema, no annotations, and 100% schema description coverage, the description is complete enough for an agent to call the tool correctly: it covers the host-model mechanism, capability fallback, incompatible parameter combinations, persona validation, cursor continuation, and return formats.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema: previous_response_id cursor formats and verification behavior, tools capability fallback, output_schema and persona interaction constraints, and conditional return formats. It does not need to redefine every simple parameter, and the added meaning justifies a score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: "Generate a chat completion from an OpenAI chat-completions-shaped request," and explains that the host agent's own model produces it. It does not compare itself to siblings such as messages_create or responses_create, so an agent cannot fully distinguish when to choose this tool from those without additional inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied by the OpenAI chat-completions shape and the detailed explanation of tools, output_schema, persona, and cursor modes. However, there is no explicit statement of when to use this tool versus siblings like messages_create, responses_create, or generate, nor are there exclusion criteria beyond parameter incompatibilities.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateA

Generate a raw text completion from a plain prompt string. The prompt is sent as a single user sampling message with no system prompt and no chat formatting: raw prompt in, completion text out, produced by the host agent's own model. Same model hint and parameters as the other completion tools, minus any chat or tool features: no tools, no output_schema, no tool_choice. It does accept the optional persona contract ({name, input_schema, output_schema}): request/response validation only, never a sampling feature, so the thin path stays zero overhead. Session cursors: the server keeps no session state. previous_response_id '' mints a cursor over the current prompt and completion, returned as JSON '{"completion": "", "response_id": "cur_<...>"}' instead of plain text; when omitted the tool returns plain text exactly as before. generate has no structured history channel (the prompt is the only input), so a 'cur_' cursor can never be verified here: passing one fails loud instead of silently skipping the check. The cursor is 'cur_' + sha256 over canonical JSON '{"model","tool","transcript"}' (sorted keys, compact separators) with the transcript [{"role": "user", "content": }, {"role": "assistant", "content": }], so the caller can recompute it. No API key is used or needed: the connected agent is the model.

NameRequiredDescriptionDefault
modelNoModel alias; agent-default means the host's own model.agent-default
promptYesThe raw prompt text to complete. No chat formatting applied.
personaNoOptional persona contract for this call: {name, input_schema, output_schema}. name is required and non-empty; the server is stateless and keeps no persona registry. When input_schema is given, the request arguments (prompt, model, temperature, max_tokens, previous_response_id) are validated against it before anything is sent. When output_schema is given, the host's completion text must parse as JSON validating against it.
max_tokensNoMaximum tokens to generate.
temperatureNoSampling temperature, if the host honors it.
previous_response_idNoOptional session cursor for host-owned continuations. '' mints a cursor over the current prompt and completion, returned as JSON '{"completion": "<text>", "response_id": "cur_<...>"}' instead of plain text; when omitted the tool returns plain text exactly as before. generate has no structured history channel, so a 'cur_' cursor can never be verified here and fails loud rather than silently skipping the check.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses statelessness ('the server keeps no session state'), the exact return shape when previous_response_id is '' versus omitted, that persona validation is request/response validation 'never a sampling feature', that 'cur_' cursors cannot be verified here and 'fail loud', and that no API key is used. That is a rich, non-obvious behavioral profile including error semantics and auth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the raw-vs-chat distinction are front-loaded, then the cursor contract, and every block is bounded. There is noticeable duplication: the previous_response_id paragraph repeats almost verbatim the schema's own parameter description, and the sha256 canonical-JSON recipe is heavier than selection or invocation needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a stateless completion tool with 6 params, an output schema and no annotations, the description supplies the missing pieces an agent would otherwise have to guess: no state is kept, how the cursor variant changes the return type, that unverifiable cursors error rather than silently pass, and that no credentials are needed. Nothing needed to call this correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, and the description genuinely adds beyond it: persona is framed as validation-only and zero-overhead on the thin path, and previous_response_id is explained in terms of what the '' value mints, the resulting JSON shape, and the fail-loud limitation specific to this tool. The model parameter's 'agent-default' meaning is reinforced. It does not add new guidance for temperature or max_tokens beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Generate a raw text completion from a plain prompt string') and defines the mechanism precisely: single user message, no system prompt, no chat formatting. It distinguishes itself from the other completion tools by feature subtraction ('no tools, no output_schema, no tool_choice'), though it never names the siblings it contrasts with, so the differentiation is real but indirect.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes clear the context where this tool applies (raw prompt in, completion out, no chat formatting), which implicitly routes chat/tool use elsewhere. However, it never explicitly names chat_complete, messages_create, or responses_create as the alternatives or states the condition that selects them. 'Same model hint and parameters as the other completion tools, minus...' gestures at siblings without giving the agent a decision rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_modelsA

List the models this server offers. There is exactly one: agent-default, an alias for the host agent's own model.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does disclose non-obvious semantics: the list is fixed at one entry and that entry is an alias for the host agent's own model. It does not discuss auth or rate limits, but for a trivial read-only lister with an output schema defining the return, that gap is minor.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no filler, with the core purpose front-loaded before the detail about the single model. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter lister with an output schema and no annotations, the description supplies everything needed: what it returns, how many entries, and the meaning of that entry. Nothing required to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. There is nothing for the description to clarify beyond that, and it correctly presents the call as argument-free.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the models this server offers') and goes further by naming the single returned value, agent-default. No sibling offers model discovery, so there is no ambiguity with chat_complete or messages_create.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is for discovering available model identifiers. There is no explicit when-to-use statement, no exclusions, and no routing to an alternative. The note that only one model exists implicitly tells the agent the call is rarely needed, which is mildly useful but not structured guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messages_createA

Generate a completion from an Anthropic messages-shaped request. The completion is produced by the host agent's own model: direct MCP sampling on pre-2026-07-28 connections, an MRTR InputRequiredResult carrying the request payload on 2026-07-28+. When output_schema is given, the request carries exactly one required tool whose input schema is that schema, and the validated structured completion is returned as JSON text. When tools is given, the tool definitions are forwarded to the host's model with tool_choice, but only if the host advertised the sampling.tools capability: otherwise the tools are dropped (a warning is logged server-side) and the call degrades to a plain-text completion. When the host answers by calling tools, the returned text is JSON: {"text": "...", "tool_calls": [{"id": "...", "input": {...}, "name": "..."}]} (keys sorted). A plain-text host answer returns text as before. tools and output_schema cannot be combined. An optional persona {name, input_schema, output_schema} registers a per-call contract: the request arguments are validated against input_schema before anything is sent, and the host's completion text must parse as JSON validating against output_schema. The server is stateless and keeps no persona registry. persona.output_schema and output_schema cannot be combined. Session cursors: the server keeps no session state. To continue a conversation, pass the accumulated history back in and the previous turn's cursor as previous_response_id: '' starts a cursor chain (nothing verified), 'cur_<64 hex>' continues a verified chain (checked against the history passed back; mismatch fails loud naming expected vs received), 'resp_<32 hex>' (a responses_create response id) anchors a new chain at the passed history. When previous_response_id is given, the completion returns as JSON '{"completion": "", "response_id": "cur_<...>"}' instead of plain text; when omitted the tool returns plain text exactly as before. The cursor is 'cur_' + sha256 over canonical JSON '{"model","tool","transcript"}' (sorted keys, compact separators), the transcript being the conversation through the assistant turn, so the caller can recompute it. Re-supply previous_response_id on the MRTR retry round on 2026-07-28+ connections, like persona. No API key is used or needed: the connected agent is the model.

NameRequiredDescriptionDefault
modelNoModel alias; agent-default means the host's own model.agent-default
toolsNoOptional tool definitions to forward to the host's model. Each is {name, description, input_schema} where input_schema is a JSON Schema object with root type 'object'. Forwarded only when the host advertised the sampling.tools capability; otherwise dropped with a server-side warning and the call degrades to plain text.
systemNoSystem prompt as text or text blocks.
personaNoOptional persona contract for this call: {name, input_schema, output_schema}. name is required and non-empty; the server is stateless and keeps no persona registry. When input_schema is given, the request arguments (messages, model, system, temperature, max_tokens, output_schema, tools, tool_choice, previous_response_id) are validated against it before anything is sent. When output_schema is given, the host's completion text must parse as JSON validating against it. persona.output_schema and output_schema cannot be combined.
messagesYesUser/assistant messages in order.
max_tokensNoMaximum tokens to generate.
temperatureNoSampling temperature, if the host honors it.
tool_choiceNoOptional tool-choice mode, forwarded with tools; defaults to 'auto' when tools are given.
output_schemaNoOptional JSON Schema (root type object). When given, the sampling request carries exactly one required tool with this input schema and the completion is validated against it before returning.
previous_response_idNoOptional session cursor for host-owned multi-turn continuations. The server keeps no session state: pass the accumulated history back in messages and the previous turn's cursor here. '' starts a cursor chain (nothing verified); 'cur_<64 hex>' continues a verified chain, checked against the history passed back (mismatch fails loud, naming expected vs received); 'resp_<32 hex>' (a responses_create response id) anchors a new chain at the passed history. When given, the completion returns as JSON '{"completion": "<text>", "response_id": "cur_<...>"}' instead of plain text; when omitted the tool returns plain text exactly as before.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly: it discloses the transport (direct MCP sampling vs MRTR InputRequiredResult on 2026-07-28+), capability-gated degradation when sampling.tools is absent (tools silently dropped with a server-side warning), statelessness (no persona or session registry), fail-loud cursor verification with expected-vs-received naming, and that no API key is required. These are exactly the non-obvious behaviors an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the body is a single unbroken wall of text covering transport, tools, persona, and cursors with no headings or grouping, making it hard to scan. The previous_response_id mechanics and return-format rule are restated in both the description and the schema, which is avoidable redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with an output schema, complex conditional modes, and no annotations, the description covers everything an agent needs: validation timing, return shape changes (JSON with completion/response_id vs plain text vs tool_calls JSON), retry-round re-supply of previous_response_id and persona, and incompatibility rules. Nothing material is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds value the schema does not: it states the mutual-exclusion constraints (tools and output_schema cannot be combined; persona.output_schema and output_schema cannot be combined) and the exact cursor derivation (sha256 over canonical JSON of model/tool/transcript) so a caller can recompute it. Some of the previous_response_id prose duplicates the schema's own description rather than extending it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Generate a completion from an Anthropic messages-shaped request', and immediately clarifies the model producing it is the host agent's own. The Anthropic-message shape is a genuine distinguishing trait, but the description never names or contrasts with the sibling tools (chat_complete, responses_create, generate), so an agent must infer which completion endpoint to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives extensive conditional guidance for modes (tools, output_schema, persona, previous_response_id) and their mutual exclusions, which helps an agent choose how to call it. However, it offers no guidance on when to choose this tool over chat_complete, responses_create, or generate; usage relative to alternatives is only implied by the 'Anthropic messages-shaped' phrasing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

responses_createA

Generate a completion from an OpenAI Responses-shaped request, returning the Responses API response object. The completion is produced by the host agent's own model: direct MCP sampling on pre-2026-07-28 connections, an MRTR InputRequiredResult carrying the request payload on 2026-07-28+. input is a string or a list of input items; each item is {role, content} with role user, assistant, system, or developer, and content a string or a list of text parts ({type: 'input_text'|'text', input_text: '...'}). A string input becomes one user message. System and developer items fold into the system prompt alongside instructions, which leads. Non-text parts are rejected. max_tokens is named for uniformity with the other tools (the Responses API calls it max_output_tokens); same meaning. When output_schema is given, the request carries exactly one required tool whose input schema is that schema, and the validated structured completion is returned as JSON text inside the output_text. When tools is given, the tool definitions are forwarded to the host's model with tool_choice, but only if the host advertised the sampling.tools capability: otherwise the tools are dropped (a warning is logged server-side) and the call degrades to a plain-text completion. When the host answers by calling tools, the output array carries the accompanying text as a message item (omitted when empty) followed by one function_call item per call: {type: 'function_call', id: 'fc_', call_id: '', name: '...', arguments: ''}; the host's tool-call id maps to call_id, the object id is derived from it. A plain-text host answer returns a single message item. tools and output_schema cannot be combined. An optional persona {name, input_schema, output_schema} registers a per-call contract: the request arguments are validated against input_schema before anything is sent, and the host's completion text must parse as JSON validating against output_schema. The server is stateless and keeps no persona registry. persona.output_schema and output_schema cannot be combined. Session cursors: the server keeps no session state. To continue a conversation, pass the accumulated history back in input and the previous turn's response id as previous_response_id: '' starts a cursor chain (nothing verified), 'cur_<64 hex>' continues a verified chain (checked against the history passed back; mismatch fails loud naming expected vs received), 'resp_<32 hex>' (a previous response id) anchors a new chain at the passed history. The response object's id field IS the cursor: when previous_response_id is given it carries the 'cur_' tamper-evident commitment, when omitted it stays the opaque 'resp_' unique id exactly as before. The cursor is 'cur_' + sha256 over canonical JSON '{"model","tool","transcript"}' (sorted keys, compact separators), the transcript being the conversation through the assistant turn, so the caller can recompute it. Re-supply previous_response_id on the MRTR retry round on 2026-07-28+ connections, like persona. No API key is used or needed: the connected agent is the model.

NameRequiredDescriptionDefault
inputYesThe Responses API input: a string, which becomes one user message, or a list of input items {role, content}. role is user, assistant, system, or developer; content is a string or a list of text parts ({type: 'input_text'|'text', input_text: '...'}). System and developer items fold into the system prompt alongside instructions. Non-text parts are rejected.
modelNoModel alias; agent-default means the host's own model.agent-default
toolsNoOptional tool definitions to forward to the host's model. Each is {name, description, input_schema} where input_schema is a JSON Schema object with root type 'object'. Forwarded only when the host advertised the sampling.tools capability; otherwise dropped with a server-side warning and the call degrades to plain text.
personaNoOptional persona contract for this call: {name, input_schema, output_schema}. name is required and non-empty; the server is stateless and keeps no persona registry. When input_schema is given, the request arguments (input, instructions, model, temperature, max_tokens, output_schema, tools, tool_choice, previous_response_id) are validated against it before anything is sent. When output_schema is given, the host's completion text must parse as JSON validating against it. persona.output_schema and output_schema cannot be combined.
max_tokensNoMaximum tokens to generate. Named max_tokens for uniformity with the other tools; the Responses API calls it max_output_tokens.
temperatureNoSampling temperature, if the host honors it.
tool_choiceNoOptional tool-choice mode, forwarded with tools; defaults to 'auto' when tools are given.
instructionsNoOptional system prompt; leads the system/developer items.
output_schemaNoOptional JSON Schema (root type object). When given, the sampling request carries exactly one required tool with this input schema and the completion is validated against it before returning.
previous_response_idNoOptional session cursor for host-owned multi-turn continuations. The server keeps no session state: pass the accumulated history back in input and the previous turn's response id here. '' starts a cursor chain (nothing verified); 'cur_<64 hex>' continues a verified chain, checked against the history passed back (mismatch fails loud, naming expected vs received); 'resp_<32 hex>' (a previous response id) anchors a new chain at the passed history. When given, the response object's id field carries the 'cur_' cursor; when omitted the id stays the opaque 'resp_' unique id exactly as before.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses the transport split (direct MCP sampling vs MRTR InputRequiredResult), silent degradation when sampling.tools is absent (tools dropped, warning logged, plain-text fallback), statelessness, no API key required, and loud-failure semantics for cursor mismatch naming expected vs received.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a dense wall of run-on sentences; critical operational constraints (tools+output_schema exclusivity, cursor formats, MRTR resupply of previous_response_id) are buried mid-paragraph rather than front-loaded. Nearly every sentence carries real information, but the lack of structure makes retrieval hard for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, stateful-looking-but-stateless sampling tool with no output schema, it covers the mechanics an agent needs: input shaping, capability gating, tool-call output item shapes, and cursor semantics. It stops short of fully describing the returned response envelope (fields besides id/output_text are only implied), leaving some reconstruction to the caller.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes beyond it with cross-parameter rules the schema cannot express: tools and output_schema cannot be combined, persona.output_schema and output_schema cannot be combined, system/developer items fold into the prompt behind instructions, and the one-required-tool mechanics of output_schema. Some of this repeats schema text (max_tokens naming rationale, string-to-user-message) rather than adding to it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Generate a completion from an OpenAI Responses-shaped request') and the exact return ('the Responses API response object'). The 'Responses-shaped' dialect naming implicitly separates it from the chat-completions and messages-shaped siblings, and the closing line 'the connected agent is the model' sharpens what kind of completion this is.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for optional features: when to pass tools (only if host advertised sampling.tools), when to use output_schema (structured completion returned inside output_text), when to use persona, and how to use previous_response_id for continuations. It never explicitly says when to prefer this over chat_complete or messages_create, so sibling routing is left to inference from the API dialect.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.2
    • Changedchat_complete7 fields changed
      • addedInput schema / $defs / Persona
        Added value: +{
        +  "description": "A host-registered persona contract for one completion call.\n\nThe server is stateless: it keeps no persona registry. The host supplies\nthe persona per call as a plain dict, and the server validates the call\nagainst it. `input_schema` constrains the tool's request arguments (see\n`_validate_persona_request` for the exact per-tool shape); `output_schema`\nconstrains the host's completion text, which must parse as JSON validating\nagainst it. Both schemas follow the same shape as `output_schema`: a JSON\nSchema object with root type \"object\".",
        +  "properties": {
        +    "input_schema": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Input Schema"
        +    },
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    },
        +    "output_schema": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Output Schema"
        +    }
        +  },
        +  "required": [
        +    "name"
        +  ],
        +  "title": "Persona",
        +  "type": "object"
        +}
      • addedInput schema / $defs / ToolDefinition
        Added value: +{
        +  "description": "One caller-defined tool to forward to the host's model.\n\nCallers pass these as plain dicts; the server validates them before they\ntravel anywhere. `input_schema` follows the MCP Tool inputSchema shape: a\nJSON Schema object with root type \"object\".",
        +  "properties": {
        +    "description": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Description"
        +    },
        +    "input_schema": {
        +      "additionalProperties": true,
        +      "title": "Input Schema",
        +      "type": "object"
        +    },
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "input_schema"
        +  ],
        +  "title": "ToolDefinition",
        +  "type": "object"
        +}
      • addedInput schema / properties / output_schema
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional JSON Schema (root type object). When given, the sampling request carries exactly one required tool with this input schema and the completion is validated against it before returning.",
        +  "title": "Output Schema"
        +}
      • addedInput schema / properties / persona
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/Persona"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional persona contract for this call: {name, input_schema, output_schema}. name is required and non-empty; the server is stateless and keeps no persona registry. When input_schema is given, the request arguments (messages, model, temperature, max_tokens, output_schema, tools, tool_choice, previous_response_id) are validated against it before anything is sent. When output_schema is given, the host's completion text must parse as JSON validating against it. persona.output_schema and output_schema cannot be combined."
        +}
      • addedInput schema / properties / previous_response_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional session cursor for host-owned multi-turn continuations. The server keeps no session state: pass the accumulated history back in messages and the previous turn's cursor here. '' starts a cursor chain (nothing verified); 'cur_<64 hex>' continues a verified chain, checked against the history passed back (mismatch fails loud, naming expected vs received); 'resp_<32 hex>' (a responses_create response id) anchors a new chain at the passed history. When given, the completion returns as JSON '{\"completion\": \"<text>\", \"response_id\": \"cur_<...>\"}' instead of plain text; when omitted the tool returns plain text exactly as before.",
        +  "title": "Previous Response Id"
        +}
      • addedInput schema / properties / tool_choice
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "auto",
        +        "required",
        +        "none"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional tool-choice mode, forwarded with tools; defaults to 'auto' when tools are given.",
        +  "title": "Tool Choice"
        +}
      • addedInput schema / properties / tools
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "$ref": "#/$defs/ToolDefinition"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional tool definitions to forward to the host's model. Each is {name, description, input_schema} where input_schema is a JSON Schema object with root type 'object'. Forwarded only when the host advertised the sampling.tools capability; otherwise dropped with a server-side warning and the call degrades to plain text.",
        +  "title": "Tools"
        +}
    • Addedgenerate
    • Changedmessages_create7 fields changed
      • addedInput schema / $defs / Persona
        Added value: +{
        +  "description": "A host-registered persona contract for one completion call.\n\nThe server is stateless: it keeps no persona registry. The host supplies\nthe persona per call as a plain dict, and the server validates the call\nagainst it. `input_schema` constrains the tool's request arguments (see\n`_validate_persona_request` for the exact per-tool shape); `output_schema`\nconstrains the host's completion text, which must parse as JSON validating\nagainst it. Both schemas follow the same shape as `output_schema`: a JSON\nSchema object with root type \"object\".",
        +  "properties": {
        +    "input_schema": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Input Schema"
        +    },
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    },
        +    "output_schema": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Output Schema"
        +    }
        +  },
        +  "required": [
        +    "name"
        +  ],
        +  "title": "Persona",
        +  "type": "object"
        +}
      • addedInput schema / $defs / ToolDefinition
        Added value: +{
        +  "description": "One caller-defined tool to forward to the host's model.\n\nCallers pass these as plain dicts; the server validates them before they\ntravel anywhere. `input_schema` follows the MCP Tool inputSchema shape: a\nJSON Schema object with root type \"object\".",
        +  "properties": {
        +    "description": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Description"
        +    },
        +    "input_schema": {
        +      "additionalProperties": true,
        +      "title": "Input Schema",
        +      "type": "object"
        +    },
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "input_schema"
        +  ],
        +  "title": "ToolDefinition",
        +  "type": "object"
        +}
      • addedInput schema / properties / output_schema
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional JSON Schema (root type object). When given, the sampling request carries exactly one required tool with this input schema and the completion is validated against it before returning.",
        +  "title": "Output Schema"
        +}
      • addedInput schema / properties / persona
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/Persona"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional persona contract for this call: {name, input_schema, output_schema}. name is required and non-empty; the server is stateless and keeps no persona registry. When input_schema is given, the request arguments (messages, model, system, temperature, max_tokens, output_schema, tools, tool_choice, previous_response_id) are validated against it before anything is sent. When output_schema is given, the host's completion text must parse as JSON validating against it. persona.output_schema and output_schema cannot be combined."
        +}
      • addedInput schema / properties / previous_response_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional session cursor for host-owned multi-turn continuations. The server keeps no session state: pass the accumulated history back in messages and the previous turn's cursor here. '' starts a cursor chain (nothing verified); 'cur_<64 hex>' continues a verified chain, checked against the history passed back (mismatch fails loud, naming expected vs received); 'resp_<32 hex>' (a responses_create response id) anchors a new chain at the passed history. When given, the completion returns as JSON '{\"completion\": \"<text>\", \"response_id\": \"cur_<...>\"}' instead of plain text; when omitted the tool returns plain text exactly as before.",
        +  "title": "Previous Response Id"
        +}
      • addedInput schema / properties / tool_choice
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "auto",
        +        "required",
        +        "none"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional tool-choice mode, forwarded with tools; defaults to 'auto' when tools are given.",
        +  "title": "Tool Choice"
        +}
      • addedInput schema / properties / tools
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "$ref": "#/$defs/ToolDefinition"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional tool definitions to forward to the host's model. Each is {name, description, input_schema} where input_schema is a JSON Schema object with root type 'object'. Forwarded only when the host advertised the sampling.tools capability; otherwise dropped with a server-side warning and the call degrades to plain text.",
        +  "title": "Tools"
        +}
    • Addedresponses_create
  2. 3 tool updatesv0.1.1
    • First observedchat_complete
    • First observedlist_models
    • First observedmessages_create

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation3/5

chat_complete, messages_create, and responses_create perform essentially the same operation—sampling the host model—and differ only in request/response schema. The long descriptions explain the shapes, but an agent must know which external API format is intended, so boundaries are inferable yet easy to confuse.

Naming Consistency3/5

All names use snake_case, but ordering is mixed: list_models and generate are verb-first, while chat_complete, messages_create, and responses_create are noun-first. 'generate' is also vaguer than the other completion tools, so the pattern is readable but not predictable.

Tool Count4/5

Five tools is a healthy, well-scoped count for a model-proxy server. The only slight issue is that three of the five are near-duplicate completion endpoints that could arguably be consolidated.

Completeness4/5

The surface covers the main completion shapes (chat, messages, responses, raw text) plus model discovery, which is solid for a model-sampling proxy. It lacks embeddings, streaming controls, and other peripheral model operations, but core completion workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers