Skip to main content
Glama
gbrussich52

Main Street MCP

Main Street MCP

M8ven Score

A free, industry-specific MCP server that gives a small business's AI assistants (ChatGPT, Claude, etc.) reliable answers about the business itself — hours, menu/services, FAQs, staff, and how to book — instead of hallucinating them. One business.yaml file per business; no code changes required to run it.

Quickstart (business owner)

  1. Install Node.js 20+ (or use the version already on your machine — check with node -v).

  2. Generate a starter config for your industry:

    npx -y mainstreet-mcp init --industry restaurant

    Replace restaurant with your industry. Supported industries: restaurant, dental, law-firm, home-services, salon-spa, fitness-studio, real-estate-agent, auto-repair, insurance-agency, church.

    This writes business.yaml in the current directory — edit it with your business's real name, hours, menu/services, FAQs, etc. (Use --out <path> for a different name; every other command then needs --config <path>.)

  3. Check your edits are valid:

    npx -y mainstreet-mcp validate

    A broken file (bad YAML, a typo'd industry, a field that doesn't fit) prints a specific, readable error instead of a stack trace.

  4. Point your AI assistant at it. For a local MCP client (e.g. Claude Desktop) that spawns stdio servers, add an entry like:

    {
      "mcpServers": {
        "my-business": {
          "command": "npx",
          "args": ["-y", "mainstreet-mcp", "--config", "/absolute/path/to/business.yaml"]
        }
      }
    }

    To serve over HTTP instead (e.g. for a hosted deployment), run:

    npx -y mainstreet-mcp serve --http --port 3000

    The HTTP server only binds to 127.0.0.1 and validates the Host/Origin headers on every request — put a reverse proxy in front of it for anything beyond local testing.

Related MCP server: essetech-ai-readiness-mcp

What it gives an AI assistant

Every business gets 7 universal tools regardless of industry:

  • get_business_profile — name, description, contact info, address, policies

  • check_open_status — open/closed right now (or at a given time), in the business's own timezone, including overnight hours and holiday/exception overrides

  • search_offerings — free-text search over whatever the business sells/offers

  • answer_question — looks up configured FAQs; returns found: false rather than a guess when nothing matches confidently

  • list_staff — configured staff, roles, bios, credentials

  • get_booking_options — how to actually book (phone/online/walk-in/email)

  • submit_inquiry — lets a customer leave a message; rate-limited, sanitized, and screened by industry-specific guardrails before it's accepted

On top of that, each industry preset turns on a handful of capabilities — pluggable tool modules — matched to that industry:

Industry

Capabilities / tools

restaurant

menu → get_menu

dental

insurance_accepted → check_insurance_accepted

law-firm

practice_areas → list_practice_areas (always carries a not-legal-advice disclaimer)

home-services

service_area → check_service_area, price_estimate → get_price_estimate

salon-spa

class_schedule → get_class_schedule

fitness-studio

class_schedule → get_class_schedule

real-estate-agent

listings → search_listings

auto-repair

service_area, price_estimate, insurance_accepted

insurance-agency

coverage_lines → list_coverage_lines

church

service_times → get_service_times

Every tool ships an outputSchema and returns structuredContent, so a calling agent gets typed data back, not just prose to parse.

Guardrails

Some presets screen submit_inquiry messages before accepting them, on top of the universal sanitization (HTML/control-char stripping, length caps, rate limiting):

  • dental — rejects messages containing an SSN-shaped pattern, and long messages with clinical/health detail keywords (tells the patient to call the office instead).

  • law-firm — caps the message to one line / 280 characters (a topic, not case details).

  • salon-spa / fitness-studio — rejects messages containing health/medical detail keywords (pregnancy, injury, medication, etc.), directing the customer to tell staff in person instead.

price_estimate outputs always carry is_estimate: true plus a disclaimer — never present as a firm quote.

Install

Claude Desktop (one-click, no terminal)

Download the latest mainstreet-mcp.mcpb from the releases page (or build it yourself — see mcpb/ below), then double-click it. Claude Desktop opens it as a Desktop Extension install prompt; it asks for one thing — a folder to keep your business.yaml in. Pick any folder you can find again; Documents is fine. No Node.js install or terminal needed.

You do not need a business.yaml before you install. If the folder is empty, the server starts in setup mode: ask Claude to "set up my business", and it lists the industries, writes the starter file into that folder, and interviews you to fill in your real hours, services and prices. Turn the extension off and on again when you're done and your business tools appear. The folder you picked stays the same throughout.

To build the .mcpb yourself:

npx @anthropic-ai/mcpb pack mcpb build/mainstreet-mcp.mcpb

Claude Code (plugin)

Install the bundled plugin, which registers the MCP server and adds a setup-my-business skill that interviews you and writes business.yaml for you:

claude plugin install ./plugin

The plugin's MCP config expects business.yaml at your project root (${CLAUDE_PROJECT_DIR}/business.yaml), which is exactly what init writes — run the setup-my-business skill, or npx -y mainstreet-mcp init --industry <yours>, from that directory.

Claude Code (direct MCP add, no plugin)

claude mcp add mainstreet -- npx -y mainstreet-mcp --config /absolute/path/to/business.yaml

Generic JSON config (any MCP client)

For any client that spawns stdio servers from a JSON config (Claude Desktop's manual config, other MCP clients):

{
  "mcpServers": {
    "my-business": {
      "command": "npx",
      "args": ["-y", "mainstreet-mcp", "--config", "/absolute/path/to/business.yaml"]
    }
  }
}

Example configs

examples/ has one working <industry>.business.yaml per supported industry — the same files init copies from and the E2E test suite runs against.

Development

npm install
npm run build     # tsc -> dist/
npm test          # builds, then runs node --test against dist/test/*.test.js

Stack: @modelcontextprotocol/server@2.0.0 (MCP spec 2026-07-28), TypeScript strict/ESM, Zod for all schemas and config validation, yaml for parsing business.yaml. All dependencies are pinned to exact versions (no ^).

Project layout

  • src/config/schema.ts — the business.yaml Zod schema (BusinessConfigSchema) and types.

  • src/config/load.ts — loads + validates a config file, including per-capability config and the industry/capability compatibility check.

  • src/hours.ts — timezone-aware open/closed logic (Intl-based), overnight ranges, date exceptions, forward-scanning for the next open/close time.

  • src/search.ts — the recall-first free-text search used by search_offerings and answer_question.

  • src/inquiries.ts — InquirySink: sanitization, rate limiting, guardrail hook, and file/webhook delivery for submit_inquiry.

  • src/capabilities/* — the 9 pluggable capability modules (config schema + tool registration each).

  • src/presets/* — the 10 industry presets: which capabilities are on, the instructions text injected into the server, and any guardHooks.

  • src/tools/universal.ts — the 7 universal tools every business gets.

  • src/server.ts — createServer(config): builds the McpServer for a loaded config.

  • src/cli.ts — mainstreet-mcp entry point (stdio default, init, validate, serve --http).

  • src/test/*.test.js (compiled from .ts) — unit tests (schema, search, hours, inquiries/ guardrails) plus an E2E suite that spawns the built stdio server for every example config and drives it with the real MCP client SDK.

Testing notes

  • npm test runs both unit tests and the E2E suite (src/test/e2e.test.ts), which spawns dist/cli.js as a child process via StdioClientTransport for every file in examples/, calls tools/list, then calls every registered tool and asserts it returns structuredContent without isError.

  • serve --http binds a local port, which some sandboxed shells block by default; test it outside such a sandbox if EPERM/listen errors appear.

Status

Presets, capabilities, universal tools, CLI, and all 10 example configs are built and verified (build, unit tests, E2E stdio tests, CLI validate success/failure paths, and an HTTP smoke test all pass — see the build's final report for exact output). This is a first build, not yet published or deployed anywhere.

Available Tools

2 tools
create_business_configCreate Business ConfigA

Writes a starter business.yaml for the chosen industry into the folder this server was pointed at. Refuses to overwrite an existing file. After this, edit the file with the owner's real details and have them reconnect the extension.

ParametersJSON Schema
NameRequiredDescriptionDefault
industryYesIndustry id from list_industries, e.g. "dental" or "home-services".

Output Schema

ParametersJSON Schema
NameRequiredDescription
pathYes
industryYes
next_stepYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations indicate no readOnlyHint (so it's a write operation) and no destructiveHint, but the description adds critical behavior: 'Refuses to overwrite an existing file' and 'have them reconnect the extension' (post-requisite). These are non-obvious and valuable. The description does not claim idempotency (annotations say idempotentHint=false), but it explains the overwrite refusal, which is consistent. No 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 concise sentences with no filler. The main action and target are front-loaded, and the crucial overwrite constraint is placed second. Every sentence adds necessary information: what it does, what it refuses to do, and the next steps the agent should advise.

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?

Given the single parameter and full schema coverage, the description is near-complete. It covers the action, the overwrite refusal, and the follow-up steps. It lacks an explicit pointer to validate the industry via list_industries, but the schema already references that sibling. The output schema exists, so return values need not be described.

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 coverage is 100%, including a description for the industry parameter and an enum. The description does not add additional parameter-level detail beyond what the schema provides, but it does mention 'chosen industry' and 'real details' in context. Baseline 3 is appropriate given full schema coverage.

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 verb (writes), the resource (starter business.yaml), and the target location ('folder this server was pointed at'). It distinguishes itself from the sibling list_industries by being a write operation versus a read/list operation. The agent can immediately understand what the tool does.

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 implicitly communicates when to use it: after the user has chosen an industry, and before the owner's details are added. It explicitly says it refuses to overwrite, which is a clear constraint. However, it does not explicitly state when not to use it or mention list_industries as the source for the industry parameter, which is a minor gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_industriesList IndustriesA
Read-onlyIdempotent

Lists the industry starter kits this server can generate. Use this first, then pass the chosen id to create_business_config.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
industriesYes

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, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds useful context beyond annotations: that the list contains 'industry starter kits this server can generate' and that the result feeds into a specific downstream tool. This is meaningful behavioral/scoping information, though it doesn't describe output format or pagination (minor for a zero-parameter read-only list).

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?

Two sentences with zero fluff. The primary action is stated first, followed by the critical routing instruction. Every word adds value.

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 an output schema and safety annotations, the description is fully sufficient. It states the purpose, usage order, sibling relationship, and downstream integration. There is no missing information an agent would need to invoke this 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?

The tool has zero parameters and the input schema is empty, so the description needs no parameter explanation. The baseline for 0 params is 4, and the description appropriately adds no extraneous parameter detail. It does mention passing the 'id' downstream, which clarifies how the output is used rather than parameter semantics.

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 uses a specific verb ('Lists') and resource ('industry starter kits'), and immediately distinguishes this tool from its only sibling by stating that it should be used first, with the chosen id then passed to create_business_config. An agent can clearly understand what this tool returns and how it differs from the sibling without opening the schema.

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?

Explicitly states when to use the tool ('Use this first') and the follow-up action ('then pass the chosen id to create_business_config'), naming the alternative tool directly. This gives clear guidance on invocation order and relationship to the sibling.

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 updatesv0.1.3
    • First observedcreate_business_config
    • First observedlist_industries

TDQS

A4.4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct roles: list_industries enumerates the available starter kits, and create_business_config generates the file from a chosen kit. There is no overlap, and the intended workflow dependency is explicitly documented.

Naming Consistency5/5

Both tool names follow the same verb_noun pattern (list_industries, create_business_config). The naming is consistent, predictable, and accurately describes each action.

Tool Count4/5

Two tools is on the thin side, but it is reasonable for a narrowly scoped server whose purpose is listing starter industries and generating one config file. Each tool earns its place, and adding more would likely go beyond the stated design.

Completeness4/5

The tool set covers the promised flow: discover an industry starter and create the corresponding business config, with a clear manual-editing handoff afterward. It intentionally omits update/overwrite behavior because the server explicitly refuses to overwrite existing files.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers