onthecheap-mcp
This server provides read-only access to free and cheap events, articles, and deals across 14 US cities in the On the Cheap network. No credentials are required, but a site key is needed for each query (no default city).
List events for a specific day: Get everything happening in a city on a given date, including time, price, and venue. Filter to free-only listings. (Not available for the national site.)
Browse a month's event overview: See a day-by-day breakdown of event counts and previews for an entire month. (Not available for the national site.)
Search articles and deals: Search by keyword, category, location, and date range. Expired/retired deals are excluded by default but can be included.
Fetch a full article: Retrieve a complete article by its ID, slug, or URL, in either readable plain text or raw HTML.
List categories: Get all topic categories (kids, music, food, festivals, art, etc.) with IDs for filtering searches.
List locations/neighborhoods: Get geographic sub-areas within a city with IDs for filtering searches.
List all supported cities: See every city in the network and its
sitekey. Coverage includes Charlotte, Denver, Atlanta, Chicago, Columbus, Seattle, Kansas City, Miami, Orlando, Portland, Richmond, Southern Maine, Raleigh/Durham/Chapel Hill, plus a national deals hub.Health check a site: Verify that a specific city's site is reachable and its API is responding.
Provides tools to access and search event listings, articles, and categories from the On the Cheap network of WordPress-based local guides across 14 US cities.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@onthecheap-mcpWhat's free in Charlotte this weekend?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
onthecheap-mcp
MCP server for the On the Cheap network — local guides to free and cheap things to do across 14 US cities. Daily event listings with times, prices and venues, plus a searchable archive of deals and guides.
Developed and maintained by AI (Claude Code). Use at your own discretion.
No credentials required. Every site is public, so the server reads them server-side over plain HTTPS. There is nothing to configure beyond which city you want, and no browser extension involved.
Install
npx onthecheap-mcpOr as a Claude Code plugin:
/plugin marketplace add chrischall/onthecheap-mcp
/plugin install onthecheap-mcpRelated MCP server: valet-parking-directory
Choosing a city
One server reads the whole network. Every tool takes a site argument
naming the city to read — there is no default and no configuration step:
Key | Site | Area |
| Charlotte On The Cheap | Charlotte, NC |
| Mile High on the Cheap | Denver, CO |
| Atlanta on the Cheap | Atlanta, GA |
| Chicago on the Cheap | Chicago, IL |
| Columbus on the Cheap | Columbus, OH |
| Greater Seattle on the Cheap | Seattle–Tacoma |
| Kansas City on the Cheap | Kansas City |
| South Florida on the Cheap | Miami / Broward / Palm Beach |
| Orlando on the Cheap | Orlando, FL |
| Portland Living on the Cheap | Portland, OR |
| RVA on the Cheap | Richmond, VA |
| Southern Maine on the Cheap | Southern Maine |
| Triangle on the Cheap | Raleigh / Durham / Chapel Hill |
| Living On The Cheap | US-wide deals (no local events calendar) |
Common aliases work too — milehigh, raleigh, rva, kc, southflorida.
otc_list_sites reports the same list.
site is required rather than defaulted on purpose: a server that quietly fell
back to one city would answer a question about Denver with Charlotte's data and
give no sign anything was wrong. An unknown key is refused with the valid ones
listed.
Tools
All tools are read-only. Every tool except otc_list_sites takes a required
site argument. The two event tools reject national, which has no local
events calendar — it is still searchable via the other tools.
Tool | What it does |
| Everything on a given day — time, price, venue. |
| Day-by-day counts for a month, to find the busiest days. Each day's list is a preview; |
| Search articles by text, category, location and date range. Returns slim summaries by default. |
| One article in full, as readable text or raw HTML. Accepts an id, slug, or URL. |
| Category ids and post counts, for filtering searches by topic. |
| Local area ids and post counts, for filtering geographically. |
| The cities in the network and their |
| Confirm one site is reachable. |
Examples
What's free in Charlotte this Saturday?
Find kids' events in Lake Norman in August
Compare free things to do in Denver and Portland next weekend
Two things worth knowing
Retired deals are excluded by default. Each site parks expired offers in an
expired category, so searches skip them and you don't get deals that no
longer exist. Pass include_expired: true to search the archive. The category's
id differs on every site, so it's resolved by slug at request time — a
hardcoded id silently disables the filter elsewhere.
Category and location ids are per-site. Each site is a separate WordPress
install, so id 13 is a different category on every one of them. Resolve ids
against the same site you then search — an id borrowed from another city will
filter to something unrelated rather than error.
Month overviews are previews, with honest counts. The calendar shows at
most four listings per day. otc_events_month_overview reports each day's
true total alongside the preview — call otc_list_events with a date for the
complete schedule.
Configuration
None. The city is a per-call site argument, not an environment variable, so
there is nothing to set up before use.
Development
npm install
npm test
npm run buildSee docs/OTC-API.md for the verified data surface,
including the events calendar's US M-D-YYYY date routing (an ISO date is
silently parsed as 1970), the month-view truncation, and why term ids are never
hardcoded.
License
MIT
Available Tools
8 toolsotc_events_month_overviewOverview of a city’s events across a monthARead-onlyIdempotent
Day-by-day overview of a whole month from an "on the Cheap" city’s events calendar: for each day, the true number of listings and a short preview of them. Pass the site key for the city (see otc_list_sites). The calendar shows at most four listings per day, so events is a preview while total is the real count — call otc_list_events for a specific date to get that day's complete schedule. The national hub has no local calendar and is not a valid site here. Use this to find the busiest days or scan a month at a glance. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. | |
| month | No | Month to summarise, as ISO YYYY-MM. Defaults to the current month. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, openWorldHint, idempotentHint), the description discloses critical behavioral traits: 'events is a preview while total is the real count,' the calendar shows at most four listings per day, and the national hub has no local calendar. It also clarifies the read-only nature, matching annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each serving a distinct purpose: purpose, parameter instruction, behavioral caveat with alternative, and use-case summary. The information is front-loaded with the core purpose and the critical preview/total distinction appears early. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description sufficiently explains the response structure ('for each day, the true number of listings and a short preview') and clarifies the meaning of the fields. It covers limitations, defaults implicitly via schema, and provides routing to the correct sibling for deeper detail. An agent has everything needed to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both site and month fully documented including aliases, pattern, and default. The description's mention of 'Pass the site key' adds no substantial meaning beyond the schema, so the baseline of 3 applies. It does reinforce cross-tool reference to otc_list_sites, but that is already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Day-by-day overview of a whole month from a city’s events calendar.' It clearly differentiates from the sibling otc_list_events by noting the month-level aggregation and explicitly pointing to the alternative for a single day's full schedule. The scope and output shape ('true number of listings and a short preview') are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use this to find the busiest days or scan a month at a glance.' It also states when not to use it, pointing users to otc_list_events for a specific date and warning that the national hub is not a valid site. It further directs users to otc_list_sites for obtaining the site key, covering both prerequisites and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_get_postGet an On the Cheap articleARead-onlyIdempotent
Fetch one "on the Cheap" article in full by numeric id, slug, or full URL. Pass the site key for the city the article belongs to — an id or slug from one site will not resolve on another, and a full URL must match the site you name. Returns the article text as readable plain text by default; set format to "html" for the original markup. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| post | Yes | Post id, slug, or full article URL | |
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. | |
| format | No | Body format: readable text (default) or raw HTML |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only, idempotent, and open-world, and the description repeats read-only, which is redundant. However, it adds meaningful behavioral details beyond annotations: site-scoped resolution, the requirement that a URL match the named site, and the default plain-text output with optional HTML.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted verbiage: the action comes first, then the critical site-scoping constraint, then the output format option. The word 'Read-only' is redundant with annotations but harmless and not at the cost of conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only fetch operation with three parameters and no output schema, the description covers the essential call behavior: identifiers, required site, cross-site matching constraints, and the return format and its switch. Nothing critical is missing for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining that ids and slugs are site-specific and will not resolve on another site, and that a full URL must match the site passed. This supplements the schema's parameter descriptions rather than repeating them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Fetch') and a precise resource ('one On the Cheap article'), and defines the accepted identifiers (numeric id, slug, or full URL). This clearly distinguishes it from sibling tools like otc_search_posts, which search rather than fetch a single article by identifier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational context: a site key is required, must match the article's city, and a full URL must match the named site. It does not explicitly mention when to choose this tool over a sibling, but the contrast between fetching one known article and searching is implied strongly enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_healthcheckCheck an On the Cheap site’s connectivityARead-onlyIdempotent
Verify one "on the Cheap" site is reachable and its public API is responding. Pass the site key for the city (see otc_list_sites). The sites need no credentials, so this checks connectivity only. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds the cruial detail that no credentials are required and that the tool checks only connectivity, not deeper functionality. This aligns with and extends the annotation context without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: purpose, parameter guidance, and credential context. The description is front-loaded with the action and avoids redundant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter health check, the description plus rich annotations and a detailed schema cover purpose, invocation, and safety. It does not describe the return format, but there is no output schema and the nature of the tool makes this gap minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already explains the site parameter, its requiredness, valid values, aliases, and referral to otc_list_sites. The description adds only a brief 'pass the site key' reminder without new semantic meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Verify') and resource ('one on the Cheap site... reachable and its public API is responding'). It clearly distinguishes the healthcheck operation from sibling tools that search, get, or list content. No ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains that the caller must pass the site key for the city and points to otc_list_sites for the full list. It also clarifies that this is connectivity-only and needs no credentials. It does not explicitly state when not to use it, but the context is clear for a read-only health check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_list_categoriesList a city’s article categoriesARead-onlyIdempotent
List one "on the Cheap" site's article categories with their ids and post counts (kids, music, food, festivals, art, museums, and so on). Pass the site key for the city (see otc_list_sites). Use an id to filter otc_search_posts by topic — ids are per-site, so use them only against the site they came from. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this read-only, idempotent, and open-world, so the safety profile is covered. The description adds meaningful behavioral context: category ids are per-site and must only be used against the originating site, and results include post counts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences front-load the result and then give parameter and cross-tool guidance. The final 'Read-only.' is redundant with the readOnlyHint annotation, so it does not fully earn its place, but the overall size is appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one fully documented parameter and no output schema, the description supplies the key return fields ('ids and post counts') and the cross-tool relationships needed to use the result correctly. It does not specify the exact response shape or pagination, but for a simple read-only list this is not a serious gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the site property is fully documented with valid values and aliases, so the baseline applies. The description repeats the instruction to pass the site key and points to otc_list_sites, but adds no new parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description pairs the verb 'List' with a concrete resource ('one "on the Cheap" site's article categories') and specifies returned data ('ids and post counts'). It also separates itself from siblings by explaining the site key comes from otc_list_sites and category ids feed otc_search_posts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It tells you to pass the site key for the city and points to otc_list_sites for valid keys, routing a required prerequisite. It also explicitly frames the output as a way to filter otc_search_posts by topic, so an agent knows when and why to call this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_list_eventsList a city’s events for a dayARead-onlyIdempotent
List everything happening in an "on the Cheap" city on a given date, from that site’s events calendar — each with its time, price (most are free) and venue. Pass the site key for the city (see otc_list_sites) and an ISO date (YYYY-MM-DD); the date defaults to today. Set free_only to keep just the no-cost listings. The national hub has no local calendar and is not a valid site here. Use otc_get_post on a listing's url for the full write-up. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Day to list, as ISO YYYY-MM-DD. Defaults to today. | |
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. | |
| free_only | No | Only listings marked FREE |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint, openWorldHint, and idempotentHint, so the description is not burdened with restating these. It adds valuable behavioral details: date defaulting to today, the free_only filter, the invalid national hub site, and the fact that each listing includes time, price (mostly free), and venue, with URLs implied by the otc_get_post instruction. This goes well beyond the annotations and helps the agent predict output and edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the purpose, then parameter instructions, then exclusions and alternatives. It is slightly long but every sentence serves a purpose. The final 'Read-only' is redundant given the annotation, but it's a minor redundancy. Overall, it is efficient and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with three parameters and no output schema, the description covers the essential operational details: what it returns (time, price, venue), how to filter, constraints (invalid national hub), and the path to get full write-ups (otc_get_post). It lacks explicit pagination or ordering details, but these are not critical for this tool. The description is sufficiently complete for an agent to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents all three parameters with descriptions. The tool description adds marginal value: it reinforces the site key requirement, mentions the date default (already in schema), and restates free_only's effect (similar to schema). It does add context about the site being from otc_list_sites, but that's more usage guidance than parameter semantics. Since the schema covers parameters, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'List everything happening in an 'on the Cheap' city on a given date.' It names the specific verb (List) and resource (city's events for a day), and distinguishes it from siblings by focusing on a single city/day, with references to the site's events calendar. It also implicitly differentiates from otc_events_month_overview by specifying 'a given date' and from otc_search_posts by focusing on a calendar rather than a text search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage instructions: pass the site key, an ISO date (defaults to today), and optional free_only flag. It explicitly mentions the alternative otc_get_post for full write-ups, and warns that the national hub is not a valid site. However, it does not explicitly contrast with otc_events_month_overview, leaving the agent to infer when to use that sibling instead. This is a minor gap but the core guidance is solid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_list_locationsList a city’s locationsARead-onlyIdempotent
List one "on the Cheap" site's location taxonomy with ids and post counts — the neighbourhoods and surrounding areas it covers. Pass the site key for the city (see otc_list_sites). Use an id to filter otc_search_posts geographically — ids are per-site, so use them only against the site they came from. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, so the description need not repeat safety. It adds the crucial behavioral detail that ids are per-site and must only be used against the originating site, which is beyond the annotations. No contradictions found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the primary purpose, and every sentence earns its place: the output, the parameter usage, and the downstream use case. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with no output schema, the description covers the essential elements: output content (ids and post counts), the parameter, the downstream use, and the per-site constraint. It is sufficient for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents the 'site' parameter thoroughly, including allowed values and aliases, with 100% coverage. The description adds minor context (purpose of the key) but does not significantly enhance meaning beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List one "on the Cheap" site's location taxonomy with ids and post counts'. It clearly distinguishes from siblings like otc_list_sites (which lists cities) and otc_search_posts (which searches posts). The purpose is unambiguous and differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool: to retrieve a city's location taxonomy for filtering otc_search_posts geographically. It references otc_list_sites for the site key and warns that ids are per-site, providing clear context. While it doesn't explicitly state when not to use it, the guidance is sufficient for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_list_sitesList the On the Cheap sitesARead-onlyIdempotent
List every city in the "on the Cheap" network with the site key used to select it. This server reads them all — every other tool takes a site argument, and there is no default, so start here when you do not already know which key covers the city the user means. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds value by stating 'This server reads them all' and 'Read-only,' reinforcing the read-only nature, and by explaining the relationship to other tools (no default site). It doesn't describe return format or pagination, but for a list-all tool with no parameters, the behavioral context is largely complete. The description does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: what it lists, why it matters (site key), and when to use it. It is front-loaded with the core action and resource, and there is no fluff or repetition of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only list tool with no output schema, the description is complete. It tells the agent what it returns (city names and site keys), why that matters (site selection for other tools), and when to call it. The annotations cover safety and idempotency. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema is trivially complete (100% coverage). The description adds meaning by explaining what the output is used for (the `site` key to select a city in other tools), which is valuable context beyond the empty schema. Baseline for 0 params is 4, and the description earns it by clarifying the purpose of the returned keys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a specific resource ('every city in the on the Cheap network'), and the key output ('the `site` key used to select it'). It also distinguishes itself from sibling tools by explaining that this is the starting point for selecting a site, which is unique among the listed siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool: 'start here when you do not already know which key covers the city the user means.' It also explains the context that every other tool takes a `site` argument and there is no default, which effectively tells the agent to use this tool before others when site is unknown. This is clear usage guidance with an implicit alternative (other tools) and a condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
otc_search_postsSearch a city’s On the Cheap articlesARead-onlyIdempotent
Search and filter one "on the Cheap" site's articles — free and cheap things to do in that city, plus deals, festivals, kids activities and local guides. Pass the site key for the city (see otc_list_sites); the national hub is valid here and carries country-wide deals. Filter by full-text query, category or location id (see otc_list_categories / otc_list_locations), and publication date range. Category and location ids are per-site — resolve them against the SAME site you are searching. Retired deals live in an "expired" category and are excluded by default; set include_expired to search them too. Returns slim summaries by default — use otc_get_post for an article's full text. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Tag id | |
| page | No | 1-based page number | |
| site | Yes | Which "on the Cheap" city to read. Required — there is no default site. One of: charlotte, denver, atlanta, chicago, columbus, seattle, kansascity, miami, orlando, portland, richmond, southernmaine, triangle, national. Common aliases also work (milehigh, raleigh, rva, southflorida, kc, …). Use otc_list_sites for the full list with the area each one covers. | |
| view | No | Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact returns slim summaries AND asks WordPress for only the fields they use; "full" returns the whole records. | |
| after | No | Only posts published on or after this date | |
| query | No | Full-text search, e.g. "free museum day" | |
| before | No | Only posts published on or before this date | |
| category | No | Category id from otc_list_categories, for this same site | |
| location | No | Location id from otc_list_locations, for this same site | |
| per_page | No | Results per page (max 100) | |
| include_expired | No | Include retired/expired deals (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, openWorld, idempotent), the description adds crucial behavior: the default exclusion of expired deals, the effect of include_expired, the per-site nature of category/location ids, and the default slim-summary response shape. This is exactly the kind of context that prevents incorrect calls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a compact paragraph where every sentence earns its place. It front-loads the core purpose, then flows through key parameters, caveats, and the sibling handoff, without redundancies or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with no output schema, the description covers all critical aspects: site resolution, filter types, per-site id caveat, expired deals handling, default response shape, and the pointer to otc_get_post. It is complete enough for an agent to call it correctly without further investigation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description enriches parameter meaning: it explains that site keys are city-specific, that the national hub is valid, and how to resolve category/location ids via sibling tools. It also ties include_expired to the 'expired' category, which the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Search and filter one site's articles') and immediately clarifies the content type ('free and cheap things to do...'). It distinguishes itself from sibling tools by explicitly routing full-text needs to otc_get_post and implying the article/event split from the sibling list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear usage context: when to search articles, how to scope to a site, and when to use otc_get_post for full text. However, it does not explicitly state when NOT to use this tool (e.g., for events or categories listings), leaving some inference to the agent despite the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v1.0.0- Changed
otc_events_month_overview1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_get_post1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_healthcheck1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_list_categories1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_list_events1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_list_locations1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_list_sites1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
otc_search_posts1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
1 tool update
v0.4.1- Changed
otc_search_posts2 fields changed- removed
Input schema / properties / compactRemoved value: -{ - "description": "Return slim summaries instead of full records (default true)", - "type": "boolean" -} - added
Input schema / properties / viewAdded value: +{ + "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact returns slim summaries AND asks WordPress for only the fields they use; \"full\" returns the whole records.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
2 tool updates
v0.3.3- Added
otc_healthcheck - Added
otc_search_posts
6 tool updates
v0.3.0- First observed
otc_events_month_overview - First observed
otc_get_post - First observed
otc_list_categories - First observed
otc_list_events - First observed
otc_list_locations - First observed
otc_list_sites
TDQS
Scored across 8 tools
Each tool targets a distinct, well-defined purpose: searching posts, fetching a post, listing daily events, viewing a month overview, and listing taxonomies/sites/health. Even the two event tools are clearly separated by day-level versus month-level scope, and their descriptions cross-reference each other explicitly.
All tools share the consistent `otc_` prefix and use lowercase snake_case, with a mostly predictable verb-first pattern like `search_posts`, `get_post`, and `list_events`. Minor deviations are `otc_events_month_overview` (does not start with `list_`) and `otc_healthcheck` (a noun-style command), but these remain readable and easy to predict.
Eight read-only tools is well-scoped for a city-deals and events content server. Each tool fills a clear role: discovery, detail retrieval, taxonomy lookup, site selection, and connectivity checking, with no redundant or filler tools.
The server covers the core read-only domain thoroughly: searching and reading articles, browsing events by day or month, resolving category/location filters, and enumerating sites. Minor gaps exist, such as no category/query filtering for events and no explicit pagination controls, but the described workflows do not hit major dead ends.
Maintenance
Related MCP Connectors
Google Events listings with dates, venues, and ticket links via a hosted MCP server.
MCP gateway for manoforstaterep.com: articles, search and full text. Read-only, no auth.
One MCP server for 180+ live web-data APIs returning clean JSON from sites that block scrapers.
MCP gateway for donhuffines.com: articles, search and full text. Read-only, no auth.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenancePreference-aware events discovery MCP server that aggregates events, restaurants, and cultural activities across multiple sources and re-ranks them against your personal taste profile to surface things you'd actually want to do.1MIT
- AlicenseNot gradedqualityCmaintenancePublic read-only MCP server backed by GetValetParking.com directory of 789 US valet parking operators across 31,186 cities. Discover valet operators by coordinates or city slug, filter by 9 service types, and fetch full operator profiles. No auth required.MIT
- AlicenseAqualityAmaintenanceRead-only MCP server for accessing Eventbrite tickets, orders, organizer data, and public event search (including undocumented consumer search via browser bridge).31455 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables listing metros and fetching events from the DoStuff network via MCP.1 npmMIT