Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, email [email protected] and we’ll put it right.

Advertise richer MCP server capabilities

What we checked

We read the capabilities your server declared in the initialize result and inspected what it actually exposes over the handshake:

How many of the core MCP primitives the server provides
Supports authenticated MCP flows.
Authenticated-flow check failed: the server doesn't advertise support for authenticated MCP flows.
Advertises advanced primitives (sampling / elicitation / roots)
Supports UI / widget rendering.
UI-support check failed: no UI / widget support is advertised.
Supports structured tool output.
Structured-output check failed: no structured tool output is advertised.
Protocol version not yet verified: we do not have a sandbox capture of the MCP handshake this version of the package performs yet.
Protocol version not yet verified: our sandbox run of this package did not complete, so we never saw its MCP handshake.

Why it matters

Capabilities are how a client learns what your server can do before it calls anything. The MCP spec defines three server primitives, tools, resources and prompts, so a server that declares just a couple of bare tools is using one of the three primitives and leaving the rest unused. One that also exposes resources, prompts, and structured tool results gives the model typed, machine-readable data it can chain into the next step instead of re-parsing prose.

Structured output is the highest-leverage of these. When a tool returns free text, the model has to guess at the shape of the answer. When it returns structured content described by an outputSchema, the client gets a predictable, typed object: fewer parsing errors, more reliable agent loops.

How to fix it

Declare the capabilities that fit your server and implement them honestly. Concretely: surface more of the core primitives where they’re useful, and have tools return structured output rather than only text. The snippets below are minimal and conceptual; check your SDK version’s docs for the exact structured output API, as it has evolved across releases.

// @modelcontextprotocol/sdk - a tool with an output schema returns
// structured content the client can consume as typed data.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

const server = new McpServer({ name: "my-server", version: "1.0.0" });

server.registerTool(
"get_weather",
{
  description: "Current weather for a city.",
  inputSchema: { city: z.string().describe("City name, e.g. 'Berlin'") },
  // Declaring an output schema is what makes the result 'structured'.
  outputSchema: { tempC: z.number(), conditions: z.string() },
},
async ({ city }) => {
  const data = { tempC: 21, conditions: "Clear" };
  return {
    content: [{ type: "text", text: JSON.stringify(data) }],
    structuredContent: data,
  };
},
);

// McpServer advertises the matching capabilities from what you register.

How we re-check

We re-read your declared capabilities and tool outputs on the next capture: a crawl for a hosted endpoint, or a fresh sandbox run of your published package. As you add primitives or return structured content, the coverage and capability signals update on the following score refresh.

Give this to your AI

Paste this into Claude Code (or any coding agent) from inside your server's repository. It states the failing signal, the outcome we re-check for, and the format the fix has to take.

Prompt
Context: this repository publishes an MCP server, either as a hosted
endpoint or as a package on a registry such as npm or PyPI.
VerifyMCP's capabilities check found a narrow
surface, which means the server uses only a slice of the three MCP
primitives (tools, resources, prompts) and its tools return free text
rather than typed, structured results.

Goal: tools with a natural typed result declare an `outputSchema` and
return matching `structuredContent`, so the next capture records structured
output, with declared capabilities matching what's implemented.

Do this:
1. Audit the registered tools; for each one whose result has an obvious
   typed shape (numbers, records, lists), add an `outputSchema` (or use an
   SDK-native typed return, e.g. a Pydantic model in FastMCP) and return
   `structuredContent` alongside the existing text `content`.
2. Consider whether resources or prompts would genuinely help this
   server; if so, implement and register them rather than leaving them
   declared but empty.
3. Re-run the `initialize` handshake and confirm the capability object
   the SDK advertises now matches what you actually implemented.

Rules:
- Never declare a capability (`resources`, `prompts`, structured output)
  the server doesn't actually implement; the check reads the real
  handshake and tool responses, not the manifest's intentions.
- Don't bolt on a prompt or resource you won't maintain purely to raise
  coverage, a focused tools-only server can be excellent as-is.
- Keep `structuredContent` consistent with the text `content` you already
  return, don't let the two drift apart.

Report back: which tools or primitives you changed, and the `initialize`
response (or an MCP inspector session) showing the advertised capabilities
match the implementation.

Reference: https://verifymcp.io/docs/remote/capabilities

Written by Stuart Blackler · Last reviewed 30 June 2026.