# MCP contract diff examples

> Four illustrative contracts analyzed by the production diff engine. No customer data or measured model behavior. Discovery does not invoke tools.

## Make an optional argument required

An existing call with only query stops validating when limit becomes required. Keep the previous default during migration.

Verdict: BREAKING.

- tool.input.required.added (BREAKING): `limit` changed from optional to required. Migration: Accept calls that omit it for at least one release, applying the previous default, then require it.

Before tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      },
      "limit": {
        "type": "integer"
      }
    },
    "required": [
      "query"
    ]
  }
}
```

After tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      },
      "limit": {
        "type": "integer"
      }
    },
    "required": [
      "query",
      "limit"
    ]
  }
}
```

[Download before snapshot](https://mcprobe.dev/examples/required-input/before.json), [after snapshot](https://mcprobe.dev/examples/required-input/after.json), [findings](https://mcprobe.dev/examples/required-input/diff.json).

## Accept another input enum value

Adding archived to the accepted input values preserves existing calls. This is the input direction; returning a new value has a different verdict.

Verdict: NON_BREAKING.

- tool.input.enum.widened (NON_BREAKING): `status` now also accepts "archived".

Before tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "status": {
        "type": "string",
        "enum": [
          "open",
          "closed"
        ]
      }
    },
    "required": [
      "status"
    ]
  }
}
```

After tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "status": {
        "type": "string",
        "enum": [
          "open",
          "closed",
          "archived"
        ]
      }
    },
    "required": [
      "status"
    ]
  }
}
```

[Download before snapshot](https://mcprobe.dev/examples/widen-input-enum/before.json), [after snapshot](https://mcprobe.dev/examples/widen-input-enum/after.json), [findings](https://mcprobe.dev/examples/widen-input-enum/diff.json).

## Return another output enum value

A caller handling only open and closed may fail when the server returns archived. The same enum expansion is breaking in the output direction.

Verdict: BREAKING.

- tool.output.enum.widened (BREAKING): `status` now also accepts "archived". Migration: Consumers switching exhaustively on this enum will not handle the new values.

Before tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      },
      "limit": {
        "type": "integer"
      }
    },
    "required": [
      "query"
    ]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "status": {
        "type": "string",
        "enum": [
          "open",
          "closed"
        ]
      }
    },
    "required": [
      "status"
    ]
  }
}
```

After tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      },
      "limit": {
        "type": "integer"
      }
    },
    "required": [
      "query"
    ]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "status": {
        "type": "string",
        "enum": [
          "open",
          "closed",
          "archived"
        ]
      }
    },
    "required": [
      "status"
    ]
  }
}
```

[Download before snapshot](https://mcprobe.dev/examples/widen-output-enum/before.json), [after snapshot](https://mcprobe.dev/examples/widen-output-enum/after.json), [findings](https://mcprobe.dev/examples/widen-output-enum/diff.json).

## Rewrite a tool description

The input schema is unchanged, but the model-visible purpose changes. The finding is a deterministic review heuristic; test tool selection with your own evaluations.

Verdict: POTENTIALLY_BREAKING.

- tool.description.changed (POTENTIALLY_BREAKING): `search` description changed. Description changed substantially. Agents may alter tool-selection behavior. Migration: The description is the primary tool-selection signal. Re-run your evaluations: a model may now pick this tool where it did not, or stop picking it where it did.

Before tool:

```json
{
  "name": "search",
  "description": "Search the issue tracker.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      },
      "limit": {
        "type": "integer"
      }
    },
    "required": [
      "query"
    ]
  }
}
```

After tool:

```json
{
  "name": "search",
  "description": "Find tickets across every connected workspace.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      },
      "limit": {
        "type": "integer"
      }
    },
    "required": [
      "query"
    ]
  }
}
```

[Download before snapshot](https://mcprobe.dev/examples/description-rewrite/before.json), [after snapshot](https://mcprobe.dev/examples/description-rewrite/after.json), [findings](https://mcprobe.dev/examples/description-rewrite/diff.json).

## Capture your own server

Create an account at https://app.mcprobe.dev/signup with email and password. Add a public MCP URL to capture a baseline, then Capture again to compare. No CLI, API key, GitHub connection or telemetry is needed for HTTP first value. Local CLI distribution requires an approved preview build. Usage queries remain pending.

[Example index](https://mcprobe.dev/examples/index.json). [Getting started](https://mcprobe.dev/docs/getting-started.md). [Rule reference](https://mcprobe.dev/docs/rules.md).
