{
  "$comment": "Tool definitions the Broker Tool MCP server exposes to Nora. Shapes match src/broker-tool-mock.js and mcp/examples/*.json.",
  "tools": [
    {
      "name": "search_spaces",
      "description": "Search active listing records the calling broker is allowed to see. Applies requirement filters, classifies each listing as exact or near, and ranks with fixed rules. Never infers missing fields.",
      "annotations": { "readOnlyHint": true, "idempotentHint": true },
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "rsf": {
            "type": "object",
            "properties": { "min": { "type": ["integer", "null"], "minimum": 0 }, "max": { "type": ["integer", "null"], "minimum": 0 }, "required": { "type": "boolean" } },
            "required": ["required"]
          },
          "full_floor": { "$ref": "#/$defs/boolCriterion" },
          "furnished": { "$ref": "#/$defs/boolCriterion" },
          "neighborhoods": {
            "type": "object",
            "description": "Ordered by preference. values[0] is the first choice. Names must come from the Broker Tool's neighborhood list.",
            "properties": { "values": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "required": { "type": "boolean" } },
            "required": ["values", "required"]
          },
          "term_months": {
            "type": "object",
            "description": "Desired term range. Met when it overlaps the listing's offered term range.",
            "properties": { "min": { "type": "integer", "minimum": 1 }, "max": { "type": "integer", "minimum": 1 }, "required": { "type": "boolean" } },
            "required": ["min", "max", "required"]
          },
          "statuses": { "type": "array", "items": { "enum": ["Active", "Pending", "Off market"] }, "default": ["Active"] },
          "include_near_matches": { "type": "boolean", "default": true },
          "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }
        },
        "$defs": {
          "boolCriterion": {
            "type": "object",
            "properties": { "value": { "type": "boolean" }, "required": { "type": "boolean" } },
            "required": ["value", "required"]
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "required": ["searched_at", "listings_scanned", "exact_matches", "near_matches"],
        "properties": {
          "searched_at": { "type": "string", "format": "date-time" },
          "listings_scanned": { "type": "integer" },
          "excluded_by_status": { "type": "integer" },
          "exact_matches": { "type": "array", "items": { "$ref": "#/$defs/result" } },
          "near_matches": { "type": "array", "items": { "$ref": "#/$defs/result" } },
          "elapsed_ms": { "type": "integer" }
        },
        "$defs": {
          "fieldState": {
            "type": "object",
            "description": "verified = confirmed in the record; unverified = reported but not confirmed; unknown = not in the record. Only verified can satisfy a requirement.",
            "properties": { "state": { "enum": ["verified", "unverified", "unknown"] }, "value": {} },
            "required": ["state", "value"]
          },
          "listing": {
            "type": "object",
            "required": ["id", "address", "neighborhood", "floor", "full_floor", "rsf", "furnished", "term_months", "availability", "status", "last_verified"],
            "properties": {
              "id": { "type": "string" }, "address": { "type": "string" }, "neighborhood": { "type": "string" },
              "floor": { "type": "integer" }, "full_floor": { "$ref": "#/$defs/fieldState" }, "rsf": { "type": "integer" },
              "furnished": { "$ref": "#/$defs/fieldState" }, "term_months": { "$ref": "#/$defs/fieldState" },
              "availability": { "type": "string" }, "status": { "type": "string" },
              "last_verified": { "type": "string", "format": "date" }, "verified_days_ago": { "type": "integer" }
            }
          },
          "check": {
            "type": "object",
            "required": ["key", "required", "result", "detail"],
            "properties": {
              "key": { "enum": ["rsf", "full_floor", "furnished", "neighborhood", "term", "fresh"] },
              "label": { "type": "string" }, "required": { "type": "boolean" }, "system": { "type": "boolean" },
              "result": { "enum": ["met", "missed", "unknown"] }, "detail": { "type": "string" }
            }
          },
          "result": {
            "type": "object",
            "required": ["listing", "match", "checks", "score"],
            "properties": {
              "listing": { "$ref": "#/$defs/listing" },
              "match": { "enum": ["exact", "near"] },
              "checks": { "type": "array", "items": { "$ref": "#/$defs/check" } },
              "score": { "type": "integer", "minimum": 0, "maximum": 100 },
              "score_parts": { "type": "array", "items": { "type": "object", "properties": { "label": { "type": "string" }, "pts": { "type": "number" }, "max": { "type": "number" } } } }
            }
          }
        }
      }
    },
    {
      "name": "get_space_details",
      "description": "Load the full listing record when a broker opens a result. Same permission check as search_spaces.",
      "annotations": { "readOnlyHint": true, "idempotentHint": true },
      "inputSchema": { "type": "object", "properties": { "id": { "type": "string" } }, "required": ["id"], "additionalProperties": false },
      "outputSchema": {
        "type": "object",
        "description": "The listing fields from search_spaces plus asking_rent_psf, building_class, ceiling_height, listing_broker and notes. Errors: not_found (missing or not visible to this broker).",
        "required": ["id", "address"]
      }
    }
  ]
}
