{
  "openapi": "3.1.0",
  "info": {
    "title": "FreeTools API",
    "version": "3.0.0",
    "description": "Free developer tools with JSON APIs. No key, no signup, no tracking. An MCP server exposing the same tools is available at POST /mcp.",
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://freetools.one"
    }
  ],
  "x-mcp": {
    "endpoint": "https://freetools.one/mcp",
    "transport": "streamable-http",
    "protocolVersion": "2025-06-18",
    "tools": [
      "count_loc",
      "star_history",
      "check_tls",
      "http_headers",
      "ip_geolocation",
      "get_weather"
    ],
    "clientConfig": {
      "mcpServers": {
        "freetools": {
          "url": "https://freetools.one/mcp"
        }
      }
    }
  },
  "x-rate-limit": {
    "requests": 30,
    "perMinutes": 1,
    "note": "/v1/random/* allows 300/min. Exceeding returns 429."
  },
  "paths": {
    "/v1/loc": {
      "get": {
        "summary": "Count lines of code in a GitHub or GitLab repository",
        "parameters": [
          {
            "name": "github",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "torvalds/linux"
          },
          {
            "name": "gitlab",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "gitlab-org/gitlab-runner"
          },
          {
            "name": "branch",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ignored",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "comma-separated files/dirs"
          },
          {
            "name": "detail",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "files"
              ]
            },
            "description": "also return extensions[] and files[]"
          }
        ],
        "responses": {
          "200": {
            "description": "Per-language stats, or {languages, extensions, files} with detail=1",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LangStats"
                }
              }
            }
          },
          "400": {
            "description": "Invalid repository or parameters"
          },
          "413": {
            "description": "Repository too large"
          }
        }
      }
    },
    "/v1/locbadge": {
      "get": {
        "summary": "Single formatted LOC number for README badges",
        "parameters": [
          {
            "name": "github",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "cli/cli"
          },
          {
            "name": "gitlab",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "gitlab-org/gitlab-runner"
          }
        ],
        "responses": {
          "200": {
            "description": "Formatted number such as 279.3k",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid repository"
          }
        }
      }
    },
    "/v1/stars": {
      "get": {
        "summary": "GitHub/GitLab star history as cumulative points",
        "parameters": [
          {
            "name": "github",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "torvalds/linux"
          },
          {
            "name": "gitlab",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "GitHub is weekly and anchored to the live total; GitLab is per-day",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StarPoint"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/stars/chart": {
      "get": {
        "summary": "Star history as an embeddable SVG image (1200x630)",
        "parameters": [
          {
            "name": "github",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "repeatable"
          },
          {
            "name": "gitlab",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "repeatable"
          },
          {
            "name": "theme",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "light",
                "dark"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SVG image",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/headers": {
      "get": {
        "summary": "HTTP response headers and redirect chain",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "example.com"
          }
        ],
        "responses": {
          "200": {
            "description": "One entry per redirect hop",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/tls": {
      "get": {
        "summary": "TLS protocol, cipher and certificate details",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "example.com"
          },
          {
            "name": "port",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 443
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Certificate and cipher information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/geolocation/json": {
      "get": {
        "summary": "IP geolocation as JSON",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "8.8.8.8"
          }
        ],
        "responses": {
          "200": {
            "description": "Location data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/geolocation/xml": {
      "get": {
        "summary": "IP geolocation as XML",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Location data",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/weather": {
      "get": {
        "summary": "Current weather by city or caller IP",
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "london"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "xml"
              ],
              "default": "json"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current temperature in Celsius and Fahrenheit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/proxy": {
      "get": {
        "summary": "SSRF-guarded CORS proxy (max 5MB)",
        "parameters": [
          {
            "name": "quest",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Proxied response body",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/random/integer": {
      "get": {
        "summary": "Random integer(s)",
        "parameters": [
          {
            "name": "min",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "max",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "times",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1,
              "maximum": 10000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Random values",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/random/list": {
      "get": {
        "summary": "Shuffled list of 1..len",
        "parameters": [
          {
            "name": "len",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 2,
              "maximum": 10000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Shuffled list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/random/name": {
      "get": {
        "summary": "Random surname",
        "responses": {
          "200": {
            "description": "A random name",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "LangStats": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "language": {
              "type": "string"
            },
            "files": {
              "type": "integer"
            },
            "lines": {
              "type": "integer"
            },
            "blanks": {
              "type": "integer"
            },
            "comments": {
              "type": "integer"
            },
            "linesOfCode": {
              "type": "integer"
            },
            "percent": {
              "type": "number"
            }
          }
        }
      },
      "StarPoint": {
        "type": "object",
        "properties": {
          "x": {
            "type": "string",
            "description": "YYYY-MM-DD"
          },
          "y": {
            "type": "integer",
            "description": "cumulative stars"
          }
        }
      }
    }
  }
}