{
  "schemaVersion": "2026-04",
  "name": "Kineticist",
  "description": "Pinball industry database, hype tracker, and editorial publication. 1,700+ pinball machines, 8,300+ locations, 347 hype themes, 600+ articles.",
  "url": "https://www.kineticist.com",
  "version": "1.0.0",
  "provider": {
    "organization": "Kineticist",
    "url": "https://www.kineticist.com"
  },
  "homepage": "https://www.kineticist.com",
  "documentationUrl": "https://www.kineticist.com/docs/api",
  "iconUrl": "https://www.kineticist.com/images/kineticist-k-mark.png",
  "contentNegotiation": {
    "markdown": {
      "siteOverview": {
        "url": "/llms.txt",
        "accept": "text/markdown",
        "note": "Curated site overview, ~700 tokens. Returned for any URL via Accept: text/markdown when no per-route projection exists."
      },
      "perRoute": {
        "discovery": "Each detail page declares <link rel=\"alternate\" type=\"text/markdown\" href=\"{canonical}.md\"> in <head>.",
        "suffixPattern": "{canonical}.md",
        "acceptHeader": "text/markdown",
        "supportedRoutes": [
          { "pattern": "/news/[slug]", "example": "/news/worst-video-modes-90s.md" },
          { "pattern": "/games/pinball/[slug]", "example": "/games/pinball/godzilla-premium.md" },
          { "pattern": "/hype/[slug]", "example": "/hype/godzilla.md" },
          { "pattern": "/locations/[slug]", "example": "/locations/pinz-portland.md" },
          { "pattern": "/manufacturers/[slug]", "example": "/manufacturers/stern-pinball.md" },
          { "pattern": "/people/[slug]", "example": "/people/keith-elwin.md" },
          { "pattern": "/mods/[slug]", "example": "/mods/cliffy-protectors.md" },
          { "pattern": "/promoters/[slug]", "example": "/promoters/replay-fx.md" }
        ],
        "tokensEstimate": "1000-3000 per route (vs ~14,000 HTML decoded)",
        "fallback": "Non-detail-page URLs (browse, homepage, etc.) return the siteOverview."
      }
    }
  },
  "capabilities": {
    "streaming": false,
    "pushNotifications": false,
    "extendedAgentCard": false
  },
  "defaultInputModes": ["application/json"],
  "defaultOutputModes": ["application/json"],
  "supportedInterfaces": [
    {
      "url": "https://www.kineticist.com/api/v1",
      "protocolBinding": "HTTP+JSON",
      "protocolVersion": "1.0"
    },
    {
      "url": "https://www.kineticist.com/api/mcp",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "2025-03-26"
    }
  ],
  "skills": [
    {
      "id": "search_pinball_games",
      "name": "Search Pinball Games",
      "description": "Search and filter the Kineticist pinball game database. Supports text search, manufacturer filtering, year ranges, production status, and sorting. Returns game names, slugs, manufacturers, fun scores, and edition counts.",
      "tags": ["search", "games", "pinball", "database", "filter", "browse"],
      "examples": [
        "Find all Stern games from 2023",
        "What pinball games have dinosaurs?",
        "Show me the highest-rated games in production"
      ]
    },
    {
      "id": "get_game_details",
      "name": "Get Game Details",
      "description": "Get full details for a pinball game including editions (Pro/Premium/LE with pricing), images, tags, description, and rules links.",
      "tags": ["games", "pinball", "details", "editions", "pricing"],
      "examples": [
        "Tell me about Godzilla pinball",
        "What editions does Jurassic Park come in?",
        "Show me the rules for Medieval Madness"
      ]
    },
    {
      "id": "get_random_game",
      "name": "Get Random Game",
      "description": "Get a random pinball game with full details. Different game every time. Great for discovery, recommendations, or 'game of the day' features.",
      "tags": ["games", "pinball", "random", "discovery"],
      "examples": [
        "Pick a random pinball game for me",
        "Surprise me with a pinball machine"
      ]
    },
    {
      "id": "get_pinball_stats",
      "name": "Get Database Stats",
      "description": "Get database statistics: total games, games in production, total manufacturers, total designers, average fun score, most rated game, and newest game.",
      "tags": ["stats", "metrics", "pinball", "database"],
      "examples": [
        "How many pinball games are in the database?",
        "What's the highest-rated game?"
      ]
    },
    {
      "id": "get_game_credits",
      "name": "Get Game Design Team",
      "description": "Get the design team for a pinball game — designer, artist, programmer, mechanical engineer, sound designer, animator, etc. Each credit includes the person's name and role.",
      "tags": ["games", "pinball", "credits", "design", "people"],
      "examples": [
        "Who designed Godzilla?",
        "Show me the team behind Jurassic Park"
      ]
    },
    {
      "id": "kineticist_log_play",
      "name": "Log a Play",
      "description": "Log a play of a pinball game for the authenticated user. Tracks date, location, score, and notes.",
      "tags": ["plays", "diary", "user", "tracking", "write"],
      "examples": [
        "Log that I played Godzilla today at Logan Arcade",
        "I played Jurassic Park yesterday and got 500 million"
      ]
    },
    {
      "id": "kineticist_toggle_ownership",
      "name": "Toggle Game Ownership",
      "description": "Mark a game as owned or no longer owned for the authenticated user. Tracks acquisition and removal details.",
      "tags": ["ownership", "collection", "user", "write"],
      "examples": [
        "Add Medieval Madness to my collection",
        "I sold my Jurassic Park"
      ]
    },
    {
      "id": "kineticist_toggle_want",
      "name": "Toggle Want-to-Play / Wishlist",
      "description": "Toggle the authenticated user's want-to-play or want-to-own flag for a game. Calling twice turns the flag off.",
      "tags": ["wishlist", "want-to-play", "user", "write"],
      "examples": [
        "Add Godzilla to my wishlist",
        "Mark Stranger Things as want-to-play"
      ]
    },
    {
      "id": "kineticist_set_fun_score",
      "name": "Set Fun Score",
      "description": "Set the authenticated user's fun score (1-100) for a game. Upserts — calling again overwrites.",
      "tags": ["rating", "fun-score", "review", "user", "write"],
      "examples": [
        "Rate Godzilla 92",
        "I give Medieval Madness a 95 out of 100"
      ]
    },
    {
      "id": "kineticist_undo_last_play",
      "name": "Undo Last Play",
      "description": "Delete the authenticated user's most recent play log for a game. Errors if there is no play to undo.",
      "tags": ["plays", "undo", "user", "write"],
      "examples": [
        "Undo my last Godzilla play",
        "I logged that play by accident, remove it"
      ]
    },
    {
      "id": "kineticist_toggle_favorite",
      "name": "Toggle Favorite",
      "description": "Toggle the authenticated user's favorite flag for a game. Calling twice removes the favorite.",
      "tags": ["favorite", "user", "write"],
      "examples": [
        "Mark Godzilla as a favorite",
        "Unfavorite Stranger Things for me"
      ]
    },
    {
      "id": "kineticist_delete_fun_score",
      "name": "Delete Fun Score",
      "description": "Delete the authenticated user's fun score for a game. The score recorded inside a written review is NOT removed by this — call kineticist_delete_review for that.",
      "tags": ["rating", "user", "write"],
      "examples": [
        "Remove my rating on Avatar",
        "I changed my mind, clear my Spider-Man score"
      ]
    },
    {
      "id": "kineticist_update_play_log",
      "name": "Update Play Log",
      "description": "Update an existing play log row owned by the authenticated user. Pass any subset of fields; omitted fields are left untouched.",
      "tags": ["plays", "edit", "user", "write"],
      "examples": [
        "Fix the date on play log abc-123",
        "Add a note to my last Godzilla play"
      ]
    },
    {
      "id": "kineticist_delete_play_log",
      "name": "Delete Play Log",
      "description": "Delete an existing play log row owned by the authenticated user (by play log id, not game id).",
      "tags": ["plays", "delete", "user", "write"],
      "examples": [
        "Delete play log abc-123",
        "Remove that bogus play I logged last month"
      ]
    },
    {
      "id": "kineticist_update_ownership_details",
      "name": "Update Ownership Details",
      "description": "Update purchase price, source, trade detail, trim, or sale price on the user's most-recent open ownership record for a game.",
      "tags": ["ownership", "edit", "user", "write"],
      "examples": [
        "Set my Godzilla purchase price to 8000",
        "Pin my James Bond ownership to the LE trim"
      ]
    },
    {
      "id": "kineticist_submit_review",
      "name": "Submit Review",
      "description": "Save the authenticated user's review (fun score 1-100 + optional written body) for a game. Upserts on (game, user).",
      "tags": ["review", "rating", "user", "write"],
      "examples": [
        "Rate Godzilla 92 with a quick note about the layout",
        "Save my Cosmic Princess review (88, 'best Sega in years')"
      ]
    },
    {
      "id": "kineticist_delete_review",
      "name": "Delete Review",
      "description": "Delete the authenticated user's review for a game. The fun score recorded via kineticist_set_fun_score is NOT removed by this.",
      "tags": ["review", "delete", "user", "write"],
      "examples": [
        "Delete my Avatar review",
        "Remove my written take on Star Wars"
      ]
    },
    {
      "id": "kineticist_get_my_state",
      "name": "Get My Engagement State",
      "description": "Get the authenticated user's engagement state for a game: owned, wishlist flags, play count, latest play, fun score, ownership details. Read-only — useful for verifying after a write.",
      "tags": ["user", "state", "verification", "library"],
      "examples": [
        "What's my play count for Godzilla?",
        "Have I rated Jurassic Park yet?"
      ]
    }
  ],
  "contact": {
    "email": "colin@kineticist.com",
    "url": "https://www.kineticist.com/contact"
  },
  "documentation": {
    "human": "https://www.kineticist.com/docs/api",
    "reference": "https://www.kineticist.com/docs/api/reference",
    "openapi": "https://www.kineticist.com/openapi.json",
    "llmsTxt": "https://www.kineticist.com/llms.txt"
  },
  "api": {
    "baseUrl": "https://www.kineticist.com/api/v1",
    "protocol": "REST",
    "auth": {
      "type": "bearer",
      "header": "Authorization: Bearer <key>",
      "signup": "https://www.kineticist.com/settings"
    },
    "rateLimits": {
      "model": "per-key, 3 tiers, enforced as burst + per-minute + per-day",
      "tiers": [
        { "name": "free", "burst": "10/s", "perMinute": 60, "perDay": 1000 },
        { "name": "builder", "burst": "20/s", "perMinute": 120, "perDay": 5000 },
        { "name": "partner", "burst": "30/s", "perMinute": 200, "perDay": 25000 }
      ],
      "notes": "All tiers are free during early access. New keys start on free. Email colin@kineticist.com for a higher ceiling."
    },
    "capabilities": ["read", "write"],
    "resources": [
      "games",
      "game-files",
      "stats",
      "user-library (plays, ownership, wishlist, fun scores)"
    ]
  },
  "packages": {
    "cli": {
      "name": "@kineticist/cli",
      "command": "pinball",
      "registry": "https://www.npmjs.com/package/@kineticist/cli",
      "install": "npm install -g @kineticist/cli"
    },
    "mcpServer": {
      "name": "@kineticist/mcp-server",
      "command": "kineticist-mcp",
      "registry": "https://www.npmjs.com/package/@kineticist/mcp-server",
      "install": "npx @kineticist/mcp-server",
      "transports": ["stdio", "streamable-http", "webmcp"],
      "httpEndpoint": "https://www.kineticist.com/api/mcp",
      "httpAuth": "bearer (same Kineticist API key as /api/v1/*)",
      "rateLimitNote": "MCP HTTP requests consume the per-key tier limit twice per tools/call — once at the /api/mcp route, once on the tool's internal /api/v1/* fetch. Free tier (1000/day) supports about 500 MCP calls/day.",
      "webmcpNote": "Every public page on www.kineticist.com registers tools via navigator.modelContext (Web Model Context API). Anonymous visitors get the read tools (search_pinball_games, get_game_details, find_locations_near_zip); signed-in visitors additionally get the write tools (log_play, toggle_owned, toggle_wishlist, set_fun_score, undo_last_play). In-page polyfill via @mcp-b/webmcp-polyfill so the API is reachable in browsers that haven't yet shipped native navigator.modelContext.",
      "clients": ["Claude Desktop", "Cursor", "ChatGPT", "any MCP-compatible client", "in-browser agents (WebMCP)"]
    }
  },
  "allowed": {
    "crawling": true,
    "training": "see /robots.txt and /llms.txt"
  }
}
