Skip to main content
Glama
chrischall

onthecheap-mcp

by chrischall

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-mcp

Or as a Claude Code plugin:

/plugin marketplace add chrischall/onthecheap-mcp
/plugin install onthecheap-mcp

Related 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

Charlotte On The Cheap

Charlotte, NC

denver

Mile High on the Cheap

Denver, CO

atlanta

Atlanta on the Cheap

Atlanta, GA

chicago

Chicago on the Cheap

Chicago, IL

columbus

Columbus on the Cheap

Columbus, OH

seattle

Greater Seattle on the Cheap

Seattle–Tacoma

kansascity

Kansas City on the Cheap

Kansas City

miami

South Florida on the Cheap

Miami / Broward / Palm Beach

orlando

Orlando on the Cheap

Orlando, FL

portland

Portland Living on the Cheap

Portland, OR

richmond

RVA on the Cheap

Richmond, VA

southernmaine

Southern Maine on the Cheap

Southern Maine

triangle

Triangle on the Cheap

Raleigh / Durham / Chapel Hill

national

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

otc_list_events

Everything on a given day — time, price, venue. free_only filters to no-cost listings. Defaults to today.

otc_events_month_overview

Day-by-day counts for a month, to find the busiest days. Each day's list is a preview; total is the real count.

otc_search_posts

Search articles by text, category, location and date range. Returns slim summaries by default.

otc_get_post

One article in full, as readable text or raw HTML. Accepts an id, slug, or URL.

otc_list_categories

Category ids and post counts, for filtering searches by topic.

otc_list_locations

Local area ids and post counts, for filtering geographically.

otc_list_sites

The cities in the network and their site keys. Takes no arguments.

otc_healthcheck

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 build

See 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 tools
otc_events_month_overviewOverview of a city’s events across a monthA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteYesWhich "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.
monthNoMonth to summarise, as ISO YYYY-MM. Defaults to the current month.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 articleA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
postYesPost id, slug, or full article URL
siteYesWhich "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.
formatNoBody format: readable text (default) or raw HTML

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 connectivityA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteYesWhich "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

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 categoriesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteYesWhich "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

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 dayA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoDay to list, as ISO YYYY-MM-DD. Defaults to today.
siteYesWhich "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_onlyNoOnly listings marked FREE

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 locationsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteYesWhich "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

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 sitesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 articlesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNoTag id
pageNo1-based page number
siteYesWhich "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.
viewNoResponse 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.
afterNoOnly posts published on or after this date
queryNoFull-text search, e.g. "free museum day"
beforeNoOnly posts published on or before this date
categoryNoCategory id from otc_list_categories, for this same site
locationNoLocation id from otc_list_locations, for this same site
per_pageNoResults per page (max 100)
include_expiredNoInclude retired/expired deals (default false)

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 8 tool updatesv1.0.0
    • Changedotc_events_month_overview1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_get_post1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_healthcheck1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_list_categories1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_list_events1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_list_locations1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_list_sites1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedotc_search_posts1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  2. 1 tool updatev0.4.1
    • Changedotc_search_posts2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return slim summaries instead of full records (default true)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added 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"
        +}
  3. 2 tool updatesv0.3.3
    • Addedotc_healthcheck
    • Addedotc_search_posts
  4. 6 tool updatesv0.3.0
    • First observedotc_events_month_overview
    • First observedotc_get_post
    • First observedotc_list_categories
    • First observedotc_list_events
    • First observedotc_list_locations
    • First observedotc_list_sites

TDQS

A4.4/5.0

Scored across 8 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityActive
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Preference-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.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Public 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
  • A
    license
    A
    quality
    A
    maintenance
    Read-only MCP server for accessing Eventbrite tickets, orders, organizer data, and public event search (including undocumented consumer search via browser bridge).
    31
    455 npm
    MIT