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; on failure error.kind is edge_blocked, http, timeout or transport.

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 in the city’s own time zone.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even with readOnlyHint/openWorldHint/idempotentHint annotations, the description adds crucial behavioral context: 'The calendar shows at most four listings per day, so events is a preview while total is the real count'. It discloses the preview limitation, the invalid national hub, and month default behavior, going well beyond the 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 front-loaded with the core purpose, and every subsequent sentence adds distinct value: preview vs. total, alternative tool, invalid site, use cases, and read-only confirmation. It is slightly longer than average but contains zero filler; every clause earns its place.

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 two-parameter tool with no output schema, the description is remarkably complete: it explains the main return fields (events vs total), the four-listing cap, the month default, invalid site values, and the alternative tool for full schedules. An agent has everything needed to invoke it 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 on top by telling the agent to pass the site key, referencing otc_list_sites, and explicitly stating the national hub is not valid. Month semantics are fully covered by the schema, so a modest bump to 4 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 opens with a specific verb+resource: 'Day-by-day overview of a whole month' and clearly states the output concept ('true number of listings and a short preview'). It distinguishes itself from siblings by naming otc_list_events (for complete daily schedules) and otc_list_sites (for city keys), so an agent knows exactly what this tool does and does not do.

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,' and directs the agent to otc_list_events for a specific date's complete schedule. It also warns that the national hub is not a valid site, and points to otc_list_sites for key lookup — clear routing versus 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. On failure error.kind names what broke: edge_blocked (a CDN/WAF refused the request before it reached the site), http, timeout or transport. 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.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations (readOnly/openWorld/idempotent) by enumerating failure modes via error.kind: edge_blocked (with the meaning — CDN/WAF refused pre-site), http, timeout, transport. That is exactly the operational context an agent needs to interpret a failure.

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 tight sentences, front-loaded with purpose, then the required param, then the connectivity caveat, then the failure taxonomy. No 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 a single-param read-only probe with no output schema, the definition covers purpose, required input, credential-free nature, and the full error taxonomy an agent needs to act on results. Nothing material is missing.

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 already lists the enum values, aliases, and the otc_list_sites pointer. Description only repeats the sibling pointer already in the schema, adding no new param detail beyond baseline.

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?

Specific verb+resource: verifies a named site is reachable and its public API responds. Distinct from all siblings (list/get/search tools) — none of which perform a connectivity probe.

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?

States it needs a `site` key and points to otc_list_sites for valid values and coverage. Clarifies this is connectivity-only since no credentials are needed, implicitly contrasting with any authenticated operations. No explicit 'when not to use' beyond that.

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 in that city. 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 in the city’s own time zone.
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.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only and idempotent behavior. The description adds meaningful behavioral context: the date defaults to today in the city's time zone, the national hub is invalid, listings include time/price/venue, and the operation is read-only. No contradictions with 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?

Four focused sentences, front-loaded with the core action gift, then parameter notes, an exclusion, and a pointer to a sibling tool. No filler or redundant restatement 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?

With no output schema, the description compensates by stating what each listing contains (time, price, venue) and the behavior of each parameter. It also covers the invalid site case and directs users to otc_get_post for full write-ups, so an agent has enough to invoke it 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 beyond the schema by explaining that `date` defaults to today, `free_only` filters to no-cost listings, and `site` must be a valid local calendar—reinforcing the schema's provided list and aliases.

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 everything happening in an 'on the Cheap' city on a given date." It clearly distinguishes itself from siblings by noting the site-scoped calendar listing and pointing to otc_get_post for full write-ups.

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?

Gives explicit usage instructions: pass `site` key, use ISO `date`, set `free_only` for no-cost listings. It also mentions when not to use it (the national hub has no local calendar) and directs to otc_get_post for richer detail.

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. 2 tool updatesv1.1.2
    • Changedotc_events_month_overview1 field changed
      • changedInput schema / properties / month / description
        Previous value: -"Month to summarise, as ISO YYYY-MM. Defaults to the current month."New value: +"Month to summarise, as ISO YYYY-MM. Defaults to the current month in the city’s own time zone."
    • Changedotc_list_events1 field changed
      • changedInput schema / properties / date / description
        Previous value: -"Day to list, as ISO YYYY-MM-DD. Defaults to today."New value: +"Day to list, as ISO YYYY-MM-DD. Defaults to today in the city’s own time zone."
  2. 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"
  3. 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"
        +}
  4. 2 tool updatesv0.3.3
    • Addedotc_healthcheck
    • Addedotc_search_posts
  5. 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

Disambiguation4/5

Most tools target clearly distinct resources or actions: healthcheck, sites, categories, locations, events-by-date, events-by-month, get-post, and search-posts. The only mild overlaps are the two event tools (month overview vs single-date list) and the two taxonomy listers (categories vs locations), but the descriptions explicitly differentiate granularity and domain, so misselection risk is low.

Naming Consistency4/5

All 8 tools share a consistent `otc_` prefix and predominantly use a `otc_<verb>_<noun>` pattern (list_sites, get_post, search_posts, list_events, list_categories). The deviations are `otc_healthcheck` (verb without noun) and `otc_events_month_overview` (noun-first, longer), which are still readable and predictable.

Tool Count5/5

Eight tools is well-scoped for a read-only local-listings server: a discovery tool (list_sites), two taxonomy listers, two event views at different granularities, article search/get, and a connectivity check. Each tool earns its place with no obvious filler.

Completeness4/5

The read-only surface is largely complete: site discovery, category/location taxonomies, event listing at day and month granularity, article search and full-text fetch, plus health checking. Minor gaps exist — no cross-site aggregation or dedicated event-detail endpoint (you must route through otc_get_post) — but these are workable within the stated read-only scope.

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
    550 npm
    MIT