Skip to content

MCP schema warnings: non-standard "format" values (uint32/uint64) from schemars pollute TUI #31002

Closed

Description

@Ploppy3

Problem

MCP servers that derive their JSON Schemas from Rust types via schemars emit non-standard format values like uint32, uint64, uint8, and uint. When opencode registers these tools, AJV (the JSON Schema validator) outputs warnings for each unknown format:

unknown format "uint64" ignored in schema for path "/properties/pid"
unknown format "uint32" ignored in schema for path "/properties/width"
...

These warnings cannot be suppressed — --log-level ERROR does not help because they come from AJV's console.warn() bypassing opencode's logger.

Affected MCP servers

  • computer-use-linux (schemars-derived schemas for Rust u32/u64/u8 types)
  • BigQuery MCP (previously reported in bigquery MCP connection #8581)
  • Any other MCP server built with Rust + schemars

Previous attempt

PR #12815 ("fix(mcp): strip non-standard JSON Schema formats to suppress AJV warnings") was closed without merging.

Request

Either:

  1. Strip non-standard format values before AJV validation (resurrect fix(mcp): strip non-standard JSON Schema formats to suppress AJV warnings #12815 approach)
  2. Provide a mechanism to suppress/silence schema validation warnings from MCP tool registration
  3. Both

Why upstream fixes aren't enough

While individual MCP servers can (and should) configure schemars to use SchemaSettings::draft07() to avoid emitting these formats, this is a systemic issue that will keep appearing for any Rust MCP server using default schemars config.

Activity

  1. github-actions commented on Jun 5, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. BzNdevOps commented on Jun 14, 2026

    @BzNdevOps

    Workaround (client-side Node.js proxy wrapper)

    While waiting for a fix on the OpenCode side, here's a practical workaround for anyone using a Rust-based MCP server: wrap the binary in a Node.js JSON-RPC filter that strips the non-standard format values before OpenCode's AJV sees them.

    #!/usr/bin/env node
    const { spawn } = require('child_process');
    const path = require('path');
    
    const NON_STANDARD_FORMATS = new Set(['uint8', 'int8', 'uint16', 'int16', 'uint32', 'int32', 'uint64', 'int64']);
    
    const child = spawn('/path/to/your-mcp-binary', process.argv.slice(2), {
      stdio: ['pipe', 'pipe', 'inherit'],
      env: { ...process.env }
    });
    
    process.stdin.on('data', (chunk) => child.stdin.write(chunk));
    
    let buffer = '';
    child.stdout.on('data', (chunk) => {
      buffer += chunk.toString();
      const lines = buffer.split('\n');
      buffer = lines.pop();
      for (const line of lines) {
        if (!line.trim()) continue;
        try {
          process.stdout.write(JSON.stringify(stripFormats(JSON.parse(line))) + '\n');
        } catch {
          process.stdout.write(line + '\n');
        }
      }
    });
    
    child.on('close', (code) => process.exit(code));
    
    function stripFormats(obj) {
      if (Array.isArray(obj)) return obj.map(stripFormats);
      if (obj && typeof obj === 'object') {
        const result = {};
        for (const [k, v] of Object.entries(obj)) {
          if (k === 'format' && NON_STANDARD_FORMATS.has(v)) continue;
          result[k] = stripFormats(v);
        }
        return result;
      }
      return obj;
    }

    Point your opencode.jsonc command at this script instead of the binary. The filter intercepts JSON-RPC stdout and removes all Rust integer format annotations before OpenCode validates the schema.

    Tested on tmux-mcp-rs v0.4.0 — eliminates all unknown format "uint64" warnings on startup.

    The cleanest fix would still be option 1 from the issue (strip in OpenCode's MCP tool registration layer), since this workaround has to be applied per-MCP-server.

  3. lightcloud00 commented on Aug 6, 2026

    @lightcloud00

    Reproduced on OpenCode 1.18.14 for macOS arm64 with a Rust/schemars-based MCP server. The repeated AJV console.warn() messages were written into the TUI and visually corrupted it; --log-level did not suppress them.

    A narrowly scoped local workaround now proxies only this MCP's JSON-RPC stream and recursively removes unsupported integer formats (uint, uint8/16/32/64, int8/16/32/64) only inside successful result.tools responses. It leaves non-tool messages byte-identical and preserves recognized formats.

    Acceptance evidence:

    • direct enumeration: 54 tools, 0 unsupported integer formats after normalization, 29 double formats preserved;
    • three full OpenCode MCP enumerations: exit 0, 25 servers each, affected MCP connected;
    • PTY TUI smoke: remained alive past startup, clean exit, no schema-warning flood.

    This confirms the systemic client-side normalization approach requested here works without changing the MCP implementation or disabling schema validation.

  4. Ayoola commented on Aug 18, 2026

    @Ayoola

    Client-side workaround: schema-sanitizing stdio shim (keeps the server enabled)

    For anyone hitting this with a Rust/schemars MCP server (I hit it with cua-driver), a local stdio wrapper can strip the non-standard uint32/uint64 format annotations before AJV sees them — without disabling the server, losing tools, or hiding real errors.

    Wrapper script (~/.config/opencode/cua-driver-mcp, chmod 755):

    #!/bin/zsh
    
    set -o pipefail
    
    # adjust to your cua-driver binary path
    ~/.local/bin/cua-driver mcp "$@" |
      /usr/bin/jq --unbuffered --compact-output '
        if ((.result.tools? // null) | type) == "array" then
          walk(
            if type == "object" and ((.format? == "uint32") or (.format? == "uint64")) then
              del(.format)
            else
              .
            end
          )
        else
          .
        end
      '

    Then point the mcp entry at the wrapper:

    "mcp": {
      "cua-driver": {
        "type": "local",
        "command": ["~/.config/opencode/cua-driver-mcp"],
        "enabled": true
      }
    }

    Notes:

    • Only touches tools/list responses (result.tools) and only removes format fields whose value is exactly uint32/uint64. Tool names, descriptions, parameters, required fields, calls, and results are untouched.
    • These are the same annotations AJV was already ignoring, so no validation behavior changes — it just stops the console.warn noise.
    • Verified: opencode mcp list shows the server connected with zero unknown format warnings.
    • Trade-off: adds a jq dependency on the MCP stdio path; if the wrapper ever fails, the server reports disconnected rather than misbehaving.

    Band-aid until opencode strips non-standard formats at the MCP boundary, but it keeps the full tool surface functional.

  5. arkaydeus commented on Sep 10, 2026

    @arkaydeus

    Reproduced on opencode 1.18.30 (macOS 26.6.2 arm64) with cua-driver 0.26.0 (Rust/schemars MCP server, 34 tools with outputSchema). opencode mcp list prints 81 warning lines covering 26 unique schema paths, so it reproduces outside the TUI too.

    Root cause is in the SDK's output-schema validation path, not the AI SDK jsonSchema() conversion:

    Verified fix: supply a jsonSchemaValidator through the SDK's documented ClientOptions seam, using an Ajv with the SDK's defaults plus logger: false:

    const ajv = new Ajv({ strict: false, validateFormats: true, validateSchema: false, allErrors: true, logger: false })
    addFormats(ajv)
    const CLIENT_OPTIONS = {
      // capabilities...
      jsonSchemaValidator: new AjvJsonSchemaValidator(ajv),
    } satisfies ClientOptions

    With that, warning output goes to 0, while known formats (uuid, date-time, ...) and type validation are unchanged. I can open a PR with a unit test if this approach is acceptable.

  6. vpeschenkov commented on Sep 24, 2026

    @vpeschenkov

    Confirmed on OpenCode 1.18.32 (macOS) with the Firebase MCP server enabled. On TUI startup, repeated raw unknown format "google-duration" ignored in schema at path "#/properties/versionRetentionPeriod" warnings (also #/properties/retention) are painted over the alternate-screen UI, including the input area. This is the same class of failure as the schemars uint64 case tracked here; the format differs, but Ajv is ignoring it and warning through console.warn. #48331 is still open and its logger: false validator should cover this Firebase case as well. The older Firebase-specific report #15161 was auto-closed without a fix.

  7. Ploppy3 commented on Oct 5, 2026

    @Ploppy3
    Author

    Closing as resolved for opencode v2: verified against the current v2 tip (2.0.23, fad352c) — JSON Schemas are no longer Ajv-compiled during MCP registration (input schemas are never compiled, output schemas compile lazily only when a tool is first called), and the managed server's stderr is captured, so the unknown format warnings no longer pollute the TUI. Reopen if it resurfaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions