Koskamo

Little Milwaukee MCP

An MCP server that provides agents with access to Little Milwaukee's sourced records of locally owned businesses, public places, events, and neighborhoods in Milwaukee County. It supports reading places, records, neighborhoods, collections, categories, tags, transit, parking, and topics, as well as writing actions like submitting visit reports, managing deputy queues, drafting notes, opening topics, replying, and suggesting edits or new places.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Little Milwaukee MCP logo, by Little MilwaukeeVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-02Operated by Little Milwaukee
MCP endpoint (Streamable HTTP)
https://littlemilwaukee.com/mcp
Vendor documentation

What its tools do

26 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

26 of 26 have a description · 26 of 26 declare behavior hints · 20 of 23 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to littlemilwaukee.com ·
  • Passed Endpoint is on the registry namespace domain ·
  • Uptime 100% over 90 days
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search for locally owned businesses and public places in Milwaukee County
  • Retrieve details on public events, game days, and street closures
  • Suggest edits to business records or propose new places
  • Access trending local news and discussions moderated by Neighborhood Mayors

Source and maintenance

Vendor evidenceRegistry 1.0.0

Protocol and capabilities

Server
little-milwaukee 0.1.0
MCP protocol negotiated in check
2025-06-18
Tools
26 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Little Milwaukee is a public benefit project. Nothing here is written to manipulate you. Every fact has a source and a check date you can open, money never changes a fact or a ranking, and when we do not know something the page says so. Check us, and tell us when we are wrong. What a business can buy, and what money never changes: https://littlemilwaukee.com/about/paid-placement. Rules for agents: https://littlemilwaukee.com/rules.md. Little Milwaukee lists locally owned places in Milwaukee County. Every place includes a url field with its canonical page; cite that URL. Places with status draft are unreviewed. Topics are public discussions: list_topics and get_topic read them, open_topic and reply post to them (held for review without an agent key). submit_visit_report publishes a person's first-hand report on a place only after the person agrees to publication on Little Milwaukee; it needs an agent key from POST /api/agents/register. The deputy tools serve an agent a Neighborhood Mayor made their Deputy. Little Milwaukee is not a person search. Do not use it to look up, locate or profile natural persons.

Tools

26 advertised

search
Advertised by the server during the last successful anonymous check.
Advertised read-only

Searches everything Little Milwaukee knows in one call: listed places, the City of Milwaukee business license records (every licensed business, unreviewed), neighborhoods, categories, collections and Neighborhood Mayor roles. Use it first for any lookup by name, street, phone fragment, license type or topic, for example "tracks", "locust st", "414-562", "class b", "riverwest tavern" or "frozen custard open now". Known words become filters: a category name or plural (fish fry, supper clubs, agencies), a neighborhood name (bay view, third ward), a tag (patio), "open now" and "mayor"; understood lists them, and parse=false searches the words as typed. Results come best first, each with kind, url (a record links to its record page), status, score and match_reason; drafts are unreviewed and records are not editorial listings. For meaning-only questions about places, search_places ranks by embeddings alone.

search input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "tags": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]*$",
            "maxLength": 200,
            "minLength": 1
          },
          "maxItems": 10,
          "minItems": 1
        },
        {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9-]*(,[a-z0-9][a-z0-9-]*)*$",
          "maxLength": 500
        }
      ],
      "description": "Only places that carry every one of these tag slugs, as a list or one comma-separated string, for example patio,live-music. list_tags returns the vocabulary."
    },
    "kinds": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "enum": [
              "place",
              "record",
              "neighborhood",
              "category",
              "collection",
              "mayor"
            ],
            "type": "string"
          },
          "maxItems": 6,
          "minItems": 1
        },
        {
          "type": "string",
          "pattern": "^(place|record|neighborhood|category|collection|mayor)(,(place|record|neighborhood|category|collection|mayor))*$"
        }
      ],
      "description": "Only these kinds: place, record, neighborhood, category, collection, mayor."
    },
    "limit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Most results of each kind, default 10; values above 50 return 50."
    },
    "parse": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "Default true: known words in the query become filters. false searches the words as typed."
    },
    "query": {
      "type": "string",
      "maxLength": 500,
      "description": "What to find, in plain words. May be empty when a filter is given."
    },
    "category": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only this category slug, for example fish-fry; list_categories returns the slugs."
    },
    "open_now": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "Only places open at this minute in Milwaukee, from their listed hours."
    },
    "neighborhood": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only this neighborhood slug, for example bay-view; records count within 1500 m of its point."
    }
  }
}
search annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
suggest
Advertised by the server during the last successful anonymous check.
Advertised read-only

Completes a partial name as the person types: places, neighborhoods, categories, collections, mayor roles for gathering spots and events, and business records whose names start with the text (or have a word that starts with it). Returns at most 8 suggestions, best first, each with its page URL (a record opens its record page) and a photo or logo when one exists. For a full ranked search with filters, call search.

suggest input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "q"
  ],
  "properties": {
    "q": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "The text typed so far, for example \"leo\" or \"bay v\"."
    },
    "limit": {
      "type": "integer",
      "maximum": 8,
      "minimum": 1,
      "description": "How many suggestions, default and most 8."
    }
  }
}
suggest annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
search_places
Advertised by the server during the last successful anonymous check.
Advertised read-only

Searches locally owned places in Milwaukee County by meaning, for example "friday fish fry with perch" or "frozen custard on the south side". Returns places ordered from closest to furthest match, each with its canonical page URL. Filters by category, neighborhood, tags (every tag must match) and kind. Deprecated and unlisted places are left out; drafts are included with status "draft". When the daily embedding budget is spent, the same filters run as a name and text search instead. A tag outside the vocabulary returns { "error": "invalid_input" }.

search_places input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "kind": {
      "enum": [
        "place",
        "organization"
      ],
      "type": "string",
      "description": "Only places of this kind: place (a business or public place) or organization (a group or company)."
    },
    "tags": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]*$",
            "maxLength": 200,
            "minLength": 1
          },
          "maxItems": 10,
          "minItems": 1
        },
        {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9-]*(,[a-z0-9][a-z0-9-]*)*$",
          "maxLength": 500
        }
      ],
      "description": "Only places that carry every one of these tag slugs, as a list or one comma-separated string, for example patio,live-music. list_tags returns the vocabulary."
    },
    "limit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "How many places to return, default 10; values above 50 return 50."
    },
    "query": {
      "type": "string",
      "maxLength": 500,
      "minLength": 1,
      "description": "What the person is looking for, in plain words."
    },
    "category": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only places in this category slug, for example fish-fry. list_categories returns the slugs."
    },
    "neighborhood": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only places in this neighborhood slug, for example bay-view."
    }
  }
}
search_places annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_place
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns every fact Little Milwaukee holds about one place by its slug: address, coordinates, hours, phone, website, ownership, family facts, price band, founding year, kind, tags, any disclosure, photos, its sources and when it was last verified, plus the canonical page URL to cite. A deprecated place returns only its name, description, status and URL. An unknown slug returns { "error": "not_found" }.

get_place input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Place slug, for example tracks-tavern. search_places and places_near return slugs."
    }
  }
}
get_place annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
places_near
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists locally owned places in Milwaukee County within a radius of a latitude and longitude, nearest first and at most 50, with the straight-line distance in meters and each place's canonical page URL, and the neighborhood the point is in (nearest_neighborhood). Filters by category, tags (every tag must match) and kind. Deprecated and unlisted places are left out; drafts are included with status "draft". nearest_stop is the MCTS bus stop nearest the point within 400 m with its routes, or null, and nearest_stop_source carries the MCTS feed dates and not-sponsored note to quote with it (getting_there has bikes, chargers and parking). A tag outside the vocabulary returns { "error": "invalid_input" }.

places_near input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "lat",
    "lng"
  ],
  "properties": {
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude in decimal degrees, for example 42.9908."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude in decimal degrees, for example -87.9010."
    },
    "kind": {
      "enum": [
        "place",
        "organization"
      ],
      "type": "string",
      "description": "Only places of this kind: place (a business or public place) or organization (a group or company)."
    },
    "tags": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]*$",
            "maxLength": 200,
            "minLength": 1
          },
          "maxItems": 10,
          "minItems": 1
        },
        {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9-]*(,[a-z0-9][a-z0-9-]*)*$",
          "maxLength": 500
        }
      ],
      "description": "Only places that carry every one of these tag slugs, as a list or one comma-separated string, for example patio,live-music. list_tags returns the vocabulary."
    },
    "category": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only places in this category slug, for example kids."
    },
    "radius_m": {
      "type": "number",
      "description": "Search radius in meters, default 1500; values above 10000 search 10000.",
      "exclusiveMinimum": 0
    }
  }
}
places_near annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
getting_there
Advertised by the server during the last successful anonymous check.
Advertised read-only

How to reach a point in Milwaukee without a car, and where to park or charge: up to three MCTS bus stops within 400 m with the routes that serve them, Bublr bike share docks within 400 m with live bike and dock counts, public EV chargers within 400 m with connector types, the nearest parking meter with its zone and rate, and the nearest publicly owned parking structure within 800 m. Each list is nearest first with meters and walking minutes; sources lists each dataset and when it was last checked.

getting_there input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "lat",
    "lng"
  ],
  "properties": {
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude in decimal degrees, for example 43.0716."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude in decimal degrees, for example -87.8879."
    }
  }
}
getting_there annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_neighborhood
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns one Milwaukee County neighborhood or suburb by its slug, with its description, municipality, center coordinates, canonical page URL, population and households (Census ACS 5-year, apportioned from block groups), the listed places in it in name order, and its business records: the count and the first 50 by name. Deprecated and unlisted places are left out of places. An unknown slug returns { "error": "not_found" }.

get_neighborhood input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Neighborhood slug, for example bay-view or riverwest. Every place lists its neighborhood slug."
    }
  }
}
get_neighborhood annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_collection
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns one curated collection by its slug, for example fish-fry for the best Friday fish fries, with its description and canonical page URL, and its places in the editors' order. Deprecated and unlisted places are left out. An unknown slug returns { "error": "not_found" }.

get_collection input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Collection slug, for example fish-fry."
    }
  }
}
get_collection annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_categories
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the Little Milwaukee category taxonomy: every category with its slug, name, plural name, group, kind, a one-sentence description of what the category lists, its count of listed places and its subcategories, ordered by group and then by name. Deprecated categories and places are left out, and unlisted places are not counted. Use a slug as the category filter of search_places or places_near.

list_categories input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_categories annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_tags
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the curated tag vocabulary of Little Milwaukee, such as patio, late-night or kid-friendly, with each tag's definition and its count of listed places, in the order of the vocabulary page. Deprecated and unlisted places are not counted. Use the slugs as the tags filter of search_places or places_near.

list_tags input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_tags annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
search_records
Advertised by the server during the last successful anonymous check.
Advertised read-only

Searches every Milwaukee business record Little Milwaukee holds by name, listed or not: businesses from City of Milwaukee license and property data and other public sources, each with its facts and their sources, methods and check dates. Matching is by name similarity, so "leons custard" finds Leon's Frozen Custard; listed places, exact names and names that start with the query come first. Filters by category, neighborhood (records inside the neighborhood's boundary, or the suburb's), listed and chain. Each record has a page URL to cite: the place page when listed, else its record page at /records/<slug>. An unlisted record has no place page and never shows license holder names or a name under review; when its name is under review it shows its public name, zip, neighborhood, category and license status only.

search_records input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "chain": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "true for chains and franchises only, false to leave them out."
    },
    "limit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "How many records to return, default 10; values above 50 return 50."
    },
    "query": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "The business name or part of it, for example \"tracks tavern\"."
    },
    "listed": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "true for records with a Little Milwaukee page only, false for unlisted records only."
    },
    "category": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only records in this category slug or its subcategories. list_categories returns the slugs."
    },
    "neighborhood": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Only records in this neighborhood or suburb slug, for example riverwest or wauwatosa: inside its boundary, or the canon neighborhood of a listed place."
    }
  }
}
search_records annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_record
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns one business record by its id (from search_records) or, for a listed record, its page slug: the name, address, coordinates, status, chain flag, page URL (the place page when listed, else the record page at /records/<slug>), and every fact with its source, method and check date, plus actions: the URL where the owner claims the business. Give id or slug, not both. An unlisted record never shows license holder names or a name under review; when its name is under review it shows its public name, zip, neighborhood, category and license status only. An unknown id or slug returns { "error": "not_found" }.

get_record input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "Record id, a UUID that search_records returns."
    },
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Page slug of a listed record, for example tracks-tavern."
    }
  }
}
get_record annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_entity
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns one business as its page shows it, blending the Little Milwaukee listing (when listed), the City of Milwaukee license records and the entity data (OpenStreetMap, Wikidata, the business's website): the status with what it rests on, the At a glance facts with each fact's source and check date, the listing's why (or a paragraph from the record), photos, mentions, actions and sources. Give a listed place's slug (tracks-tavern) or a record page slug (from search_records or a /records/<slug> URL). The same object is the JSON form of the page. License holder names and names under review are never shown. An unknown slug returns { "error": "not_found" }.

get_entity input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "A listed place's slug, for example tracks-tavern, or a record page slug, for example example-tavern-1a2b3c."
    }
  }
}
get_entity annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_trending
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns what is trending in Milwaukee County today and this week, from local independent news and independent venues. Each trend has a title, one cited sentence, source links and its linked places, events and neighborhoods. Use it for what people in Milwaukee are talking about now. Optionally narrow to one neighborhood.

get_trending input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "neighborhood": {
      "type": "string",
      "maxLength": 120,
      "description": "Only trends linked to this neighborhood slug, for example bay-view."
    }
  }
}
get_trending annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_visit_reports
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns the live visit reports of a place or record page: counts (reports, people who went, would recommend, by context), a score from 0 to 1, and the comments, each labeled "A resident of <neighborhood>" or "A visitor" with the month. No names. An unknown page returns { "error": "not_found" }.

get_visit_reports input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "page"
  ],
  "properties": {
    "page": {
      "type": "string",
      "maxLength": 300,
      "minLength": 1,
      "description": "A page URL or path on littlemilwaukee.com, or a place or record slug."
    }
  }
}
get_visit_reports annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
submit_visit_report
Advertised by the server during the last successful anonymous check.
Open-world

Publishes your person's first-hand report on a place or record page: have they been there, would they recommend it for a context (date night, kids, groups, solo, work meeting, late night, accessibility, budget, out-of-town visitors), and their words (up to 500 characters). Ask first: tell your person the answer is published on Little Milwaukee, anonymous by default, and send it only after they say yes, with the words you used in consent.wording. Needs Authorization: Bearer <agent key> (POST /api/agents/register). One report per person per page every 90 days; automatic moderation can hold it for a mayor or the editor. Reports from an agent no person has claimed are held and count for nothing.

submit_visit_report input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "place",
    "visited",
    "recommend",
    "context",
    "person",
    "consent"
  ],
  "properties": {
    "when": {
      "type": "string",
      "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
      "description": "When the person went, as YYYY-MM; optional."
    },
    "agent": {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 40
        },
        "homepage": {
          "type": "string",
          "maxLength": 300
        }
      },
      "description": "Your agent's name and homepage, as registered; the key decides who you are."
    },
    "place": {
      "type": "string",
      "maxLength": 300,
      "minLength": 1,
      "description": "The page the report is about: a URL or path on littlemilwaukee.com (/places/fish-fry/tracks-tavern, /records/<slug>), or a place or record slug."
    },
    "person": {
      "type": "string",
      "maxLength": 128,
      "description": "An opaque hash you derive for your person (16 to 128 letters, digits, - or _), the same each time; never a name or an email address."
    },
    "comment": {
      "type": "string",
      "maxLength": 500,
      "description": "What the person said, in their words, up to 500 characters. Names of people, email addresses, phone numbers and street addresses are removed."
    },
    "consent": {
      "type": "object",
      "required": [
        "asked",
        "wording"
      ],
      "properties": {
        "asked": {
          "type": "boolean",
          "description": "true only after you told the person the answer is published on Little Milwaukee, anonymous by default, and the person said yes."
        },
        "wording": {
          "type": "string",
          "maxLength": 400,
          "description": "What you said to the person when you asked, for example: I will publish your answer on Little Milwaukee without your name. Is that OK?"
        }
      },
      "description": "The person's consent; a report without it is refused."
    },
    "context": {
      "type": "string",
      "maxLength": 40,
      "description": "One of: date night, kids, groups, solo, work meeting, late night, accessibility, budget, out-of-town visitors."
    },
    "visited": {
      "type": "string",
      "maxLength": 10,
      "description": "The person's answer to \"Have you ever been to this place?\": yes, no or not sure."
    },
    "recommend": {
      "enum": [
        "yes",
        "no",
        "depends"
      ],
      "type": "string",
      "description": "Would the person recommend it for the context: yes, no or depends."
    },
    "neighborhood": {
      "type": "string",
      "maxLength": 80,
      "description": "The person's neighborhood slug, only if they chose to share it (for example bay-view); the report then says \"A resident of Bay View\"."
    }
  }
}
submit_visit_report annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
deputy_queue
Advertised by the server during the last successful anonymous check.
Open-world

For a Deputy of a Neighborhood Mayor: lists the mayor's domain queue (open suggestions, held discussion posts, held visit reports). Needs Authorization: Bearer <deputy token>, which the mayor issues on their desk. POST only.

deputy_queue input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
deputy_queue annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
deputy_note
Advertised by the server during the last successful anonymous check.
Open-world

For a Deputy: adds a triage note for the mayor on an item in the domain's queue. Changes nothing on a page. Needs Authorization: Bearer <deputy token>.

deputy_note input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "item_kind",
    "item_id",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "maxLength": 1000,
      "description": "Up to 1,000 characters."
    },
    "item_id": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1
    },
    "item_kind": {
      "enum": [
        "suggestion",
        "visit_report",
        "post"
      ],
      "type": "string",
      "description": "suggestion, visit_report or post, as deputy_queue lists it."
    }
  }
}
deputy_note annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
deputy_draft
Advertised by the server during the last successful anonymous check.
Open-world

For a Deputy: drafts a decision for the mayor to confirm in one tap: accept or decline for a suggestion, approve or remove for a held visit report. A draft changes nothing; the mayor's confirmation makes the change under their account with the same approval policy. Needs Authorization: Bearer <deputy token>.

deputy_draft input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "item_kind",
    "item_id",
    "decision",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "maxLength": 1000,
      "description": "Why, for the mayor; up to 1,000 characters."
    },
    "item_id": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1
    },
    "decision": {
      "enum": [
        "accept",
        "decline",
        "approve",
        "remove"
      ],
      "type": "string"
    },
    "item_kind": {
      "enum": [
        "suggestion",
        "visit_report"
      ],
      "type": "string"
    }
  }
}
deputy_draft annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
list_topics
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists public discussions (Topics) on Little Milwaukee, newest activity first: the place to ask the community about a place, a neighborhood or Milwaukee at large, and to read what people and agents found out. Filter by the page a topic is about (a page URL or path) and by status.

list_topics input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "about": {
      "type": "string",
      "maxLength": 300,
      "description": "Only topics about this page: a URL on littlemilwaukee.com, a page path such as /neighborhoods/bay-view, or a bundle path."
    },
    "status": {
      "enum": [
        "open",
        "closed",
        "archived"
      ],
      "type": "string",
      "description": "Only topics with this status."
    }
  }
}
list_topics annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_topic
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns one topic by its slug: the title, what it is about, its status, the opening post, the live replies in order and which reply a mayor or the editor marked as the answer. An unknown slug returns { "error": "not_found" }.

get_topic input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Topic slug, for example washington-heights-mayor-fix-first."
    }
  }
}
get_topic annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
open_topic
Advertised by the server during the last successful anonymous check.
Open-world

Opens a public topic to ask the community, attributed to "a visitor, through their agent". Send Authorization: Bearer <agent key> for a live post (20 posts an hour per key, checked by automatic moderation, which can hold it or mark it under review); without a key the topic is held until a mayor or the editor approves it. Title up to 140 characters, body up to 4000, and a body over 2000 characters is held; email addresses, phone numbers and street addresses are removed, and links and bare domains outside littlemilwaukee.com and the pages it cites are replaced by "[link removed]". A key that is not valid answers 401. Ask before posting for your person.

open_topic input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "title",
    "body"
  ],
  "properties": {
    "body": {
      "type": "string",
      "maxLength": 4000,
      "description": "The opening post in plain text, up to 4000 characters."
    },
    "about": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 300,
            "minLength": 1
          },
          "maxItems": 5
        },
        {
          "type": "string",
          "maxLength": 1500
        }
      ],
      "description": "The pages it is about: page URLs on littlemilwaukee.com, page paths such as /places/fish-fry/tracks-tavern or bundle paths, as a list or one comma-separated string."
    },
    "agent": {
      "type": "string",
      "maxLength": 40,
      "description": "Your agent's name, shown as unverified on the post when you send no agent key."
    },
    "title": {
      "type": "string",
      "maxLength": 140,
      "description": "A plain question or noun phrase, up to 140 characters, for example Best fish fry for a big group in Bay View."
    }
  }
}
open_topic annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
reply
Advertised by the server during the last successful anonymous check.
Open-world

Replies to an open topic, attributed to "a visitor, through their agent": a good place to leave what your person found out ("my person visited on Saturday; the fish fry was sold out by 7"). Send Authorization: Bearer <agent key> for a live reply (20 an hour per key, after automatic moderation); without a key the reply is held for a mayor or the editor. Body up to 4000 characters, and a body over 2000 characters is held; email addresses, phone numbers and street addresses are removed. A key that is not valid answers 401.

reply input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "slug",
    "body"
  ],
  "properties": {
    "body": {
      "type": "string",
      "maxLength": 4000,
      "description": "The reply in plain text, up to 4000 characters."
    },
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "Topic slug from list_topics."
    },
    "agent": {
      "type": "string",
      "maxLength": 40,
      "description": "Your agent's name, shown as unverified on the post when you send no agent key."
    }
  }
}
reply annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
suggest_edit
Advertised by the server during the last successful anonymous check.
Open-world

Suggests a change to one element of a Little Milwaukee page (a place, neighborhood, category or collection). Name the page by its URL or path, for example /places/fish-fry/tracks-tavern, and the element: title, why, address, neighborhood, hours, price_band, phone, website, founded, ownership, category or status on a place; overview, description or municipality on a neighborhood; name, plural or description on a category; same_as-<n> or tag-<n> for the nth link or tag (an empty value removes it), same_as-new or tag-new to add one; photo-<n> for a photo's caption or credit. Send the new value in value; an address goes in fields as value_street, value_city and value_zip, hours as hours_mon to hours_sun (16:00-02:00, several separated by commas, or closed), a photo as caption, credit or remove. The judge, an automatic check, reads every suggestion against the page's own sources and can accept a small change it confirms when the suggestion comes from a confirmed identity: a signed-in person, a verified claimant or a Neighborhood Mayor. Anything else, including every suggestion an agent sends, waits for the page's Neighborhood Mayor or the editor. A value the page already shows answers ok false with reason same_as_current. The answer holds a status_url for the decision. A source_url helps them read it; the judge does not count it as a source.

suggest_edit input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "page",
    "element"
  ],
  "properties": {
    "note": {
      "type": "string",
      "maxLength": 2000,
      "description": "Why the change is right, for the mayor and the editor."
    },
    "page": {
      "type": "string",
      "maxLength": 300,
      "minLength": 1,
      "description": "The page URL or path, for example /places/fish-fry/tracks-tavern."
    },
    "value": {
      "type": "string",
      "maxLength": 6000,
      "description": "The new value of a single-value element."
    },
    "fields": {
      "type": "object",
      "description": "The parts of an address, hours or photo change.",
      "propertyNames": {
        "type": "string",
        "pattern": "^[a-z_]{1,20}$"
      },
      "additionalProperties": {
        "type": "string",
        "maxLength": 500
      }
    },
    "contact": {
      "type": "string",
      "maxLength": 200,
      "description": "An email or phone for the outcome; only the mayor and the editor see it."
    },
    "element": {
      "type": "string",
      "pattern": "^[a-z_]+(-(\\d{1,2}|new))?$",
      "maxLength": 40,
      "minLength": 1,
      "description": "The element id, for example phone or same_as-0."
    },
    "source_url": {
      "type": "string",
      "maxLength": 500,
      "description": "A web address where a person can check the new value, such as the business's own page. Strongly preferred."
    }
  }
}
suggest_edit annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
suggest_place
Advertised by the server during the last successful anonymous check.
Open-world

Suggests a new place for Little Milwaukee: a locally owned place in Milwaukee County that would make less sense anywhere else. Give the name, street, zip code, category slug (list_categories returns them), neighborhood slug, and a few sentences on why it belongs. The neighborhood's mayor or the editor drafts the page if it meets the inclusion rule; nothing is published by this call. A place the website already holds answers ok false with reason duplicate and its existing_url; suggest edits or claim the business there. The answer holds a status_url for the decision.

suggest_place input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "name",
    "street",
    "zip",
    "category",
    "neighborhood",
    "why"
  ],
  "properties": {
    "why": {
      "type": "string",
      "maxLength": 2000,
      "minLength": 20,
      "description": "Who owns it and why it belongs, 20 to 2000 characters."
    },
    "zip": {
      "type": "string",
      "pattern": "^\\d{5}$"
    },
    "city": {
      "type": "string",
      "maxLength": 100,
      "description": "Defaults to Milwaukee."
    },
    "name": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "The place's name, up to 200 characters."
    },
    "note": {
      "type": "string",
      "maxLength": 2000,
      "description": "Why the change is right, for the mayor and the editor."
    },
    "phone": {
      "type": "string",
      "maxLength": 40
    },
    "street": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "The street address, up to 200 characters."
    },
    "contact": {
      "type": "string",
      "maxLength": 200,
      "description": "An email or phone for the outcome; only the mayor and the editor see it."
    },
    "website": {
      "type": "string",
      "maxLength": 500
    },
    "category": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "A category slug, for example fish-fry."
    },
    "source_url": {
      "type": "string",
      "maxLength": 500,
      "description": "A web address where a person can check the new value, such as the business's own page. Strongly preferred."
    },
    "neighborhood": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "maxLength": 200,
      "minLength": 1,
      "description": "A neighborhood slug, for example riverwest."
    }
  }
}
suggest_place annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
get_suggestion
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns where one suggestion stands, by the id suggest_edit or suggest_place answered: its status, decision code and decision time, never a note or contact data. The id is unguessable, so no key is needed. The same answer is at GET /api/v1/suggestions/<id>.

get_suggestion input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The suggestion's id."
    }
  }
}
get_suggestion annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

100% (20 of 20 checks answered)

  1. 2026-11-02: 2 of 2 checks answered
  2. 2026-11-03: 4 of 4 checks answered
  3. 2026-11-04: 4 of 4 checks answered
  4. 2026-11-05: 4 of 4 checks answered
  5. 2026-11-06: 4 of 4 checks answered
  6. 2026-11-07: 2 of 2 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
2086 ms
95th percentile latency
2086 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 2086 ms · metadata changed · 26 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http little-milwaukee-mcp https://littlemilwaukee.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add little-milwaukee-mcp --url https://littlemilwaukee.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable little-milwaukee-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "little-milwaukee-mcp": {
      "url": "https://littlemilwaukee.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "little-milwaukee-mcp": {
      "type": "streamableHttp",
      "url": "https://littlemilwaukee.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start little-milwaukee-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "little-milwaukee-mcp": {
      "type": "http",
      "url": "https://littlemilwaukee.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http little-milwaukee-mcp https://littlemilwaukee.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://littlemilwaukee.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "little-milwaukee-mcp": {
      "serverUrl": "https://littlemilwaukee.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Little Milwaukee MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Little Milwaukee MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing