{
  "data": {
    "tool": {
      "category": "",
      "endpoint": "https://www.ikeytz.com/mcp",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/ikeytz-website.json",
      "kind": "mcp",
      "listed": "indexed",
      "liveUrl": "https://www.anchorterminal.com/api/v1/live/ikeytz-website.json",
      "markdownUrl": "https://www.anchorterminal.com/tools/ikeytz-website.md",
      "mcpTools": {
        "check": {
          "checker": "anchor-check/1.0",
          "totalTokens": 46379,
          "counts": {
            "error": 0,
            "note": 0,
            "warn": 3
          },
          "findings": [
            {
              "rule": "TC14",
              "severity": "warn",
              "tool": "get_invoice_line_items",
              "message": "allowed values are in the description, not an enum: situationKey",
              "fix": "Move them into enum."
            },
            {
              "rule": "TC22",
              "severity": "warn",
              "tool": "get_discovery",
              "message": "the definition is about 1,543 tokens",
              "fix": "Trim the description and parameter docs, or split the tool."
            },
            {
              "rule": "TC23",
              "severity": "warn",
              "message": "47 tools, about 46,405 tokens of definitions",
              "fix": "Split the server by job, or offer a smaller default toolset (a read-only set, or a search-then-call pattern)."
            }
          ]
        },
        "checkedAt": "2026-10-04T22:23:06Z",
        "count": 47,
        "note": "answered without the initialize handshake",
        "schemaTokens": 46379,
        "status": "ok",
        "tools": [
          {
            "name": "site_overview",
            "title": "Site Overview",
            "description": "WHO/WHAT: Public brand card for Schlüsseldienst Ludwigsburg ikeytz (mobile locksmith, Landkreis Ludwigsburg, Baden-Württemberg, Germany). RETURNS structuredContent: tradeName, gewerbeName, priceRange plus envelope (ok, summary, canonicalUrl=home). USE when the user asks who ikeytz is, whether there is a shop, opening hours positioning (24/7 mobile). DOES NOT: book, quote a live price, geocode, submit forms. No walk-in — office address is not a customer counter. NEXT: get_business_identity (NAP), get_contact (phones), get_prices (fixed matrix), get_ort_datetime (day|night).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "gewerbeName": {
                  "description": "Registered business name",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "priceRange": {
                  "description": "Price-range hint for schema",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "tradeName": {
                  "description": "Public trade name",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_business_identity",
            "title": "Get Business Identity",
            "description": "WHO: Legal/trade identity and NAP for agents and citations. RETURNS: gewerbeName, legalName, tradeName, inhaber (Mahmud Reza Kashani, Einzelunternehmer), street/postal/city/country, mobile/landline/fax/email, website, walkIn=false. canonicalUrl = /impressum. USE for impressum-grade facts, schema.org LocalBusiness fields, 'who owns ikeytz'. DOES NOT: prove licenses beyond what the site states; does not accept updates. walkIn is always false — do not send customers to the office. NEXT: get_legal(doc=impressum), get_contact, get_geo_office.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "city": {
                  "description": "City",
                  "type": "string"
                },
                "country": {
                  "description": "Country",
                  "type": "string"
                },
                "email": {
                  "description": "Public email",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fax": {
                  "description": "Fax display number",
                  "type": "string"
                },
                "gewerbeName": {
                  "description": "Registered business name",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "inhaber": {
                  "description": "Owner full name",
                  "type": "string"
                },
                "landline": {
                  "description": "Landline display number",
                  "type": "string"
                },
                "legalName": {
                  "description": "Legal name",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "mobile": {
                  "description": "Mobile display number",
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "postal": {
                  "description": "Postal code",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "street": {
                  "description": "Office street (no walk-in)",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "tradeName": {
                  "description": "Trade / SEO name",
                  "type": "string"
                },
                "walkIn": {
                  "description": "Always false — no shop walk-in",
                  "type": "boolean"
                },
                "website": {
                  "description": "Canonical website URL",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_nav",
            "title": "List Nav",
            "description": "WHAT: Curated main-header hubs (not a 1:1 dump of every \u003ca\u003e in the header). RETURNS items[]: Start, Notfall, Leistungen, Auswahl, Preise, Einsatzgebiet, Wissen, Ratgeber, FAQ, Kontakt — each path + locale URL + label. DOES NOT include /it, /mcp-hub, /links, locale switcher, or DevSecOps. USE to pick a hub URL. NEXT: get_ai_page(path) or get_page_summary(path) for body text.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "items": {
                  "description": "Header hub links",
                  "items": {
                    "additionalProperties": true,
                    "description": "One internal www.ikeytz.com link.",
                    "properties": {
                      "label": {
                        "description": "Short human label (German hub name) when the tool provides one.",
                        "type": "string"
                      },
                      "path": {
                        "description": "ASCII site path beginning with /, no host, no locale prefix for de.",
                        "type": "string"
                      },
                      "url": {
                        "description": "Absolute https://www.ikeytz.com{prefix}{path} for the requested locale.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_footer",
            "title": "List Footer",
            "description": "WHAT: Curated internal footer paths including legal + /it + /mcp-hub + /angebot + /ankuendigungen. RETURNS items[] {path,url}. Not a pixel-perfect HTML scrape; external directory URLs live on get_links / MCP_PUBLIC_LINKS via get_mcp_hub. USE to discover legal slugs before get_legal. NEXT: get_legal(doc), get_it, get_mcp_hub.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "items": {
                  "description": "Internal footer paths",
                  "items": {
                    "additionalProperties": true,
                    "description": "One internal www.ikeytz.com link.",
                    "properties": {
                      "label": {
                        "description": "Short human label (German hub name) when the tool provides one.",
                        "type": "string"
                      },
                      "path": {
                        "description": "ASCII site path beginning with /, no host, no locale prefix for de.",
                        "type": "string"
                      },
                      "url": {
                        "description": "Absolute https://www.ikeytz.com{prefix}{path} for the requested locale.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_locales",
            "title": "List Locales",
            "description": "WHAT: The seven public HTML locales. RETURNS locales[] {id, name, prefix}. prefix is '' for de and '/en' '/fr' '/ru' '/fa' '/ar' '/tr' for others. Host is always www.ikeytz.com (apex redirects). maps.ikeytz.com has NO locales (/en/pattonville = 404). USE before resolve_locale_url. Call with {}.",
            "inputSchema": {
              "additionalProperties": false,
              "description": "This tool takes no arguments. Call tools/call with arguments: {}. Extra keys are ignored. Result is always the same public href (tel/mailto) or locale list.",
              "properties": {},
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "locales": {
                  "description": "Seven locales with URL prefix",
                  "items": {
                    "properties": {
                      "id": {
                        "description": "Locale code",
                        "type": "string"
                      },
                      "name": {
                        "description": "Native language name",
                        "type": "string"
                      },
                      "prefix": {
                        "description": "URL prefix; empty for de",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": "array"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "resolve_locale_url",
            "title": "Resolve Locale Url",
            "description": "WHAT: Rewrite one marketing path into another locale without fetching HTML. Example: path=/preise locale=en → canonicalUrl https://www.ikeytz.com/en/preise. Accepts a path or a full https://www.ikeytz.com/… URL; strips an existing /en|/fr|… prefix first. RETURNS path (no locale prefix), fromLocale, toLocale. DOES NOT translate body text. Invalid locale still required by schema — use list_locales. NEXT: get_ai_page({path, locale: toLocale}).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "description": "Required. Target locale for the rewritten URL.",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "path": {
                  "description": "Required. Site path starting with / (e.g. /preise, /en/preise, /schluesseldienst-ludwigsburg-pattonville) OR a full https://www.ikeytz.com/… URL. Host other than www is not normalized here.",
                  "type": "string"
                }
              },
              "required": [
                "path",
                "locale"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fromLocale": {
                  "description": "Locale parsed from input path",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Path without locale prefix",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "toLocale": {
                  "description": "Requested target locale",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_prices",
            "title": "Get Prices",
            "description": "WHAT: Official Festpreis matrix + composition SYSTEM. Read composition first: exactly 10 end-invoices + one 49 € add-on (not 12, not 17 customer invoices). 49 € is cylinder_mount after an opening — already inside 148/198/178/228; never add 49 again. 49 € is NOT night/weekend/holiday (those are 149/179/198/228/119). RETURNS composition{ruleDe,doNotConfuse[],factors[],routes[],endInvoices[] with contactOption,howTo[]}, opening[], packages[], surcharges[], note. USE to understand how to assemble a price. DOES NOT compute one customer total — that is get_invoice_line_items(situationKey, whenKey). Contact: compose_whatsapp/compose_mailto with contactOption. whenKey: get_ort_datetime. No VAT (§ 19).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "composition": {
                  "description": "How to assemble: 10 end-invoices, factors, question routes, formulas. Required reading before quoting €.",
                  "type": "object"
                },
                "cylinderAfterOpening": {
                  "description": "Cylinder price after an opening",
                  "type": "object"
                },
                "cylinderOnly": {
                  "description": "Cylinder-only prices",
                  "type": "object"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "note": {
                  "description": "Legal/price note",
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "opening": {
                  "description": "Door-opening price blocks",
                  "type": "array"
                },
                "packages": {
                  "description": "Invoice packages (day/night)",
                  "type": "array"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "surcharges": {
                  "description": "Surcharge rows",
                  "type": "array"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_ort_datetime",
            "title": "Get Ort Datetime",
            "description": "WHAT: Europe/Berlin wall clock to the second + whenKey for prices. THIS www tool does NOT look up a place (no slug/plz). maps.ikeytz.com has a different geo clock tool. RULE: whenKey=day only Mo–Fr 08:00:00–17:59:59 Berlin and not a Baden-Württemberg statutory holiday; otherwise night (Sa, So, holiday, or 18:00–07:59). RETURNS ok, stand ('YYYY-MM-DD HH:MM:SS CEST|CET'), iso, unix, date, time, tz, timezone=Europe/Berlin, weekday, weekdayIso (1=Mon), whenKey, holiday (bool), holidayName (or null), rule, invoiceTool=get_invoice_line_items, pricesTool=get_prices. USE before invoicing. NEXT: get_invoice_line_items({situationKey, whenKey: 'now'}) or pass whenKey day|night.",
            "inputSchema": {
              "properties": {
                "at": {
                  "description": "Optional clock. Formats: ISO-8601 with Z or ±HH:MM; or YYYY-MM-DD; or YYYY-MM-DDTHH:MM[:SS] interpreted as Europe/Berlin if no offset; or unix seconds/ms number-as-string. Omit = now. Invalid → ok=false error=bad_datetime.",
                  "type": "string"
                },
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "date": {
                  "description": "YYYY-MM-DD in Berlin.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "holiday": {
                  "description": "true if date is a BW statutory holiday.",
                  "type": "boolean"
                },
                "holidayName": {
                  "description": "German holiday name or null. Holidays force whenKey=night.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "invoiceTool": {
                  "const": "get_invoice_line_items",
                  "type": "string"
                },
                "iso": {
                  "description": "ISO-8601 with Berlin offset.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "pricesTool": {
                  "const": "get_prices",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "rule": {
                  "description": "Human rule string for day vs night.",
                  "type": "string"
                },
                "stand": {
                  "description": "Human clock 'YYYY-MM-DD HH:MM:SS CEST|CET' Europe/Berlin.",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "time": {
                  "description": "HH:MM:SS in Berlin (24h).",
                  "type": "string"
                },
                "timezone": {
                  "const": "Europe/Berlin",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "tz": {
                  "description": "Abbreviation.",
                  "enum": [
                    "CET",
                    "CEST"
                  ],
                  "type": "string"
                },
                "unix": {
                  "description": "Unix timestamp seconds.",
                  "type": "number"
                },
                "weekday": {
                  "description": "en-GB short weekday (Mon…Sun).",
                  "type": "string"
                },
                "weekdayIso": {
                  "description": "ISO weekday 1=Monday … 7=Sunday.",
                  "type": "number"
                },
                "whenKey": {
                  "description": "Price bucket. Pass to get_invoice_line_items.whenKey or use whenKey=now there.",
                  "enum": [
                    "day",
                    "night"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_invoice_line_items",
            "title": "Get Invoice Line Items",
            "description": "WHAT: Computes ONE of the 10 end-invoices (or the 49 € mount add-on). NOT a booking, NOT a PDF. FIRST classify via get_prices.composition.routes: locked_out+slam+no cylinder → opening_slam; locked_out+locked+no cylinder → opening_locked; +cylinder same trip → pkg_key_slam / pkg_key_locked; door open → cylinder_only; mount after paid opening → cylinder_mount (not an end-invoice). THEN whenKey from get_ort_datetime (day|night|now). Night/WE/holiday is NOT +49 — 49 is only cylinder_mount. Do not invent euro. Do not add 49 on top of pkg_key_*. REQUIRED situationKey. Aliases: zugefallen→opening_slam, abgeschlossen→opening_locked, schluessel_weg_zugefallen→pkg_key_slam. breakdown=true splits combo into opening+49, totalEur unchanged. RETURNS totalEur + composition + contactOption. NEXT: compose_whatsapp or compose_mailto with that contactOption. No VAT.",
            "inputSchema": {
              "properties": {
                "at": {
                  "description": "Optional. Same formats as get_ort_datetime.at. Only used when whenKey is now or omitted.",
                  "type": "string"
                },
                "breakdown": {
                  "default": false,
                  "description": "If true, pkg_key_slam / pkg_key_locked emit two rows (opening + cylinder_mount_same_trip) instead of one package row. Total euro unchanged.",
                  "type": "boolean"
                },
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "situationKey": {
                  "description": "Required. From composition.routes: opening_slam | opening_locked | pkg_key_slam | pkg_key_locked | cylinder_only | cylinder_mount. Aliases: zugefallen, abgeschlossen, schluessel_weg_zugefallen. pkg_slam_only = opening_slam same euro.",
                  "type": "string"
                },
                "whenKey": {
                  "description": "day = Mo–Fr 08:00:00–17:59:59 Europe/Berlin except BW holidays. night = weekend, holiday, or 18:00–07:59. now or omit = live get_ort_datetime (or at=). Night is not +49 (49 is only cylinder_mount). Do not invent dusk/dawn.",
                  "enum": [
                    "day",
                    "night",
                    "now"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "situationKey"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "composition": {
                  "description": "Same SYSTEM as get_prices.composition — factors, routes, 10 invoices.",
                  "type": "object"
                },
                "contactOption": {
                  "description": "Prefab id for compose_whatsapp / compose_mailto (opening_slam_day … cylinder_only_night, or cylinder_mount).",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "line_items": {
                  "description": "Invoice rows",
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "situationKey": {
                  "description": "Resolved situation id",
                  "type": "string"
                },
                "situationLabelDe": {
                  "description": "German situation label",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalEur": {
                  "description": "End-invoice euro. Do not add VAT or extra 49.",
                  "type": "number"
                },
                "whenKey": {
                  "description": "Resolved day|night",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_services",
            "title": "List Services",
            "description": "WHAT: Core service list from SITE.services (Türöffnung, Notdienst, Sicherheitstechnik, Schlosswechsel, …) with locale /leistungen#anchor URLs. USE as a menu. For situations (zugefallen, Schlüssel weg) use list_auswahl / get_auswahl_item. For euro amounts use get_prices.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "services": {
                  "description": "Core services with locale URLs",
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_emergency",
            "title": "Get Emergency",
            "description": "WHAT: Returns the 24h Notfall-Türöffnung page pointer (summary includes mobile; canonicalUrl = /notfall-tueroeffnung, locale-prefixed). USE when the user needs emergency door-opening contact on www. Prefer get_contact for general NAP; prefer compose_tel_mobile to dial. DOES NOT dispatch a technician or take a booking. NEXT: list_whatsapp_options then compose_whatsapp with a contactOption when chat is better.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_auswahl",
            "title": "List Auswahl",
            "description": "WHAT: Auswahl hub groups (situation chooser on /auswahl). RETURNS groups[] {id, hash, hubUrl, slugs[], urls[]}. USE to discover valid slugs for get_auswahl_item. Unknown slug → get_auswahl_item ok=false unknown_auswahl.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "groups": {
                  "description": "Auswahl groups with slugs and URLs",
                  "type": "array"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_auswahl_item",
            "title": "Get Auswahl Item",
            "description": "WHAT: One Auswahl situation page. REQUIRED slug from list_auswahl. RETURNS slug + canonicalUrl /auswahl/{slug}. USE after the user described a lockout/key situation. NEXT: get_ai_page({path:'/auswahl/'+slug}) for fulltext; get_invoice_line_items for euro.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "slug": {
                  "description": "Required. ASCII slug from list_auswahl groups[].slugs, e.g. tuer-zugefallen, tuer-abgeschlossen, schluessel-verloren, schluessel-gestohlen, notdienst-oeffnung-zylinder. Not an Ort slug.",
                  "type": "string"
                }
              },
              "required": [
                "slug"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "slug": {
                  "description": "Resolved Auswahl slug",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_service_areas",
            "title": "List Service Areas",
            "description": "WHAT: All 52 service-area places (orte SSOT). Each item: slug, name, plz, lat, lng, google_maps, icbm, kind, parent, url (www keyword page), embed_map (https://maps.ikeytz.com/{slug}), geo_api, maps_mcp. related includes maps llms.txt. count=52. USE to pick a slug before get_service_area. DOES NOT verify GPS live. www sitemap contains 0× maps.ikeytz.com. iframe on HTML is DE Ortsseiten only. NEXT: get_service_area({slug}) or maps MCP find_by_geo (not this server).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "count": {
                  "description": "Always 52 when ok.",
                  "type": "number"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "items": {
                  "description": "One object per place; fields = PLACE geo + maps URLs.",
                  "items": {
                    "additionalProperties": true,
                    "properties": {
                      "embed_map": {
                        "description": "iframe/src and maps page: https://maps.ikeytz.com/{slug} (German host, no /en/).",
                        "format": "uri",
                        "type": "string"
                      },
                      "geo_api": {
                        "description": "https://maps.ikeytz.com/api/v1/embed/ort/{slug} JSON for the embed.",
                        "format": "uri",
                        "type": "string"
                      },
                      "google_maps": {
                        "description": "Paste-ready 'lat, lng' for Google Maps search (same digits as lat/lng).",
                        "type": "string"
                      },
                      "icbm": {
                        "description": "ICBM 'lat, lng' string (same as google_maps).",
                        "type": "string"
                      },
                      "kind": {
                        "description": "Place kind from orte SSOT (stadtteil / gemeinde / …).",
                        "type": "string"
                      },
                      "lat": {
                        "description": "WGS84 latitude of THIS place or the office. Unique per slug — never a silent Pattonville fallback. Example Pattonville ≈ 48.863.",
                        "type": "number"
                      },
                      "lng": {
                        "description": "WGS84 longitude of THIS place or the office. Example Pattonville ≈ 9.185.",
                        "type": "number"
                      },
                      "maps_mcp": {
                        "const": "https://maps.ikeytz.com/mcp",
                        "description": "maps machine MCP endpoint. www /mcp does not proxy this.",
                        "format": "uri",
                        "type": "string"
                      },
                      "name": {
                        "description": "German place name as on the website.",
                        "type": "string"
                      },
                      "parent": {
                        "description": "Parent place name when this is a district; else empty/omit.",
                        "type": "string"
                      },
                      "plz": {
                        "description": "German postcode. First match wins if several places share a PLZ (e.g. 71638 → pattonville).",
                        "type": "string"
                      },
                      "slug": {
                        "description": "URL slug of a service-area place, e.g. pattonville, bietigheim-bissingen, walheim. Matches maps.ikeytz.com/{slug} and www /schluesseldienst-ludwigsburg-{slug}.",
                        "type": "string"
                      },
                      "url": {
                        "description": "www keyword page https://www.ikeytz.com[/locale]/schluesseldienst-ludwigsburg-{slug}",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_service_area",
            "title": "Get Service Area",
            "description": "WHAT: One service-area place. Lookup order: slug (exact getOrt), else first ORTE with plz === args.plz, else first name substring (lowercase). No silent Pattonville fallback — unknown → ok=false error=unknown_place hint=/einsatzgebiet. RETURNS that place's own lat/lng (52 unique pairs), google_maps, icbm, embed_map, geo_api, maps_mcp, kind, parent. USE when the user names a town or PLZ. NOT verify_zip_code / verify_coordinates (those names do not exist). maps MCP is a second machine. NEXT: get_ai_page path=/schluesseldienst-ludwigsburg-{slug}.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "name": {
                  "description": "German name substring, case-insensitive (e.g. 'Vaihingen'). First includes() match. Prefer slug.",
                  "type": "string"
                },
                "plz": {
                  "description": "5-digit German PLZ. First matching place wins (71638 → pattonville). Use slug if you already know it.",
                  "type": "string"
                },
                "slug": {
                  "description": "Preferred. Exact orte slug: pattonville, asperg, bietigheim-bissingen, kornwestheim, … (52). Not 'ludwigsburg' as a catch-all unless that slug exists.",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "embed_map": {
                  "description": "iframe/src and maps page: https://maps.ikeytz.com/{slug} (German host, no /en/).",
                  "format": "uri",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "geo_api": {
                  "description": "https://maps.ikeytz.com/api/v1/embed/ort/{slug} JSON for the embed.",
                  "format": "uri",
                  "type": "string"
                },
                "google_maps": {
                  "description": "Paste-ready 'lat, lng' for Google Maps search (same digits as lat/lng).",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "icbm": {
                  "description": "ICBM 'lat, lng' string (same as google_maps).",
                  "type": "string"
                },
                "kind": {
                  "description": "Place kind from orte SSOT (stadtteil / gemeinde / …).",
                  "type": "string"
                },
                "lat": {
                  "description": "WGS84 latitude of THIS place or the office. Unique per slug — never a silent Pattonville fallback. Example Pattonville ≈ 48.863.",
                  "type": "number"
                },
                "lng": {
                  "description": "WGS84 longitude of THIS place or the office. Example Pattonville ≈ 9.185.",
                  "type": "number"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "maps_mcp": {
                  "const": "https://maps.ikeytz.com/mcp",
                  "description": "maps machine MCP endpoint. www /mcp does not proxy this.",
                  "format": "uri",
                  "type": "string"
                },
                "name": {
                  "description": "German place name as on the website.",
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "parent": {
                  "description": "Parent place name when this is a district; else empty/omit.",
                  "type": "string"
                },
                "plz": {
                  "description": "German postcode. First match wins if several places share a PLZ (e.g. 71638 → pattonville).",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "slug": {
                  "description": "URL slug of a service-area place, e.g. pattonville, bietigheim-bissingen, walheim. Matches maps.ikeytz.com/{slug} and www /schluesseldienst-ludwigsburg-{slug}.",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "url": {
                  "description": "www keyword page https://www.ikeytz.com[/locale]/schluesseldienst-ludwigsburg-{slug}",
                  "format": "uri",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_geo_office",
            "title": "Get Geo Office",
            "description": "WHAT: Firmensitz / registered office once (SITE.geo = Adalbert-Stifter-Str. 14, 71638 Ludwigsburg). RETURNS: street, postal, city, lat/lng, icbm, walkIn=false, firmensitz_url=https://maps.ikeytz.com/buero, embed_map=same, embed_map_compact=?embed=1, geo_api=/api/v1/embed/office, google_business=GBP share (external click only). canonicalUrl = firmensitz map. NOT a shop — never send customers to walk in. NOT a service-area place map (use list_service_areas / get_service_area for Ort slugs). NEXT: get_contact, get_legal(doc=impressum), or maps MCP get_geo_office on maps.ikeytz.com/mcp.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "city": {
                  "description": "Office city (Ludwigsburg).",
                  "type": "string"
                },
                "embed_map": {
                  "description": "Same as firmensitz_url (iframe-capable page).",
                  "format": "uri",
                  "type": "string"
                },
                "embed_map_compact": {
                  "description": "https://maps.ikeytz.com/buero?embed=1 — map-only embed.",
                  "format": "uri",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "firmensitz_url": {
                  "description": "https://maps.ikeytz.com/buero — Firmensitz map (not an Ort slug).",
                  "format": "uri",
                  "type": "string"
                },
                "geo_api": {
                  "description": "https://maps.ikeytz.com/api/v1/embed/office JSON.",
                  "format": "uri",
                  "type": "string"
                },
                "google_business": {
                  "description": "Google Business Profile share link (external).",
                  "format": "uri",
                  "type": "string"
                },
                "google_maps": {
                  "description": "Paste-ready 'lat, lng' for Google Maps search (same digits as lat/lng).",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "icbm": {
                  "description": "ICBM 'lat, lng' string (same as google_maps).",
                  "type": "string"
                },
                "lat": {
                  "description": "WGS84 latitude of THIS place or the office. Unique per slug — never a silent Pattonville fallback. Example Pattonville ≈ 48.863.",
                  "type": "number"
                },
                "lng": {
                  "description": "WGS84 longitude of THIS place or the office. Example Pattonville ≈ 9.185.",
                  "type": "number"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "maps_mcp": {
                  "const": "https://maps.ikeytz.com/mcp",
                  "description": "maps machine MCP endpoint.",
                  "format": "uri",
                  "type": "string"
                },
                "note": {
                  "description": "Büro · kein Walk-in · nicht Einsatzgebiet.",
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "postal": {
                  "description": "Office PLZ.",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "street": {
                  "description": "Office street line.",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "walkIn": {
                  "const": false,
                  "description": "Always false.",
                  "type": "boolean"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_contact",
            "title": "Get Contact",
            "description": "WHAT: Public phones, fax, email, office address object. DOES NOT submit the website contact form and must not claim it did. USE to give the user a number. NEXT: compose_tel_mobile, compose_tel_landline, compose_mailto, compose_whatsapp, list_whatsapp_options.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "address": {
                  "additionalProperties": true,
                  "description": "Office postal address (no walk-in).",
                  "type": "object"
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "email": {
                  "description": "Public info@ email.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fax": {
                  "description": "Fax display.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "landline": {
                  "description": "Landline display (Festnetz).",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "mobile": {
                  "description": "Mobile display (Handy), 24/7.",
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_legal",
            "title": "Get Legal",
            "description": "WHAT: Pointer to one legal HTML page. REQUIRED doc enum. Unknown doc → ok=false unknown_doc hint=/impressum. RETURNS doc + canonicalUrl. For full text call get_ai_page({path:'/'+doc}) or get_discovery(which=llms-urheberrecht) for the copyright corpus. German legal text is binding; /llms-copyright.txt is EN courtesy.",
            "inputSchema": {
              "properties": {
                "doc": {
                  "description": "Required legal slug = path /{doc}. impressum=imprint, datenschutz=privacy, agb=T\u0026Cs, nutzungsbedingungen=site terms, widerruf=withdrawal, urheberrecht=copyright/AI policy.",
                  "enum": [
                    "impressum",
                    "datenschutz",
                    "agb",
                    "nutzungsbedingungen",
                    "widerruf",
                    "urheberrecht"
                  ],
                  "type": "string"
                },
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "doc"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "doc": {
                  "description": "Legal document id",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_about",
            "title": "Get About",
            "description": "WHAT: Pointer to /ueber-uns (about, owner). For NAP facts prefer get_business_identity. NEXT: get_ai_page({path:'/ueber-uns'}).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_partner_info",
            "title": "Get Partner Info",
            "description": "WHAT: Partner-werden page facts. USE when the user asks about becoming a partner / Partner-werden (not general contact — that is get_contact). RETURNS partnerEmail for mailto; formSubmit=false — never claim the form was sent. DOES NOT submit the partner form. NEXT: compose_mailto with partnerEmail, or open /partner-werden.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_links",
            "title": "Get Links",
            "description": "WHAT: Pointer to /links — local directories, city sites, HWK, Webmail shortcut. USE for human directory/backlink list. Prefer get_mcp_hub (or get_it) for MCP machine catalogs (npm, official registry, Glama, Smithery, mcpbeat) — those are publicLinks, not this page. DOES NOT list MCP tools. NEXT: get_mcp_hub for discovery URLs; open /links for the HTML list.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_it",
            "title": "Get It",
            "description": "WHAT: HTML page /it — two MCP machines documented. RETURNS website={name:com.ikeytz/website,mcp,card,npm,cli,readme=npm CLI,httpReadme=www /mcp-readme.md}, maps={name:com.ikeytz/maps,… no httpReadme}, proxy=false, page=/it, itEmail, aiEmail. USE to tell an agent there are TWO endpoints (www vs maps). www /mcp never calls maps /mcp. HTML path /it is not Italian. Hub HTML is /mcp-hub (get_mcp_hub). CLI npm is a third channel, not this HTTP server.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "aiEmail": {
                  "description": "Public AI/abuse mailbox.",
                  "type": "string"
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "itEmail": {
                  "description": "Public IT contact mailbox.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "maps": {
                  "description": "maps machine com.ikeytz/maps",
                  "properties": {
                    "card": {
                      "description": "https://…/.well-known/mcp/server-card.json",
                      "format": "uri",
                      "type": "string"
                    },
                    "cli": {
                      "description": "CLI binary name, e.g. ikeytz-mcp",
                      "type": "string"
                    },
                    "httpReadme": {
                      "description": "HTTP MCP README on the machine host (www: /mcp-readme.md). Not the npm CLI README. Maps has no www copy.",
                      "format": "uri",
                      "type": "string"
                    },
                    "mcp": {
                      "description": "HTTPS MCP endpoint …/mcp",
                      "format": "uri",
                      "type": "string"
                    },
                    "name": {
                      "description": "MCP server name: com.ikeytz/website or com.ikeytz/maps",
                      "type": "string"
                    },
                    "npm": {
                      "description": "npm package name, e.g. @ikeytz/mcp — CLI only, not this HTTP server",
                      "type": "string"
                    },
                    "readme": {
                      "description": "CLI README on npm — not the HTTP MCP README",
                      "format": "uri",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "page": {
                  "description": "Locale /it URL.",
                  "format": "uri",
                  "type": "string"
                },
                "proxy": {
                  "const": false,
                  "description": "www does not proxy maps.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "website": {
                  "description": "www machine com.ikeytz/website",
                  "properties": {
                    "card": {
                      "description": "https://…/.well-known/mcp/server-card.json",
                      "format": "uri",
                      "type": "string"
                    },
                    "cli": {
                      "description": "CLI binary name, e.g. ikeytz-mcp",
                      "type": "string"
                    },
                    "httpReadme": {
                      "description": "HTTP MCP README on the machine host (www: /mcp-readme.md). Not the npm CLI README. Maps has no www copy.",
                      "format": "uri",
                      "type": "string"
                    },
                    "mcp": {
                      "description": "HTTPS MCP endpoint …/mcp",
                      "format": "uri",
                      "type": "string"
                    },
                    "name": {
                      "description": "MCP server name: com.ikeytz/website or com.ikeytz/maps",
                      "type": "string"
                    },
                    "npm": {
                      "description": "npm package name, e.g. @ikeytz/mcp — CLI only, not this HTTP server",
                      "type": "string"
                    },
                    "readme": {
                      "description": "CLI README on npm — not the HTTP MCP README",
                      "format": "uri",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_mcp_hub",
            "title": "Get Mcp Hub",
            "description": "WHAT: HTML hub /mcp-hub ×7 (de has no prefix). NOT Italian, NOT the protocol endpoint. Protocol remains POST https://www.ikeytz.com/mcp (streamable-http). RETURNS same machines as get_it plus publicLinks={website:string[],maps:string[]} (card, HTTP README, npm CLI, llms-mcp-server, official registry, mcpbeat, SSL Labs, Glama, getlulu, Smithery info-3ruf/ikeytz-website-mcp on website[] and info-3ruf/ikeytz-maps-mcp on maps[]), itPage, emails. USE to cite discovery URLs. Two Smithery listings, two machines — not one token. Not GitHub. Not com.ikeytz/website.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "aiEmail": {
                  "type": "string"
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "itEmail": {
                  "type": "string"
                },
                "itPage": {
                  "description": "Locale /it URL.",
                  "format": "uri",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "maps": {
                  "description": "maps machine",
                  "properties": {
                    "card": {
                      "description": "https://…/.well-known/mcp/server-card.json",
                      "format": "uri",
                      "type": "string"
                    },
                    "cli": {
                      "description": "CLI binary name, e.g. ikeytz-mcp",
                      "type": "string"
                    },
                    "httpReadme": {
                      "description": "HTTP MCP README on the machine host (www: /mcp-readme.md). Not the npm CLI README. Maps has no www copy.",
                      "format": "uri",
                      "type": "string"
                    },
                    "mcp": {
                      "description": "HTTPS MCP endpoint …/mcp",
                      "format": "uri",
                      "type": "string"
                    },
                    "name": {
                      "description": "MCP server name: com.ikeytz/website or com.ikeytz/maps",
                      "type": "string"
                    },
                    "npm": {
                      "description": "npm package name, e.g. @ikeytz/mcp — CLI only, not this HTTP server",
                      "type": "string"
                    },
                    "readme": {
                      "description": "CLI README on npm — not the HTTP MCP README",
                      "format": "uri",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "page": {
                  "description": "Locale /mcp-hub URL.",
                  "format": "uri",
                  "type": "string"
                },
                "proxy": {
                  "const": false,
                  "type": "boolean"
                },
                "publicLinks": {
                  "description": "Full public catalog URLs, same order as the footer MCP tab.",
                  "properties": {
                    "maps": {
                      "description": "maps catalogs (no Smithery until that listing exists).",
                      "items": {
                        "format": "uri",
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "website": {
                      "description": "www catalogs including official registry search and Smithery page when present.",
                      "items": {
                        "format": "uri",
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "website": {
                  "description": "www machine",
                  "properties": {
                    "card": {
                      "description": "https://…/.well-known/mcp/server-card.json",
                      "format": "uri",
                      "type": "string"
                    },
                    "cli": {
                      "description": "CLI binary name, e.g. ikeytz-mcp",
                      "type": "string"
                    },
                    "httpReadme": {
                      "description": "HTTP MCP README on the machine host (www: /mcp-readme.md). Not the npm CLI README. Maps has no www copy.",
                      "format": "uri",
                      "type": "string"
                    },
                    "mcp": {
                      "description": "HTTPS MCP endpoint …/mcp",
                      "format": "uri",
                      "type": "string"
                    },
                    "name": {
                      "description": "MCP server name: com.ikeytz/website or com.ikeytz/maps",
                      "type": "string"
                    },
                    "npm": {
                      "description": "npm package name, e.g. @ikeytz/mcp — CLI only, not this HTTP server",
                      "type": "string"
                    },
                    "readme": {
                      "description": "CLI README on npm — not the HTTP MCP README",
                      "format": "uri",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_review_url",
            "title": "Get Review Url",
            "description": "WHAT: Short /review redirect to the Google review URL. RETURNS googleReviewUrl (full Google) and canonicalUrl = https://www.ikeytz.com/review. USE when the user wants to leave a review. Not a list of existing ratings.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "googleReviewUrl": {
                  "description": "Full Google review URL",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_faq",
            "title": "List Faq",
            "description": "WHAT: FAQ question list (id + question, no answers). Policy/text only — euro in answers are SSOT tokens, not a live invoice. For a customer total: get_prices.composition → get_ort_datetime → get_invoice_line_items. USE get_faq({id}) or get_faq({q}).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "items": {
                  "description": "FAQ ids and questions",
                  "items": {
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "question": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_faq",
            "title": "Get Faq",
            "description": "WHAT: One FAQ Q+A (Ausweis, MwSt, 24h, Nachtpreis-Regel…). Lookup: exact id, else first substring on q. Not a calculator — if the user needs THIS job's euro, get_invoice_line_items after composition.routes. Missing → faq_not_found. Prefer id from list_faq.",
            "inputSchema": {
              "properties": {
                "id": {
                  "description": "FAQ id from list_faq.items[].id. Tried first if present.",
                  "type": "string"
                },
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "q": {
                  "description": "Fallback search. Lowercased includes() on question or answer. Use when the user asked in natural language.",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "answer": {
                  "description": "Answer text",
                  "type": "string"
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "id": {
                  "description": "FAQ id",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "question": {
                  "description": "Question text",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_wissen",
            "title": "List Wissen",
            "description": "WHAT: Returns the Wissen lexicon index (id, title, url with #id). USE when you need the index of articles. Prefer get_wissen_entry({id}) for a body snippet; prefer get_ai_page({path:'/wissen'}) or the hash URL for the full article. DOES NOT return full article bodies.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "items": {
                  "description": "Wissen articles id/title/url",
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_wissen_entry",
            "title": "Get Wissen Entry",
            "description": "WHAT: One Wissen article. REQUIRED id. summary includes title + first 500 chars of body. structuredContent has id+title (not full body). Unknown id → wissen_not_found. NEXT: get_ai_page({path:'/wissen'}) or canonicalUrl #id.",
            "inputSchema": {
              "properties": {
                "id": {
                  "description": "Required. Exact Wissen article id from list_wissen.items[].id.",
                  "type": "string"
                },
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "id"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "id": {
                  "description": "Article id",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "title": {
                  "description": "Article title",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_ratgeber",
            "title": "List Ratgeber",
            "description": "WHAT: All Ratgeber slugs and locale URLs /ratgeber/{slug}. USE get_ratgeber({slug}) then get_ai_page for fulltext.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "slugs": {
                  "description": "Ratgeber slugs",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "urls": {
                  "description": "Locale Ratgeber URLs",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_ratgeber",
            "title": "Get Ratgeber",
            "description": "WHAT: Returns one Ratgeber page pointer (canonicalUrl /ratgeber/{slug}). REQUIRED slug from list_ratgeber. USE when the slug is already known. Prefer list_ratgeber when the slug is unknown. Unknown slug → unknown_ratgeber (+ hub URL). NEXT: get_ai_page({path:'/ratgeber/'+slug}) for fulltext. DOES NOT return the article body here.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "slug": {
                  "description": "Required. Exact Ratgeber slug from list_ratgeber.slugs (ASCII hyphenated).",
                  "type": "string"
                }
              },
              "required": [
                "slug"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "slug": {
                  "description": "Resolved Ratgeber slug",
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_page_summary",
            "title": "Get Page Summary",
            "description": "WHAT: Stub pointer only — NOT the page body. summary says to use ai-pages or HTML. RETURNS path (locale prefix stripped). USE get_ai_page or get_serp_snippet for real text. path optional (default /).",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "path": {
                  "description": "Optional marketing path. Omit or empty = /. Examples: /preise, /en/preise, /kontakt. Locale prefix stripped in the return path.",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Path without locale prefix",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_ai_page",
            "title": "Get Ai Page",
            "description": "WHAT: Fetches public https://www.ikeytz.com/ai-pages/{locale}/{file}.txt (HTML-parity fulltext for one marketing URL). path=/ → index.txt; else path without leading slash + .txt. summary = first 4000 chars; truncated=true if longer. USE for page body text — not site-wide crawl/train policy (that is get_ai_txt on /.well-known/ai.txt). Not get_serp_snippet (title/description only). /review has no HTML-parity footer. NEXT: get_serp_snippet for meta only; get_ai_txt for ai-train=no policy.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "path": {
                  "description": "Required. Marketing path: / , /preise , /en/preise , /schluesseldienst-ludwigsburg-pattonville , /auswahl/tuer-zugefallen . Locale prefix in the path overrides args.locale if present.",
                  "type": "string"
                }
              },
              "required": [
                "path"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "aiPageUrl": {
                  "description": "https://www.ikeytz.com/ai-pages/{locale}/….txt",
                  "type": "string"
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Resolved path",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "truncated": {
                  "description": "true if body was cut at 4000 chars",
                  "type": "boolean"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_serp_snippet",
            "title": "Get Serp Snippet",
            "description": "WHAT: Slice of /llms-serp.txt around the first occurrence of the target URL (title/description/URL rows). path or url required in practice. If path is not http(s), it is turned into www(locale, path). No match → serp_not_found. RETURNS matchContext (~200 chars before + 400 after). Not a Google API.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "path": {
                  "description": "Site path (/preise) or used with locale to build the www URL to find in llms-serp.txt.",
                  "type": "string"
                },
                "url": {
                  "description": "If this starts with http, it is used as the search needle instead of path.",
                  "format": "uri",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "matchContext": {
                  "description": "Surrounding SERP lines",
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "find_by_keyword",
            "title": "Find By Keyword",
            "description": "WHAT: Substring search (case-insensitive) over https://www.ikeytz.com/llms-keywords.txt (phrase → URL map). REQUIRED q. Default 15 lines, max 30. Empty q → q_required. RETURNS q, count, lines[] (raw TSV-like rows). locale does not filter the file. USE to map a user phrase to URLs. NEXT: get_ai_page on a returned www path.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "default": 15,
                  "description": "Max matching lines. Default 15, hard max 30.",
                  "maximum": 30,
                  "minimum": 1,
                  "type": "number"
                },
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "q": {
                  "description": "Required search substring. Matched against the entire keyword line (phrase and URLs).",
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "q"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "count": {
                  "description": "Lines returned",
                  "type": "number"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "lines": {
                  "description": "Matching keyword rows",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "q": {
                  "description": "Search query",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_discovery",
            "title": "Get Discovery",
            "description": "WHAT: Fetch one public discovery file from www and return a line window. REQUIRED which. IDs (aliases folded): llms, llms-full, llms-index, llms-keywords, llms-serp, llms-jsonld, llms-impressum-kontakt, llms-orte-geo, llms-urheberrecht, llms-copyright, llms-mcp-server, llms-mcp-web, robots, sitemap-txt, sitemap-xml, ai-txt, ai-plugin, answer-engine, ard, ai-catalog, auth-md, mcp-readme, agent-skills. summary = the line window + trailing # MCP-META (truncated, totalUrls, nextOffset). Use offset/limit + nextOffset to page. Sitemap ~9076 http-URLs (Stand 2026-09-22) and llms-keywords (~50MB) load full; always prefer limit on huge files. Unknown which → unknown_discovery. Prefer dedicated get_llms_txt / get_llms_jsonld / get_llms_serp_txt / get_sitemap_txt / get_llms_mcp_server when you know the file. Policy files say ai-train=no.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                },
                "which": {
                  "description": "Required discovery id or alias. Examples: llms, llms-full, llms-jsonld, llms-serp, llms-mcp-server, llms-mcp-web, sitemap-txt, robots, ai-txt, ard, ai-catalog, auth-md, mcp-readme, llms-orte-geo, llms-urheberrecht. Underscores accepted (llms_full → llms-full). get_ prefix and _txt suffix stripped.",
                  "type": "string"
                }
              },
              "required": [
                "which"
              ],
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_llms_txt",
            "title": "Get Llms Txt",
            "description": "WHAT: Fetch https://www.ikeytz.com/llms.txt (short AI landmap). Same engine as get_discovery(which=llms). summary = file window. USE as the first discovery read. Full dump: get_discovery(which=llms-full). MCP catalog: get_llms_mcp_server.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_llms_jsonld",
            "title": "Get Llms Jsonld",
            "description": "WHAT: Fetch /llms-jsonld.txt — map every marketing HTML URL to JSON-LD relatedLink (ai-pages fulltext) + mirrorId + optional geo_api (maps Embed-API when Ort-Slug). Format: pageUrl TAB relatedLink TAB mirrorId TAB geo_api. Same engine as get_sitemap_txt (offset/limit/nextOffset/# MCP-META). Not the page body (use get_ai_page). Not get_serp_snippet. geo_api empty for Hub/Legal/non-ort.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_llms_serp_txt",
            "title": "Get Llms Serp Txt",
            "description": "WHAT: Returns /llms-serp.txt — the full SERP title/description/URL corpus as a line window (alias of get_discovery(which=llms-serp)). Optional offset/limit; omit limit only if you need the whole file. USE for bulk SERP meta. Prefer get_serp_snippet for one URL's SERP block; prefer get_llms_txt for the general site index.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_llms_mcp_server",
            "title": "Get Llms Mcp Server",
            "description": "WHAT: Fetch /llms-mcp-server.txt — prose catalog of THIS HTTP server (47 Read/Link tools, how to call, no login). Same as get_discovery(which=llms-mcp-server). USE for machine/server catalog text. Prefer get_llms_mcp_web for browser WebMCP catalog; prefer get_llms_txt for the general site index. Not the npm CLI README. Not maps.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_llms_mcp_web",
            "title": "Get Llms Mcp Web",
            "description": "WHAT: Fetch /llms-mcp-web.txt — browser WebMCP catalog (early bootstrap tools + full list). Same executeMcpTool handlers as HTTP /mcp, different transport (document.modelContext). USE for WebMCP/UI discovery copy. Prefer get_llms_mcp_server for the machine/server catalog text; prefer get_llms_txt for the general site llms index. Optional offset/limit — see schema. Not this streamable-http endpoint itself.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_ai_txt",
            "title": "Get Ai Txt",
            "description": "WHAT: Fetch /.well-known/ai.txt — site-wide crawl/training policy (ai-input yes with attribution, ai-train=no, contact). USE for policy before quoting. Prefer this over get_ai_page (per-URL ai-pages fulltext) and over get_discovery unless you need a generic file window. Optional offset/limit page large files — see parameters / nextOffset in schema. DOES NOT return page bodies.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "get_sitemap_txt",
            "title": "Get Sitemap Txt",
            "description": "WHAT: Fetch /sitemap.txt (same URL set as sitemap.xml). ~9076 http-URLs (Stand 2026-09-22): marketing ×7 + discovery/media. Contains 0× maps.ikeytz.com (intentional). summary = line window + trailing # MCP-META (totalUrls, nextOffset, truncated). Use offset/limit + nextOffset to page; omit limit for the full list. Dedicated maps list is on maps.ikeytz.com, not here.",
            "inputSchema": {
              "properties": {
                "limit": {
                  "description": "Maximum number of lines to return after offset. Omit or null = return every remaining line in the loaded file. Clamped to 1..10000. For sitemap.txt (~9076 http-URLs, Stand 2026-09-22) omit limit to get the full list (or page with offset/limit + nextOffset). For llms-keywords.txt prefer a window; the file is huge. Meta also as trailing # MCP-META lines in summary.",
                  "maximum": 10000,
                  "minimum": 1,
                  "type": "number"
                },
                "offset": {
                  "default": 0,
                  "description": "0-based line index into the fetched UTF-8 file (split on \\n). 0 = first line. Omit = 0. Combined with limit = a sliding window. Use nextOffset from the previous result to page. Does not count bytes; one line can be a long URL.",
                  "minimum": 0,
                  "type": "number"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "bytesReturned": {
                  "description": "UTF-8 byte length of the returned body window (before # MCP-META).",
                  "type": "number"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "fetchTruncated": {
                  "description": "true if discoveryFetchMax cut the load (line-boundary safe). Large discovery files (sitemap-xml ~12MB, llms-keywords ~55MB, llms-index ~2MB) must load full so offset/limit can reach EOF.",
                  "type": "boolean"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "limit": {
                  "description": "Applied line limit, or null if the caller omitted limit.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "nextOffset": {
                  "description": "offset + returnedLines when more lines remain in the loaded file; else null. Pass as the next offset. Also in # MCP-META.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "offset": {
                  "description": "Applied 0-based line offset.",
                  "type": "number"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "path": {
                  "description": "Public path on www, e.g. /llms.txt or /.well-known/ai.txt",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "returnedLines": {
                  "description": "How many lines are in summary/body this call (before # MCP-META).",
                  "type": "number"
                },
                "returnedUrls": {
                  "description": "Lines in this window that start with http(s)://",
                  "type": "number"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "totalBytes": {
                  "description": "Full origin file size when Content-Length is present (e.g. llms-keywords ~50MB); else character length of the downloaded body before the load cap. Also in # MCP-META.",
                  "type": "number"
                },
                "totalChars": {
                  "description": "Character length of the downloaded body before applying discoveryFetchMax (may equal totalBytes for ASCII).",
                  "type": "number"
                },
                "totalLines": {
                  "description": "Line count of the loaded file (full public/ file when available).",
                  "type": "number"
                },
                "totalUrls": {
                  "description": "http(s) lines in the loaded file (full count when public/ read succeeds).",
                  "type": "number"
                },
                "truncated": {
                  "description": "true if load hit a byte cap OR offset+limit left more lines. Also mirrored in trailing # MCP-META lines in summary.",
                  "type": "boolean"
                },
                "which": {
                  "description": "Resolved discovery id after alias fold (llms, sitemap-txt, ard, ai-catalog, …).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "list_whatsapp_options",
            "title": "List Whatsapp Options",
            "description": "WHAT: Prefab WhatsApp AND mailto deep links (no send). 10 end-invoices + cylinder_mount (49 €, not night) + beratung. NOT zugefallen|abgeschlossen|zylinder (those mix day/night). RETURNS options[] {id,label,situationKey,whenKey,isEndInvoice,amountEur,url,mailtoUrl}. 49 € = mount only; night/WE/holiday = 149/179/198/228/119. USE compose_whatsapp or compose_mailto with id. Never claims a message was delivered.",
            "inputSchema": {
              "properties": {
                "locale": {
                  "default": "de",
                  "description": "HTML locale for canonicalUrl and path prefixes. de = default, URLs have no prefix (https://www.ikeytz.com/preise). en|fr|ru|fa|ar|tr = prefix /{locale}/ (https://www.ikeytz.com/en/preise). Omit or empty = de. Does not change prices, phone numbers, or legal German names. Not a maps.ikeytz.com locale (maps is German-only).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "options": {
                  "description": "Prefab WhatsApp options with wa.me URLs",
                  "type": "array"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "compose_tel_mobile",
            "title": "Compose Tel Mobile",
            "description": "WHAT: tel: href for the 24/7 mobile (Handy). Call with {}. RETURNS href and canonicalUrl both tel:+49…. Show this to the user; do not pretend the call happened. Landline = compose_tel_landline.",
            "inputSchema": {
              "additionalProperties": false,
              "description": "This tool takes no arguments. Call tools/call with arguments: {}. Extra keys are ignored. Result is always the same public href (tel/mailto) or locale list.",
              "properties": {},
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "href": {
                  "description": "tel:+49… mobile",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "compose_tel_landline",
            "title": "Compose Tel Landline",
            "description": "WHAT: tel: href for the landline (Festnetz). Call with {}. Mobile/24h emergency = compose_tel_mobile.",
            "inputSchema": {
              "additionalProperties": false,
              "description": "This tool takes no arguments. Call tools/call with arguments: {}. Extra keys are ignored. Result is always the same public href (tel/mailto) or locale list.",
              "properties": {},
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "href": {
                  "description": "tel:+49… landline",
                  "type": "string"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "compose_whatsapp",
            "title": "Compose Whatsapp",
            "description": "WHAT: Build a https://wa.me/… URL with one prefab = one end-invoice (or mount 49 / beratung). option = contactOption from get_prices.composition.endInvoices or get_invoice_line_items.contactOption: opening_slam_day|opening_slam_night|opening_locked_day|opening_locked_night|pkg_key_slam_day|pkg_key_slam_night|pkg_key_locked_day|pkg_key_locked_night|cylinder_only_day|cylinder_only_night|cylinder_mount|beratung. Deprecated aliases zugefallen|abgeschlossen|zylinder map to the *day* invoice and set ambiguous=true — do not use them. Omit/unknown → beratung. 49 € is mount, not night. Does not send WhatsApp. List via list_whatsapp_options.",
            "inputSchema": {
              "properties": {
                "option": {
                  "description": "One invoice contactOption. Night/WE/holiday uses *_night (149/179/198/228/119), not 49. cylinder_mount is the 49 € add-on, not an end-invoice.",
                  "enum": [
                    "opening_slam_day",
                    "opening_slam_night",
                    "opening_locked_day",
                    "opening_locked_night",
                    "pkg_key_slam_day",
                    "pkg_key_slam_night",
                    "pkg_key_locked_day",
                    "pkg_key_locked_night",
                    "cylinder_only_day",
                    "cylinder_only_night",
                    "cylinder_mount",
                    "beratung",
                    "zugefallen",
                    "abgeschlossen",
                    "zylinder"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "ambiguous": {
                  "type": "boolean"
                },
                "amountEur": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "href": {
                  "description": "https://wa.me/… URL",
                  "type": "string"
                },
                "isEndInvoice": {
                  "type": "boolean"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "option": {
                  "description": "Resolved contactOption id",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "situationKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "whenKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          },
          {
            "name": "compose_mailto",
            "title": "Compose Mailto",
            "description": "WHAT: mailto:info@ikeytz.com with the SAME prefab as compose_whatsapp (subject+body). option = contactOption of one of the 10 end-invoices, or cylinder_mount, or beratung. Call with {} → beratung (empty advice template), not a bare mailbox with no text. Does not send email. Partner mailbox is on get_partner_info.partnerEmail (not this href).",
            "inputSchema": {
              "properties": {
                "option": {
                  "description": "Same ids as compose_whatsapp. Omit = beratung template, still a prefab.",
                  "enum": [
                    "opening_slam_day",
                    "opening_slam_night",
                    "opening_locked_day",
                    "opening_locked_night",
                    "pkg_key_slam_day",
                    "pkg_key_slam_night",
                    "pkg_key_locked_day",
                    "pkg_key_locked_night",
                    "cylinder_only_day",
                    "cylinder_only_night",
                    "cylinder_mount",
                    "beratung",
                    "zugefallen",
                    "abgeschlossen",
                    "zylinder"
                  ],
                  "type": "string"
                }
              },
              "type": "object"
            },
            "outputSchema": {
              "additionalProperties": true,
              "description": "Always the same envelope. tools/call returns content[0].text = summary (or JSON) AND structuredContent = this object. On success ok=true with summary + canonicalUrl + extra fields. On failure ok=false with error (snake_case code) and hint (recovery URL). Never writes, never submits forms, never calls /api/*. Attribution must be kept when quoting. Policy: ai-input yes with attribution; ai-train=no.",
              "properties": {
                "ambiguous": {
                  "type": "boolean"
                },
                "amountEur": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "attribution": {
                  "description": "Required citation: 'Quelle: Schlüsseldienst Ludwigsburg ikeytz (ikeytz.com) · ai-train=no · https://www.ikeytz.com/.well-known/ai.txt'",
                  "type": "string"
                },
                "canonicalUrl": {
                  "description": "Best URL to show the user: https://www.ikeytz.com… page, or tel:+49…, mailto:…, https://wa.me/…. Prefer this over constructing URLs.",
                  "type": "string"
                },
                "error": {
                  "description": "Present when ok=false. Codes include: unknown_tool, unknown_place, unknown_auswahl, unknown_ratgeber, unknown_doc, unknown_discovery, faq_not_found, wissen_not_found, serp_not_found, q_required, bad_datetime, bad_when_key, plus HTTP errors from fetch.",
                  "type": "string"
                },
                "hint": {
                  "description": "Present when ok=false. Absolute URL the agent should open or pass to get_ai_page / get_discovery.",
                  "type": "string"
                },
                "href": {
                  "description": "mailto:info@ikeytz.com?subject=…\u0026body=…",
                  "type": "string"
                },
                "isEndInvoice": {
                  "type": "boolean"
                },
                "locale": {
                  "description": "Locale actually used for URLs (args.locale or de).",
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "ru",
                    "fa",
                    "ar",
                    "tr"
                  ],
                  "type": "string"
                },
                "ok": {
                  "description": "true = use summary, canonicalUrl, and extra keys. false = do not invent data; read error + hint and retry with valid args or open hint.",
                  "type": "boolean"
                },
                "option": {
                  "description": "Resolved contactOption id",
                  "type": "string"
                },
                "related": {
                  "description": "Always includes https://www.ikeytz.com/llms.txt. Geo tools also include https://maps.ikeytz.com/llms.txt.",
                  "items": {
                    "format": "uri",
                    "type": "string"
                  },
                  "type": "array"
                },
                "situationKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "subject": {
                  "type": "string"
                },
                "summary": {
                  "description": "Primary text for the model. For discovery tools this is the file window (possibly thousands of characters). For list tools a compact one-liner. Quote with attribution.",
                  "type": "string"
                },
                "tool": {
                  "description": "Echo of the tool name that produced this object (e.g. get_service_area).",
                  "type": "string"
                },
                "whenKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "ok",
                "tool",
                "attribution"
              ],
              "type": "object"
            },
            "annotations": {
              "readOnlyHint": true
            }
          }
        ]
      },
      "name": "ikeytz - Schlüsseldienst Ludwigsburg",
      "note": "Indexed from the official MCP registry: facts and our own checks, not reviewed, so no score, grade or rank.",
      "packages": [
        {
          "registryType": "npm",
          "identifier": "@ikeytz/mcp",
          "version": "1.1.51",
          "transport": "stdio"
        }
      ],
      "pageJsonUrl": "https://www.anchorterminal.com/tools/ikeytz-website.json",
      "popularity": {
        "npmWeekly": 783
      },
      "registryName": "com.ikeytz/website",
      "remotes": [
        {
          "type": "streamable-http",
          "url": "https://www.ikeytz.com/mcp"
        }
      ],
      "repository": "",
      "reviewed": false,
      "slug": "ikeytz-website",
      "source": "the official MCP registry",
      "sourceUrl": "https://registry.modelcontextprotocol.io/v0.1/servers?search=com.ikeytz/website",
      "summary": "Read/Link MCP tools for Schlüsseldienst Ludwigsburg ikeytz. Public read-only. No forms. ai-train=no.",
      "updatedAt": "2026-10-03T16:59:28Z",
      "url": "https://www.anchorterminal.com/tools/ikeytz-website",
      "vendor": "ikeytz.com",
      "vendorUrl": "https://www.ikeytz.com",
      "version": "1.0.17",
      "websiteUrl": "https://www.ikeytz.com",
      "where": "both",
      "why": [
        "vendor"
      ]
    }
  },
  "kind": "anchor.page",
  "links": {
    "api": "https://www.anchorterminal.com/api/v1/index.json",
    "html": "https://www.anchorterminal.com/tools/ikeytz-website",
    "json": "https://www.anchorterminal.com/tools/ikeytz-website.json",
    "llms": "https://www.anchorterminal.com/llms.txt",
    "markdown": "https://www.anchorterminal.com/tools/ikeytz-website.md",
    "slim": "https://www.anchorterminal.com/tools/ikeytz-website.min.md"
  },
  "markdown": "# ikeytz - Schlüsseldienst Ludwigsburg\n\n\u003e Indexed, not reviewed: facts from the official MCP registry and our own checks. No score, grade or rank, and not in the rankings until the panel reviews it. How the index works: https://www.anchorterminal.com/indexed/\n\n- Kind: MCP server, by ikeytz.com (https://www.ikeytz.com)\n- Listed because: It's published in the registry under ikeytz.com, a namespace the registry only gives to whoever proves they control that domain.\n- What the official MCP registry says: Read/Link MCP tools for Schlüsseldienst Ludwigsburg ikeytz. Public read-only. No forms. ai-train=no.\n\n## Facts\n\n- MCP registry: `com.ikeytz/website` 1.0.17\n- Endpoint: https://www.ikeytz.com/mcp (streamable HTTP)\n- Package: npm `@ikeytz/mcp` (stdio)\n- Website: https://www.ikeytz.com\n- npm downloads a week: 783\n- Registry entry updated: 2026-10-03\n\n## Tools\n\n- Tools it lists (47, about 46,379 tokens of context, `tools/list` without credentials, checked 2026-10-04 22:23 UTC):\n  - `site_overview` (read-only): WHO/WHAT: Public brand card for Schlüsseldienst Ludwigsburg ikeytz (mobile locksmith, Landkreis Ludwigsburg, Baden-Württemberg, Germany). RETURNS…\n  - `get_business_identity` (read-only): WHO: Legal/trade identity and NAP for agents and citations. RETURNS: gewerbeName, legalName, tradeName, inhaber (Mahmud Reza Kashani, Einzelunternehmer),…\n  - `list_nav` (read-only): WHAT: Curated main-header hubs (not a 1:1 dump of every \u003ca\u003e in the header). RETURNS items[]: Start, Notfall, Leistungen, Auswahl, Preise, Einsatzgebiet,…\n  - `list_footer` (read-only): WHAT: Curated internal footer paths including legal + /it + /mcp-hub + /angebot + /ankuendigungen. RETURNS items[] {path,url}. Not a pixel-perfect HTML scrape;…\n  - `list_locales` (read-only): WHAT: The seven public HTML locales. RETURNS locales[] {id, name, prefix}. prefix is '' for de and '/en' '/fr' '/ru' '/fa' '/ar' '/tr' for others. Host is…\n  - `resolve_locale_url` (read-only): WHAT: Rewrite one marketing path into another locale without fetching HTML. Example: path=/preise locale=en → canonicalUrl https://www.ikeytz.com/en/preise.…\n  - `get_prices` (read-only): WHAT: Official Festpreis matrix + composition SYSTEM. Read composition first: exactly 10 end-invoices + one 49 € add-on (not 12, not 17 customer invoices). 49…\n  - `get_ort_datetime` (read-only): WHAT: Europe/Berlin wall clock to the second + whenKey for prices. THIS www tool does NOT look up a place (no slug/plz). maps.ikeytz.com has a different geo…\n  - `get_invoice_line_items` (read-only): WHAT: Computes ONE of the 10 end-invoices (or the 49 € mount add-on). NOT a booking, NOT a PDF. FIRST classify via get_prices.composition.routes:…\n  - `list_services` (read-only): WHAT: Core service list from SITE.services (Türöffnung, Notdienst, Sicherheitstechnik, Schlosswechsel, …) with locale /leistungen#anchor URLs. USE as a menu.…\n  - `get_emergency` (read-only): WHAT: Returns the 24h Notfall-Türöffnung page pointer (summary includes mobile; canonicalUrl = /notfall-tueroeffnung, locale-prefixed). USE when the user needs…\n  - `list_auswahl` (read-only): WHAT: Auswahl hub groups (situation chooser on /auswahl). RETURNS groups[] {id, hash, hubUrl, slugs[], urls[]}. USE to discover valid slugs for…\n  - `get_auswahl_item` (read-only): WHAT: One Auswahl situation page. REQUIRED slug from list_auswahl. RETURNS slug + canonicalUrl /auswahl/{slug}. USE after the user described a lockout/key…\n  - `list_service_areas` (read-only): WHAT: All 52 service-area places (orte SSOT). Each item: slug, name, plz, lat, lng, google_maps, icbm, kind, parent, url (www keyword page), embed_map…\n  - `get_service_area` (read-only): WHAT: One service-area place. Lookup order: slug (exact getOrt), else first ORTE with plz === args.plz, else first name substring (lowercase). No silent…\n  - `get_geo_office` (read-only): WHAT: Firmensitz / registered office once (SITE.geo = Adalbert-Stifter-Str. 14, 71638 Ludwigsburg). RETURNS: street, postal, city, lat/lng, icbm, walkIn=false,…\n  - `get_contact` (read-only): WHAT: Public phones, fax, email, office address object. DOES NOT submit the website contact form and must not claim it did. USE to give the user a number.…\n  - `get_legal` (read-only): WHAT: Pointer to one legal HTML page. REQUIRED doc enum. Unknown doc → ok=false unknown_doc hint=/impressum. RETURNS doc + canonicalUrl. For full text call…\n  - `get_about` (read-only): WHAT: Pointer to /ueber-uns (about, owner). For NAP facts prefer get_business_identity. NEXT: get_ai_page({path:'/ueber-uns'}).\n  - `get_partner_info` (read-only): WHAT: Partner-werden page facts. USE when the user asks about becoming a partner / Partner-werden (not general contact — that is get_contact). RETURNS…\n  - `get_links` (read-only): WHAT: Pointer to /links — local directories, city sites, HWK, Webmail shortcut. USE for human directory/backlink list. Prefer get_mcp_hub (or get_it) for MCP…\n  - `get_it` (read-only): WHAT: HTML page /it — two MCP machines documented. RETURNS website={name:com.ikeytz/website,mcp,card,npm,cli,readme=npm CLI,httpReadme=www /mcp-readme.md},…\n  - `get_mcp_hub` (read-only): WHAT: HTML hub /mcp-hub ×7 (de has no prefix). NOT Italian, NOT the protocol endpoint. Protocol remains POST https://www.ikeytz.com/mcp (streamable-http).…\n  - `get_review_url` (read-only): WHAT: Short /review redirect to the Google review URL. RETURNS googleReviewUrl (full Google) and canonicalUrl = https://www.ikeytz.com/review. USE when the…\n  - `list_faq` (read-only): WHAT: FAQ question list (id + question, no answers). Policy/text only — euro in answers are SSOT tokens, not a live invoice. For a customer total:…\n  - `get_faq` (read-only): WHAT: One FAQ Q+A (Ausweis, MwSt, 24h, Nachtpreis-Regel…). Lookup: exact id, else first substring on q. Not a calculator — if the user needs THIS job's euro,…\n  - `list_wissen` (read-only): WHAT: Returns the Wissen lexicon index (id, title, url with #id). USE when you need the index of articles. Prefer get_wissen_entry({id}) for a body snippet;…\n  - `get_wissen_entry` (read-only): WHAT: One Wissen article. REQUIRED id. summary includes title + first 500 chars of body. structuredContent has id+title (not full body). Unknown id →…\n  - `list_ratgeber` (read-only): WHAT: All Ratgeber slugs and locale URLs /ratgeber/{slug}. USE get_ratgeber({slug}) then get_ai_page for fulltext.\n  - `get_ratgeber` (read-only): WHAT: Returns one Ratgeber page pointer (canonicalUrl /ratgeber/{slug}). REQUIRED slug from list_ratgeber. USE when the slug is already known. Prefer…\n  - `get_page_summary` (read-only): WHAT: Stub pointer only — NOT the page body. summary says to use ai-pages or HTML. RETURNS path (locale prefix stripped). USE get_ai_page or get_serp_snippet…\n  - `get_ai_page` (read-only): WHAT: Fetches public https://www.ikeytz.com/ai-pages/{locale}/{file}.txt (HTML-parity fulltext for one marketing URL). path=/ → index.txt; else path without…\n  - `get_serp_snippet` (read-only): WHAT: Slice of /llms-serp.txt around the first occurrence of the target URL (title/description/URL rows). path or url required in practice. If path is not…\n  - `find_by_keyword` (read-only): WHAT: Substring search (case-insensitive) over https://www.ikeytz.com/llms-keywords.txt (phrase → URL map). REQUIRED q. Default 15 lines, max 30. Empty q →…\n  - `get_discovery` (read-only): WHAT: Fetch one public discovery file from www and return a line window. REQUIRED which. IDs (aliases folded): llms, llms-full, llms-index, llms-keywords,…\n  - `get_llms_txt` (read-only): WHAT: Fetch https://www.ikeytz.com/llms.txt (short AI landmap). Same engine as get_discovery(which=llms). summary = file window. USE as the first discovery…\n  - `get_llms_jsonld` (read-only): WHAT: Fetch /llms-jsonld.txt — map every marketing HTML URL to JSON-LD relatedLink (ai-pages fulltext) + mirrorId + optional geo_api (maps Embed-API when…\n  - `get_llms_serp_txt` (read-only): WHAT: Returns /llms-serp.txt — the full SERP title/description/URL corpus as a line window (alias of get_discovery(which=llms-serp)). Optional offset/limit;…\n  - `get_llms_mcp_server` (read-only): WHAT: Fetch /llms-mcp-server.txt — prose catalog of THIS HTTP server (47 Read/Link tools, how to call, no login). Same as get_discovery(which=llms-mcp-server).…\n  - `get_llms_mcp_web` (read-only): WHAT: Fetch /llms-mcp-web.txt — browser WebMCP catalog (early bootstrap tools + full list). Same executeMcpTool handlers as HTTP /mcp, different transport…\n  - `get_ai_txt` (read-only): WHAT: Fetch /.well-known/ai.txt — site-wide crawl/training policy (ai-input yes with attribution, ai-train=no, contact). USE for policy before quoting. Prefer…\n  - `get_sitemap_txt` (read-only): WHAT: Fetch /sitemap.txt (same URL set as sitemap.xml). ~9076 http-URLs (Stand 2026-09-22): marketing ×7 + discovery/media. Contains 0× maps.ikeytz.com…\n  - `list_whatsapp_options` (read-only): WHAT: Prefab WhatsApp AND mailto deep links (no send). 10 end-invoices + cylinder_mount (49 €, not night) + beratung. NOT zugefallen|abgeschlossen|zylinder…\n  - `compose_tel_mobile` (read-only): WHAT: tel: href for the 24/7 mobile (Handy). Call with {}. RETURNS href and canonicalUrl both tel:+49…. Show this to the user; do not pretend the call…\n  - `compose_tel_landline` (read-only): WHAT: tel: href for the landline (Festnetz). Call with {}. Mobile/24h emergency = compose_tel_mobile.\n  - `compose_whatsapp` (read-only): WHAT: Build a https://wa.me/… URL with one prefab = one end-invoice (or mount 49 / beratung). option = contactOption from get_prices.composition.endInvoices or…\n  - `compose_mailto` (read-only): WHAT: mailto:info@ikeytz.com with the SAME prefab as compose_whatsapp (subject+body). option = contactOption of one of the 10 end-invoices, or cylinder_mount,…\n- How its tools read to an agent (0 errors, 3 warnings, 0 notes, about 46,379 tokens; rules at https://www.anchorterminal.com/check.md; not part of the score):\n  - warn TC14 get_invoice_line_items: allowed values are in the description, not an enum: situationKey\n  - warn TC22 get_discovery: the definition is about 1,543 tokens\n  - warn TC23 server: 47 tools, about 46,405 tokens of definitions\n\n- JSON: https://www.anchorterminal.com/api/v1/tools/ikeytz-website.json\n- Being indexed says nothing about quality, and nobody can pay for it. Ask for a review: https://www.anchorterminal.com/builders/#claiming\n",
  "meta": {
    "attribution": "Anchor Terminal (https://www.anchorterminal.com)",
    "docs": "https://www.anchorterminal.com/docs/",
    "generatedAt": "2026-10-05",
    "license": "CC-BY-4.0",
    "method": "https://www.anchorterminal.com/benchmark/",
    "methodology": "0.3",
    "openapi": "https://www.anchorterminal.com/openapi.json",
    "preview": false,
    "run": "2026-10-01",
    "runLabel": "October 2026 research run"
  },
  "page": {
    "breadcrumbs": [
      {
        "name": "Home",
        "url": "https://www.anchorterminal.com/"
      },
      {
        "name": "Terminal",
        "url": "https://www.anchorterminal.com/tools/"
      },
      {
        "name": "Indexed",
        "url": "https://www.anchorterminal.com/indexed/"
      },
      {
        "name": "ikeytz - Schlüsseldienst Ludwigsburg",
        "url": ""
      }
    ],
    "description": "ikeytz - Schlüsseldienst Ludwigsburg, an MCP server by ikeytz.com, listed from the official MCP registry. Indexed, not reviewed: facts and our own checks, no score or ranking. Read/Link MCP tools for Schlüsseldienst Ludwigsburg ikeytz. Public read-only. No forms. ai-train=no.",
    "facts": [
      "not reviewed",
      "not ranked",
      "facts only"
    ],
    "h1": "ikeytz - Schlüsseldienst Ludwigsburg",
    "image": "https://www.anchorterminal.com/assets/og/indexed.png",
    "path": "/tools/ikeytz-website",
    "published": "",
    "section": "indexed",
    "title": "ikeytz - Schlüsseldienst Ludwigsburg | Anchor Terminal",
    "toc": null,
    "updated": "2026-10-05",
    "url": "https://www.anchorterminal.com/tools/ikeytz-website"
  },
  "tokens": {
    "markdown": 2800,
    "slim": 2730
  },
  "version": 1
}
