{
  "$schema": "https://modelcontextprotocol.io/schema/2025-03-26/server-manifest.json",
  "schemaVersion": "2025-03-26",
  "name": "gstcranes",
  "displayName": "GST Cranes",
  "version": "1.1.0",
  "description": "MCP server for GST Cranes — search and retrieve used mobile and crawler crane inventory, pricing, specifications, and submit buyer inquiries or sell requests. Supports MCP Apps with ui:// resources for rich rendering.",
  "vendor": {
    "name": "GST Cranes",
    "url": "https://gstcranes.com"
  },
  "homepage": "https://gstcranes.com",
  "documentation": "https://gstcranes.com/docs",
  "license": {
    "name": "Proprietary",
    "url": "https://gstcranes.com/en/privacy-policy"
  },
  "contact": {
    "name": "GST Cranes",
    "url": "https://gstcranes.com/en/contact",
    "email": "info@gstcranes.com"
  },
  "transport": {
    "type": "http",
    "endpoint": "https://gstcranes.com/.well-known/mcp",
    "protocols": ["http", "https"]
  },
  "auth": {
    "type": "none",
    "description": "Public read-only endpoints. Write operations (inquiries, sell requests) require no authentication but are rate-limited."
  },
  "antiSpam": {
    "captcha": {
      "enabled": false,
      "description": "No CAPTCHA is used on any endpoint, including write endpoints. AI agents can submit inquiries, crane requests, and newsletter subscriptions end-to-end without rendering HTML or solving a challenge."
    },
    "honeypot": {
      "enabled": true,
      "description": "Write endpoints accept optional honeypot fields that must be empty or omitted. Non-empty honeypot values are silently discarded (HTTP 201).",
      "fields": ["website", "botField"]
    },
    "agentBypass": {
      "apiKeyHeader": "X-API-Key",
      "description": "If CAPTCHA is ever enabled in the future, AI agents can bypass it by sending a valid X-API-Key header obtained via /en/contact. This header is already accepted and ignored today so integrations can set it unconditionally."
    },
    "readEndpointsCaptchaPolicy": "Read endpoints (GET /api/v1/cranes, GET /api/v1/cranes/{id}, all /.well-known/* documents, /llms.txt, /llms-full.txt, /sitemap.xml) will never require CAPTCHA."
  },
  "capabilities": {
    "tools": {
      "listChanged": false
    },
    "resources": {
      "listChanged": false,
      "subscribe": false
    },
    "prompts": {
      "listChanged": false
    },
    "logging": {},
    "sampling": {},
    "experimental": {
      "ui": {
        "description": "MCP Apps UI support via ui:// resources. Tools reference UI templates via `ui` metadata.",
        "supported": true
      }
    }
  },
  "tools": [
    {
      "name": "search_cranes",
      "title": "Search used cranes",
      "description": "Search the used crane inventory by type, brand, capacity, year, or price range. Returns a list of matching cranes with basic specs and links. Best rendered as a card grid with price, year, brand, image and CTA to view details.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "type": { "type": "string", "enum": ["mobile", "crawler", "any"] },
          "brand": { "type": "string" },
          "minCapacity": { "type": "number", "description": "Minimum lifting capacity in tonnes" },
          "maxCapacity": { "type": "number", "description": "Maximum lifting capacity in tonnes" },
          "minYear": { "type": "integer" },
          "maxYear": { "type": "integer" },
          "maxPriceEur": { "type": "number" }
        }
      },
      "ui": {
        "title": "Inventory results",
        "description": "A grid of crane cards with image, year, brand, capacity, price and a link to the crane detail page.",
        "preferredRendering": "card-grid",
        "resource": "ui://gstcranes/inventory",
        "mimeType": "text/html+mcp-app"
      }
    },
    {
      "name": "get_crane",
      "title": "Get crane details",
      "description": "Retrieve full specifications, images, and price for a single crane by ID. Returns a single crane object suitable for a detail view with image gallery, spec table and inquiry CTA.",
      "inputSchema": {
        "type": "object",
        "required": ["id"],
        "properties": {
          "id": { "type": "string" }
        }
      },
      "ui": {
        "title": "Crane details",
        "description": "Detail page layout with image gallery, specs table (year, brand, capacity, hours, kilometers, equipment, price) and a primary CTA to submit an inquiry.",
        "preferredRendering": "detail-card",
        "resource": "ui://gstcranes/crane/{id}",
        "mimeType": "text/html+mcp-app"
      }
    },
    {
      "name": "submit_inquiry",
      "title": "Submit a buyer inquiry",
      "description": "Submit a buyer inquiry about a specific crane or a general question. Best rendered as a confirmation card after submission.",
      "inputSchema": {
        "type": "object",
        "required": ["name", "email", "message", "type"],
        "properties": {
          "name": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "company": { "type": "string" },
          "message": { "type": "string" },
          "type": { "type": "string", "enum": ["buy", "sell", "general"] },
          "craneId": { "type": "string" }
        }
      },
      "ui": {
        "title": "Inquiry confirmation",
        "description": "A compact confirmation card showing the submitted inquiry summary (name, email, crane, message) with a link to the contact page.",
        "preferredRendering": "confirmation-card",
        "resource": "ui://gstcranes/inquiry/confirmation",
        "mimeType": "text/html+mcp-app"
      }
    },
    {
      "name": "submit_crane_request",
      "title": "Request a crane not in stock",
      "description": "Submit a request for a crane that is not currently in inventory. GST Cranes will notify the requester when a matching unit arrives. Best rendered as a confirmation card with an echo of the requested filters.",
      "inputSchema": {
        "type": "object",
        "required": ["name", "email", "craneType"],
        "properties": {
          "name": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string" },
          "craneType": { "type": "string", "enum": ["mobile", "crawler", "any"] },
          "minCapacity": { "type": "number" },
          "maxCapacity": { "type": "number" },
          "minYear": { "type": "integer" },
          "maxYear": { "type": "integer" },
          "maxBudget": { "type": "number" },
          "notes": { "type": "string" }
        }
      },
      "ui": {
        "title": "Crane request confirmation",
        "description": "A confirmation card echoing the requested crane type, capacity range, year range and budget, with information on how we notify the requester.",
        "preferredRendering": "confirmation-card",
        "resource": "ui://gstcranes/crane-request/confirmation",
        "mimeType": "text/html+mcp-app"
      }
    }
  ],
  "resources": [
    {
      "uri": "ui://gstcranes/home",
      "name": "Home overview",
      "description": "Landing view for the GST Cranes MCP app: company summary, featured cranes, quick search shortcuts and links to docs/api.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/inventory",
      "name": "Inventory grid",
      "description": "Grid UI showing the current crane inventory as cards (image, year, brand, capacity, price, CTA).",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/inventory/mobile",
      "name": "Mobile cranes grid",
      "description": "Grid UI filtered to mobile (all-terrain / truck) cranes only.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/inventory/crawler",
      "name": "Crawler cranes grid",
      "description": "Grid UI filtered to lattice-boom crawler cranes only.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/crane/{id}",
      "name": "Crane detail view",
      "description": "Detail layout for a single crane identified by its ID: image gallery, specifications table, price, inquiry CTA.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/inquiry/form",
      "name": "Inquiry form",
      "description": "Form UI for submitting a buyer inquiry, optionally scoped to a specific crane.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/inquiry/confirmation",
      "name": "Inquiry confirmation",
      "description": "Confirmation card displayed after a successful inquiry submission.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/crane-request/form",
      "name": "Crane request form",
      "description": "Form UI for submitting a request for a crane not currently in inventory.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "ui://gstcranes/crane-request/confirmation",
      "name": "Crane request confirmation",
      "description": "Confirmation card displayed after a successful crane request submission.",
      "mimeType": "text/html+mcp-app"
    },
    {
      "uri": "https://gstcranes.com/.well-known/openapi.json",
      "name": "OpenAPI Specification",
      "description": "OpenAPI 3.1 specification for the GST Cranes public API.",
      "mimeType": "application/vnd.oai.openapi+json"
    },
    {
      "uri": "https://gstcranes.com/.well-known/api-catalog",
      "name": "API Catalog (RFC 9727)",
      "description": "Linkset of available API descriptions and documentation.",
      "mimeType": "application/linkset+json"
    },
    {
      "uri": "https://gstcranes.com/llms.txt",
      "name": "llms.txt",
      "description": "Plain-text site summary optimised for LLM consumption.",
      "mimeType": "text/plain"
    },
    {
      "uri": "https://gstcranes.com/llms-full.txt",
      "name": "llms-full.txt",
      "description": "Full inventory summary in markdown for LLM consumption.",
      "mimeType": "text/markdown"
    },
    {
      "uri": "https://gstcranes.com/sitemap.xml",
      "name": "Sitemap",
      "description": "XML sitemap covering all public pages.",
      "mimeType": "application/xml"
    },
    {
      "uri": "https://gstcranes.com/.well-known/security.txt",
      "name": "security.txt (RFC 9116)",
      "description": "Security researcher contact information.",
      "mimeType": "text/plain"
    }
  ],
  "rateLimits": {
    "default": {
      "bucket": "read",
      "description": "Read endpoints (list cranes, get crane, discovery documents).",
      "requestsPerMinute": 120,
      "burst": 240,
      "windowSeconds": 60
    },
    "write": {
      "bucket": "write",
      "description": "Write endpoints (submit inquiry, crane request, newsletter subscribe).",
      "requestsPerMinute": 10,
      "burst": 20,
      "windowSeconds": 60
    },
    "headers": {
      "limit": "X-RateLimit-Limit",
      "remaining": "X-RateLimit-Remaining",
      "reset": "X-RateLimit-Reset",
      "bucket": "X-RateLimit-Bucket",
      "retryAfter": "Retry-After"
    }
  },
  "errorFormat": {
    "description": "All errors are JSON: { \"error\": { \"code\": <string>, \"message\": <string>, \"details\": <object> } }",
    "codes": [
      { "code": "BAD_REQUEST", "httpStatus": 400, "description": "Malformed JSON, missing field, or invalid enum value." },
      { "code": "UNAUTHENTICATED", "httpStatus": 401, "description": "Reserved for future authenticated endpoints." },
      { "code": "FORBIDDEN", "httpStatus": 403, "description": "Reserved for future authenticated endpoints." },
      { "code": "NOT_FOUND", "httpStatus": 404, "description": "Resource with the supplied id does not exist." },
      { "code": "CONFLICT", "httpStatus": 409, "description": "Resource already exists (e.g. newsletter email)." },
      { "code": "RATE_LIMITED", "httpStatus": 429, "description": "Rate-limit exhausted. Honor Retry-After." },
      { "code": "INTERNAL", "httpStatus": 500, "description": "Unexpected server error. Safe to retry with exponential backoff." },
      { "code": "EXTERNAL_SERVICE_ERROR", "httpStatus": 502, "description": "Upstream service failure." }
    ]
  }
}
