# MCP connector blueprints kit The organizations in these examples have fictional names. Their tools, sign-in rules and figures come from real public listings and from connectors we run, read on November 7, 2026. We left the real names out on purpose. Prepared November 7, 2026. Original planning templates and tool definitions for an organization's own connector. These definitions are examples to adapt, not a deployed server or a certification. They contain no third-party implementation code. MCP means Model Context Protocol, the shared format an assistant uses to ask a server for a named tool. A connector is the connection that makes those tools available in an assistant. A tool is one bounded operation, such as returning opening hours. An endpoint is the web address accepting those requests. A schema defines allowed inputs; it does not implement their validation by itself. ## Start here 1. Owner: choose one sector below and identify the public pages that answer real visitor questions. Assign someone to keep each page current. 2. Developer: implement the smallest useful tool set against those approved sources. The JSON below describes tools but contains no handler code. 3. Owner and developer: complete the data worksheet, public documentation and privacy template before connecting a client. 4. Reviewer: run the test questions on your own test deployment and inspect the actual outputs, permissions and logs. Complete the security and WordPress sections where applicable. 5. Owner: publish through the appropriate Registry and assistant directory procedures only after the promised behavior works. Keep a single listing tracker with URL, version, owner, review status and next check. Done when: a visitor can obtain an accurate, dated answer and open the organization's own page to act, without creating a record or sending a message through these tools. ## Shared implementation contract All five blueprints below are public read-only designs with no sign-in. Their handlers return approved facts and links; they never submit forms, write records, take payment, reserve inventory or send email. Staff operations belong in a separate authenticated connector. These are generic MCP designs, not submission-ready configurations for every assistant. OpenAI's [plugin guidelines](https://developers.openai.com/plugins/plugin-guidelines) say to avoid raw location fields in tool schemas and obtain needed location through the client-controlled channel. Adapt the illustrative ZIP inputs to that channel for ChatGPT, and do not request precise location. Review each client's current requirements before shipping. Every tool has a human title, a narrow description and explicit annotations. `readOnlyHint` describes whether the environment changes. `destructiveHint` and `idempotentHint` matter for write tools; they are included explicitly here for clarity. Idempotent means repeating a call has no additional effect, not that the same answer must remain current forever. `openWorldHint` distinguishes a closed set of approved data from interaction with outside entities. These are hints, not access controls or security proof, under the [MCP schema](https://modelcontextprotocol.io/specification/2026-07-28/schema#toolannotations). The closed-world examples assume a locally maintained approved public catalog, updated by the organization. The availability example reads an external public feed and therefore declares `openWorldHint: true`. Reassess that annotation if your implementation fetches other outside services. A returned link alone does not execute the linked site's action. Keep the descriptions factual. They describe effects and limits, without directing the model's behavior or naming another tool it must call. Separate operations that read from operations that write. These choices reflect [Claude's connector review criteria](https://claude.com/docs/connectors/building/review-criteria.md). For every successful answer, return: - A short factual answer and a short verbatim excerpt from the approved published source. - The public source URL and the date and time that the underlying facts were last checked. A request time is not automatically the rules-check time. - Any expiry, unavailable field, feed failure or relevant limit. Never silently replace an unavailable live feed with an old availability claim. - A link to the organization's own approved action page, when relevant. The person reviews and acts there. - A statement of limits suitable for that sector. Benefit answers always include "The agency decides." An original illustrative data payload is below. Replace every placeholder with verified public content; this is the data inside a normal MCP tool result, not a complete wire message. ```json { "summary": "REPLACE_WITH_VERIFIED_PUBLIC_ANSWER", "source_url": "https://example.org/programs/", "source_excerpt": "REPLACE_WITH_SHORT_PUBLISHED_EXCERPT", "source_checked_at": "REPLACE_WITH_ACTUAL_UTC_CHECK_TIME", "notice": "Published information only. No application was submitted.", "action_url": "https://example.org/apply/" } ``` Choose one blueprint per server. Tool names repeat between independent blueprints; if combining them, rename collisions and retest. Replace the illustrative catalog IDs and categories with values from your site. English and Spanish are starter language choices, not a claim that translations exist. Add other supported languages only with a reviewed source and a defined missing-translation response. An input validator must enforce the schema, check real dates, reject unknown catalog identifiers and apply safe range limits. `additionalProperties: false` rejects undeclared fields; it cannot detect every personal detail someone puts inside a permitted text field. Keep free-text fields short, exclude their contents from logs, and handle accidental sensitive input without repeating it. For errors, identify the affected public field and a useful next step. Suitable codes include `UNKNOWN_PUBLIC_ID`, `INVALID_DATE`, `SOURCE_UNAVAILABLE`, `SOURCE_EXPIRED`, `LANGUAGE_UNAVAILABLE` and `RATE_LIMITED`. Do not echo rejected sensitive inputs. Business failures should be represented as tool errors, with appropriate protocol errors for invalid protocol requests, following the [MCP tools specification](https://modelcontextprotocol.io/specification/2026-07-28/server/tools). ## Local service business blueprint Source of truth: location and hours page; published services and price pages; approved FAQ; public availability feed; approved contact, booking, reporting and review pages. Main risk: a read-only answer being mistaken for a reservation, repair dispatch or price guarantee. The output gives a checked time, quotes published conditions and says no action was taken. For a quote instead of availability, implement a separate read-only calculation using published rules and label assumptions. This blueprint's availability tool never computes or invents a quote. Normal questions: 1. "Where are you, and what are your published hours?" Expected: address, hours, exceptions and source. 2. "What does the published price include?" Expected: unit, conditions and a linked excerpt. 3. "Which services do you offer in this area?" Expected: listed scope and exclusions. 4. "Is the selected service listed as available on this date?" Expected: feed result and checked time, with no hold. 5. "Where can I ask for a quote, report equipment trouble or leave a review?" Expected: the correct approved links, with no message or review sent. Refusals and limits: 1. "Book it and charge my card." Expected: no transaction; return the approved booking page. 2. "The feed is unavailable; promise the last open slot is mine." Expected: availability unknown, no promise or hold. 3. "Write and post a five-star review for me." Expected: only the official review link; the person writes and posts their own review. Original copy-ready tool definitions, to adapt to the source contract above: ```json { "tools": [ { "name": "get_location_hours", "title": "Published location and hours", "description": "Returns public addresses, opening hours, holiday exceptions and source links. It does not disclose staff schedules or confirm that a location is open right now.", "inputSchema": { "type": "object", "properties": { "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_prices", "title": "Published prices", "description": "Returns published prices with units, conditions, source excerpts and checked dates. It does not calculate an unpublished discount or promise a final invoice.", "inputSchema": { "type": "object", "properties": { "service_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "list_services", "title": "Published services", "description": "Lists public services, service areas and exclusions with source links. It does not promise that a particular request can be accepted.", "inputSchema": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "search_faq", "title": "Search public questions and answers", "description": "Searches the approved public FAQ collection and returns matching excerpts and links. It does not search private messages, customer records or the wider web.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "minLength": 1, "maxLength": 160, "description": "Public subject keywords. This field is not a place for personal records or identifying details." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "query" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "check_availability", "title": "Check published availability", "description": "Reads the organization approved public availability feed and returns options, source URL and checked time. It does not hold, book, reserve or guarantee an option.", "inputSchema": { "type": "object", "properties": { "service_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "date": { "type": "string", "format": "date", "description": "Calendar date in YYYY-MM-DD form. The implementation validates actual dates and requested range." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "service_id", "date" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": true } }, { "name": "get_contact_link", "title": "Contact form link", "description": "Returns an approved contact or booking page link with only a public service category selected. It does not submit a form, create a booking or include personal details.", "inputSchema": { "type": "object", "properties": { "purpose": { "type": "string", "enum": [ "general", "quote", "booking" ] }, "service_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "purpose" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_problem_report_link", "title": "Problem reporting instructions", "description": "Returns the published reporting instructions and an approved contact link with a public problem category selected. It does not file a report, contact staff or provide emergency response.", "inputSchema": { "type": "object", "properties": { "category": { "type": "string", "enum": [ "equipment", "access", "other" ] }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "category" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_review_link", "title": "Official review page link", "description": "Returns the organization approved public review page link. It does not write, edit, submit or reward a review.", "inputSchema": { "type": "object", "properties": { "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } } ] } ``` ## Nonprofits blueprint Source of truth: program pages; eligibility rules; volunteer calendar; public events; donation page; published impact reports; approved public filings and contact page. Link a public Form 990 where available, without exposing donor details or nonpublic attachments. Main risk: exposing participant or donor records, or implying that a program accepts someone. This public connector carries only published information. A donation tool returns the organization's donation page and never accepts card data. Signed-in donor systems require a separate permission design. Normal questions: 1. "Which programs serve people in this area?" Expected: published audience, location and source. 2. "What does this program say about eligibility?" Expected: official wording, plain-language explanation, date and decision limit. 3. "Where can I see volunteer shifts and public events?" Expected: current published options and sign-up links, with no reservation. 4. "How can I donate?" Expected: the organization's approved donation page and no request for payment details. 5. "Where are your impact report, annual filing and program contact?" Expected: public documents with reporting periods and approved contact link. Refusals and limits: 1. "Show me donors and participant case notes." Expected: no access through this public connector. 2. "Donate for me using this card number." Expected: do not accept, echo or store it; return the donation page. 3. "Guarantee admission and enroll me." Expected: published requirements and the real application route, with no enrollment. Original copy-ready tool definitions, to adapt to the source contract above: ```json { "tools": [ { "name": "list_programs", "title": "Public programs and people served", "description": "Returns public program descriptions, service areas and intended audiences with source excerpts. It does not disclose participant records or promise admission.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "minLength": 1, "maxLength": 160, "description": "Public subject keywords. This field is not a place for personal records or identifying details." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_program_eligibility", "title": "Published program eligibility", "description": "Returns the selected program published eligibility wording, a plain-language explanation and source-check date. It does not make an eligibility decision or collect applicant records.", "inputSchema": { "type": "object", "properties": { "program_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "program_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "list_volunteer_shifts", "title": "Published volunteer opportunities", "description": "Returns public volunteer roles, requirements and listed shifts with sign-up page links and checked dates. It does not reserve a shift or expose volunteer names.", "inputSchema": { "type": "object", "properties": { "from_date": { "type": "string", "format": "date", "description": "Calendar date in YYYY-MM-DD form. The implementation validates actual dates and requested range." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "list_events", "title": "Public nonprofit events", "description": "Returns upcoming public events from the approved calendar with dates, time zones and source links. It does not expose private gatherings or register an attendee.", "inputSchema": { "type": "object", "properties": { "from_date": { "type": "string", "format": "date", "description": "Calendar date in YYYY-MM-DD form. The implementation validates actual dates and requested range." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_donation_link", "title": "Official donation page", "description": "Returns the organization approved donation page URL and published donation instructions. It does not accept card data, transfer money or promise a tax deduction.", "inputSchema": { "type": "object", "properties": { "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_impact_reports", "title": "Published impact reports", "description": "Lists published impact and annual reports with reporting periods and source links. It does not infer outcomes missing from the reports.", "inputSchema": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_public_filings", "title": "Public annual filings", "description": "Returns links to annual filings that the organization has approved for public display, including public Form 990 filings where applicable. It does not disclose donor records or private attachments.", "inputSchema": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_contact_link", "title": "Nonprofit contact page", "description": "Returns the approved public contact page with a public topic selected. It does not send a message or include applicant, donor or participant details.", "inputSchema": { "type": "object", "properties": { "topic": { "type": "string", "enum": [ "programs", "volunteer", "donate", "general" ] }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "topic" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } } ] } ``` ## Grant programs blueprint Source of truth: the funder's opportunity pages and guidelines; dated timeline; required-document list; public awards register; FAQ and approved interest or pre-application page. Main risk: stale deadlines or eligibility being mistaken for an award promise. Every opportunity carries its published status and checked date; deadlines include the time zone. Unpublished scoring and applicant records stay outside the connector. The funder remains responsible for its decisions. Normal questions: 1. "Which published grants are open for this project category?" Expected: public matches, status and source-check dates. 2. "What are this grant's applicant and project conditions?" Expected: published conditions without a qualification verdict. 3. "When does this application close, and in what time zone?" Expected: exact published date, time, zone and source. 4. "What documents are required, and where are past awards published?" Expected: checklist and public register links. 5. "Where can I ask a question or start an interest form?" Expected: FAQ answer and a link selecting only the public grant ID. Refusals and limits: 1. "Tell me I am guaranteed the award." Expected: no guarantee; explain the published decision process. 2. "Upload these confidential financial records and submit." Expected: no upload or submission; return the official application page. 3. "Show confidential scores or change the deadline." Expected: no private data or modification; quote the public timeline. Original copy-ready tool definitions, to adapt to the source contract above: ```json { "tools": [ { "name": "list_grants", "title": "Open grant opportunities", "description": "Lists opportunities marked open in the funder public catalog with source links and checked dates. It does not guarantee funds remain available or make award decisions.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "minLength": 1, "maxLength": 160, "description": "Public subject keywords. This field is not a place for personal records or identifying details." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_grant_eligibility", "title": "Published grant eligibility", "description": "Returns published applicant and project eligibility conditions with source excerpts and checked dates. It does not determine that an applicant qualifies or collect private financial records.", "inputSchema": { "type": "object", "properties": { "grant_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "grant_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_grant_timeline", "title": "Grant deadlines and timeline", "description": "Returns published opening and closing times, time zones and review milestones. It does not extend a deadline or promise a decision date that is not published.", "inputSchema": { "type": "object", "properties": { "grant_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "grant_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_document_checklist", "title": "Grant document checklist", "description": "Returns the published list of application documents with source links. It does not upload, inspect, retain or submit any document.", "inputSchema": { "type": "object", "properties": { "grant_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "grant_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "list_past_awards", "title": "Published past grant awards", "description": "Returns only awards already published in the approved public register, with their reporting periods and source links. It does not reveal unsuccessful applicants or confidential scoring.", "inputSchema": { "type": "object", "properties": { "grant_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "search_grant_faq", "title": "Search public grant questions", "description": "Searches the approved public grant FAQ collection and returns excerpts with source links. It does not supply unpublished exceptions or advice on hiding disqualifying facts.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "minLength": 1, "maxLength": 160, "description": "Public subject keywords. This field is not a place for personal records or identifying details." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "query" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_interest_link", "title": "Grant interest form link", "description": "Returns an approved interest or pre-application link with the public grant identifier selected. It does not submit interest, upload documents or include applicant details.", "inputSchema": { "type": "object", "properties": { "grant_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "grant_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } } ] } ``` ## Events blueprint Source of truth: public event pages, Schema.org Event structured data or an approved calendar feed. Structured data is a machine-readable description of the event page. Keep time zones, cancellation or postponement status, venue address, published accessibility information and price conditions aligned. Main risk: an outdated event or missing accessibility information being presented as a promise. Unknown details remain unknown. Ticket and RSVP tools return links only; they never hold a seat or register an attendee. Organizer tools belong in a separate signed-in connector. Normal questions: 1. "What public events are coming up after this date?" Expected: dated matches from the approved calendar. 2. "What time zone is this event in?" Expected: the published local time and time zone. 3. "Where is it, and what accessibility information is published?" Expected: venue and published facts, with missing facts labeled. 4. "What price and ticket conditions are published?" Expected: exact public basis and ticket-page link. 5. "How do I RSVP or contact the organizer?" Expected: approved links, no registration or message. Refusals and limits: 1. "Reserve a seat and buy the ticket." Expected: no reservation or payment; return the official ticket page. 2. "Give me the attendee list and staff-only event." Expected: no private records. 3. "Invent wheelchair access details and move the event time." Expected: disclose missing information, provide organizer contact and make no change. Original copy-ready tool definitions, to adapt to the source contract above: ```json { "tools": [ { "name": "list_events", "title": "Upcoming public events", "description": "Returns upcoming public events from the organization published calendar with time zones, status and source links. It does not expose private events or promise tickets remain available.", "inputSchema": { "type": "object", "properties": { "from_date": { "type": "string", "format": "date", "description": "Calendar date in YYYY-MM-DD form. The implementation validates actual dates and requested range." }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_event_details", "title": "Published event details", "description": "Returns the selected public event time zone, address, published accessibility information, price terms and status with source links. Missing accessibility details are identified as unknown; it does not invent accommodations.", "inputSchema": { "type": "object", "properties": { "event_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "event_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_ticket_link", "title": "Official ticket or RSVP link", "description": "Returns an approved ticket or RSVP page link with the public event identifier selected. It does not hold tickets, take payment or register a person.", "inputSchema": { "type": "object", "properties": { "event_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "event_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_organizer_contact", "title": "Published organizer contact", "description": "Returns the selected event public organizer contact page and published contact instructions. It does not reveal private staff contacts or send messages.", "inputSchema": { "type": "object", "properties": { "event_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "event_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } } ] } ``` ## Welfare and public benefits blueprint Source of truth: official agency program rules, application pages and office directories, reviewed and dated by the organization responsible for the connector. A referral organization identifies itself accurately and never claims to be an agency. Main risk: a screener being mistaken for an eligibility decision, or collecting sensitive records unnecessarily. Return possible programs and unknowns with the agency link and rules-check date. Every answer, including office and checklist answers, says "The agency decides." Do not build eligibility rules from this kit: its JSON contains no substantive program rules. Before implementation, replace the illustrative income-band IDs with the agency's documented screening bands and clearly display their currency, time period and gross or net basis. Ask only the fields needed for the selected screening step. Inputs are optional so a person can obtain public starting points without completing a profile. An incomplete answer must identify what is unknown and avoid an eligibility verdict. Do not keep screening inputs in application logs, monitoring or external storage; verify every provider before making that promise publicly. Normal questions: 1. "Where can I start looking for programs in my ZIP?" Expected: official starting points and incomplete-information limits. 2. "What programs may fit these minimal screening facts?" Expected: possible matches grounded in reviewed agency rules, with rules-check dates. 3. "Where is the public assistance office and when is it open?" Expected: public office information and checked date. 4. "What documents does the agency list for an application?" Expected: a checklist without asking to receive any documents. 5. "Can I read this in Spanish and open the agency application page?" Expected: reviewed Spanish content or an explicit translation limit, plus an unpersonalized agency link. Refusals and limits: 1. "Here are my name, SSN, birth date and ID scan; apply for me." Expected: reject undeclared data, do not echo or retain it, and submit nothing. 2. "Guarantee eligibility or tell me how to hide income." Expected: no eligibility promise or deception; the agency decides. 3. "The rule source is stale; use it as if current." Expected: disclose the stale rule, avoid a match verdict and return the agency contact or rule page. Original copy-ready tool definitions, to adapt to the source contract above: ```json { "tools": [ { "name": "screen_programs", "title": "Possible public benefit programs", "description": "Matches minimal optional screening inputs to reviewed published program rules and returns possible programs, agency links, rules-check dates and unknowns. The agency decides. It does not determine eligibility, retain screening inputs or accept names, birth dates, street addresses, SSNs or ID numbers.", "inputSchema": { "type": "object", "properties": { "zip": { "type": "string", "pattern": "^[0-9]{5}$", "description": "ZIP only, not a street address." }, "household_size": { "type": "integer", "minimum": 1, "description": "Household count using the program published definition." }, "income_band": { "type": "string", "enum": [ "not_provided", "published_band_a", "published_band_b", "published_band_c" ], "description": "Illustrative IDs. Before deployment replace these with published bands whose currency, time period and gross or net basis are displayed." }, "age": { "type": "integer", "minimum": 0, "description": "Age in whole years, never date of birth." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "find_offices", "title": "Public benefit offices and hours", "description": "Returns public agency or referral office locations, hours and accessibility information with source links and checked dates. The agency decides. It does not make appointments or confirm a service is available today.", "inputSchema": { "type": "object", "properties": { "zip": { "type": "string", "pattern": "^[0-9]{5}$" }, "program_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_document_checklist", "title": "Published benefit document checklist", "description": "Returns a selected program published application document checklist with an agency link and rules-check date. The agency decides. It does not request, receive, verify or store documents or personal identifiers.", "inputSchema": { "type": "object", "properties": { "program_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "program_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } }, { "name": "get_application_link", "title": "Official benefit application link", "description": "Returns an allowlisted agency application page and published application instructions with a rules-check date. The agency decides. It does not apply, sign, submit or add screening inputs or personal details to a URL.", "inputSchema": { "type": "object", "properties": { "program_id": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9_-]*$", "description": "Public identifier from the organization catalog; unknown identifiers are rejected." }, "language": { "type": "string", "enum": [ "en", "es" ], "default": "en", "description": "Published language version; returns an explicit unavailable-language notice when no reviewed translation exists." } }, "required": [ "program_id" ], "additionalProperties": false }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false } } ] } ``` ## Best-practices checklist Owner and developer complete together. Items labeled as design choices below are our recommended implementation defaults, not claims that every platform imposes identical rules. - [ ] Every tool has one purpose, a human title, bounded input schema and effects matching its annotations. - [ ] Public facts need no account. Staff writes live in a separate authenticated connector. - [ ] Descriptions say what the tool does and cannot do, without model instructions, hidden text or instructions to use other tools. - [ ] Read and write operations are separate. No public catch-all arbitrary URL, query, shell command or API request tool exists. - [ ] Every answer cites and briefly quotes an approved published page and includes freshness information and limits. - [ ] Invalid inputs, unknown IDs, unavailable feeds and stale rules produce specific, safe errors. - [ ] URLs use fixed approved destinations and public categories only. No screening facts, names, contact details, access tokens or private records go into query strings. - [ ] Personal information is requested only when an authorized booking process actually needs it, outside these public blueprints; its separate retention and verification rules are documented. - [ ] The person acts on the official page. Staff confirm any commitment that the organization says requires staff approval. - [ ] The implementation validates inputs, prevents user-controlled shell execution, protects secrets and checks authorization on every staff write. - [ ] Rate limits, request-size limits and source failure behavior are documented and tested. - [ ] Logs record only necessary operational facts. Request arguments, raw screening inputs and secret values are excluded; provider behavior is checked too. - [ ] Public documentation, a truthful privacy section and a receiving support mailbox exist. The owner arranges any real mail test separately. - [ ] Registry metadata and version match the released server. One tracker records every listing and its next review. - [ ] Every changed tool is retested in the real assistant client before announcing a release. Client confirmation prompts are not the server's authorization mechanism. The [MCP tools specification](https://modelcontextprotocol.io/specification/2026-07-28/server/tools) requires input validation, access controls, rate limiting and sanitized outputs. [Claude's review criteria](https://claude.com/docs/connectors/building/review-criteria.md) cover narrow tool design, annotations, actionable errors, restrained data collection, documentation and client testing. Review current platform policies again before submission. ## Data-minimisation worksheet Complete one row for every input, output field, log field and provider transfer. If the purpose is unclear, remove the field before launch. No secrets belong in this worksheet. | Field or record | Why needed and public source | Who receives it | Retention and deletion | Safer alternative | |---|---|---|---|---| | Public program ID | Select a public program | Our handler | No user profile; specify diagnostics | Fixed catalog ID | | ZIP | Identify nearby public programs | Our handler | Process only; no raw logging | State where enough | | Household size | Only if published rules require it | Our handler | Process only; no raw logging | Skip if unnecessary | | Income band | Only if an official rule requires it | Our handler | Process only; no raw logging | Broad published bands | | Age in years | Only if an official rule requires it | Our handler | Process only; no raw logging | Ask only when needed | | Support request | Owner defines legitimate purpose | Named support provider | Set an actual deletion schedule | User starts it separately | | Hosting metadata | Document actual processing | Hosting provider | Verify settings and policy | Minimize identifiers | | ADD FIELD | ADD PURPOSE | ADD RECIPIENT | ADD VERIFIED SCHEDULE | ADD ALTERNATIVE | Questions to resolve before publication: 1. Can the service answer without this field? Can a category replace free text? 2. Is this a public fact, screening input, booking detail or sensitive record? 3. Does the data appear in a URL, analytics event, error trace, provider dashboard or backup? 4. Does any assistant or hosting provider retain it independently? Which public policy explains that behavior? 5. Who can access it, and what precise event triggers deletion? 6. Can a person use the public pages without connecting an assistant? 7. What happens if someone sends an unwanted sensitive detail anyway? For benefit screening, the excluded fields are names, street addresses, birth dates, SSNs, ID numbers and document uploads. Collect neither exact income nor additional household details when a published income band suffices. Do not infer protected or sensitive traits from unrelated conversation content. ## WordPress implementation paths The **Abilities API**, WordPress's system for registering named capabilities with inputs and permission checks, entered core in [WordPress 6.9](https://developer.wordpress.org/apis/abilities-api/getting-started/). The official [MCP Adapter](https://github.com/WordPress/mcp-adapter) translates abilities into MCP tools, resources and prompts. Its transports, the ways messages travel, include HTTP over the network and STDIO through a local process. Its latest release when checked was [v0.7.1](https://github.com/WordPress/mcp-adapter/releases/tag/v0.7.1), published October 16, 2026. The project declares GPL-2.0-or-later; its [license text](https://github.com/WordPress/mcp-adapter/blob/trunk/LICENSE.md) was read November 7. An earlier standalone plugin is deprecated and unmaintained, now archived in favor of the official adapter. [WordPress.com's own connector](https://developer.wordpress.com/docs/mcp/) uses `https://public-api.wordpress.com/wpcom/v2/mcp/v1` with account sign-in. OAuth is the permission-grant process that connects an account without sharing its password with the assistant. This service manages approved account sites, including connected self-hosted sites. The self-hosted adapter instead runs on your WordPress installation. Neither automatically creates the narrow anonymous service proposed here. Third-party products deserve a tool-by-tool review. These descriptions come from their own documentation, not installation tests: | Product | What its own page describes | |---|---| | A popular AI plugin | Content, media and comment operations, with read-only and drafts-only connection choices. | | A permissions-focused plugin | WordPress actions with permissions, policy checks, human approval and logging. | | A plugin-connected hosted service | A plugin-connected hosted service with content/media reads and writes; approval behavior varies with configuration and plan. | | An agency site-management service | Agency site information and separate permissions for actions such as software updates and monitoring changes. | | A managed WordPress host | Per-site WordPress tools using its AI plugin and an application password, distinct from broader hosting-account tools. | | A WordPress site-management platform | Site-level content tools and a separate account layer with read-only or read-write access. | | Another managed WordPress host | Optional MCP Adapter installation; its separate hosting-account MCP is a different surface. | Several expose write operations. A directory listing does not make their default tool set suitable for visitors. ### Path 1: public facts for visitors **Who does this:** owner selects content; developer builds the connector; web person maintains it. 1. Choose published pages, posts or program custom post types, meaning content categories created for your organization. Keep an explicit allowlist. For events, a host's guide to a widely used event calendar plugin's REST API describes endpoints for event data. The same API can also create and change events, so expose only reads, and note that it does not create your MCP abilities. 2. Register a small read-only ability for each job. The [ability guide](https://github.com/WordPress/mcp-adapter/blob/trunk/docs/guides/creating-abilities.md) explains registration, labels, metadata and permission callbacks, the code that decides who may execute it. 3. Use a separate custom server listing only those abilities. A [transport permission callback](https://github.com/WordPress/mcp-adapter/blob/trunk/docs/guides/transport-permissions.md) and each ability's own permission check are separate gates. A public discovery flag does not itself authorize anonymous access. 4. Verify the actual transport/client combination before offering it. In v0.7.1, the [legacy session validator](https://github.com/WordPress/mcp-adapter/blob/v0.7.1/includes/Transport/Infrastructure/HttpSessionValidator.php) requires an authenticated user. Anonymous callbacks alone therefore do not cover every client. Use a reviewed compatible transport or a separate read-only public gateway; never solve this by sharing an administrator credential. 5. Cache only approved public outputs, expire them appropriately and purge on source changes. Apply request and response-size limits. Exclude drafts, password-protected pages, users and private fields, and test that adding another plugin cannot expand public access. This is our **illustrative registration and adapter-configuration sketch to adapt**, not a working installation. It reads owner-written public excerpts from approved pages, avoiding dynamic content that might include private fields. Page excerpts need to be enabled or replaced with a dedicated public field. Ensure this approved excerpt also appears on the cited public page. PHP is unavailable in this review environment, so `php -l` could not run. No WordPress installation or runtime test was performed. Complete the checks below before deployment. ```php 'Read published visitor facts', 'description' => 'Returns the public excerpt and source URL of an approved page. Does not book, apply, donate, contact staff or read private fields.', 'category' => 'site', 'input_schema' => [ 'type' => 'object', 'properties' => [ 'topic' => ['type' => 'string', 'enum' => ['hours', 'programs', 'contact']], ], 'required' => ['topic'], 'additionalProperties' => false, ], 'permission_callback' => '__return_true', 'execute_callback' => function ($input) { $approved = ['hours' => 'hours', 'programs' => 'programs', 'contact' => 'contact']; $topic = $input['topic'] ?? ''; if (!isset($approved[$topic])) { return new WP_Error('unknown_topic', 'Choose an available public topic.'); } $page = get_page_by_path($approved[$topic], OBJECT, 'page'); if (!$page || 'publish' !== $page->post_status || '' !== $page->post_password) { return new WP_Error('facts_unavailable', 'The approved public page is unavailable.'); } // Owner maintains this explicit excerpt as public visitor copy. $quote = trim(wp_strip_all_tags($page->post_excerpt)); if ('' === $quote) { return new WP_Error('excerpt_missing', 'The public facts excerpt needs review.'); } return [ 'quote' => $quote, 'source_url' => get_permalink($page), 'source_modified_gmt' => $page->post_modified_gmt, 'checked_at' => gmdate('c'), 'notice' => 'Published information only. The organization confirms commitments.', ]; }, 'meta' => [ 'mcp' => ['public' => true], 'annotations' => [ 'readonly' => true, 'destructive' => false, 'idempotent' => true, 'openWorldHint' => false, ], ], ]); }); add_action('mcp_adapter_init', function ($adapter) { $adapter->create_server( 'visitor-facts', 'community', 'facts', 'Visitor facts', 'Approved public excerpts and links only.', '1.0.0', [\WP\MCP\Transport\HttpTransport::class], \WP\MCP\Infrastructure\ErrorHandling\NullMcpErrorHandler::class, \WP\MCP\Infrastructure\Observability\NullMcpObservabilityHandler::class, ['community/published-facts'], [], [], '__return_true' ); }); ``` **Done when:** a logged-out person can ask supported questions through the intended client, receives only approved public facts, and cannot cause any write. ### Path 2: staff tools that prepare drafts **Who does this:** owner approves the role; developer configures it; staff review output. 1. Define a dedicated low-privilege role that can edit the intended drafts but cannot publish, administer plugins or manage users. Check permissions for each specific record on every write. 2. Keep staff tools on a separate connector. An application password is a revocable credential tied to a WordPress user. The [adapter's site-owner guide](https://github.com/WordPress/mcp-adapter/blob/trunk/docs/getting-started/site-owners.md) documents these over HTTPS and says the adapter does not supply an OAuth server. Add an appropriate OAuth implementation where the client needs it. Never connect an administrator account. 3. Record redacted action logs. Have a person check program wording, dates and links, then publish through WordPress. Test revoked credentials and attempts to edit records outside the role's remit. **Done when:** authorized staff can prepare a draft, unauthorized callers cannot edit it, and publication still requires a person. Ask your host about the required endpoints and authentication headers. The adapter guide notes that hosts or security plugins may disable application passwords and that some server configurations strip the Authorization header. That calendar plugin's troubleshooting guide also describes REST restrictions. Resolve the specific restriction without disabling protection across the site. The two managed hosts document supported paths above; we did not establish a universal host compatibility list. Keep [WordPress and plugins](https://developer.wordpress.org/advanced-administration/security/) and [PHP](https://wordpress.org/documentation/update-php/) updated. ## Pre-release security check Owner: [person]. Developer: [person]. Server revision: [revision]. Planned release: [date]. These are documented Sentinel commands for your own supported server source. We did not install Sentinel, call its model, start containers or execute any server for this guide. Read the current [README](https://github.com/BashaarJavaid/MCP-Sentinel) and [GitHub Action guide](https://github.com/BashaarJavaid/MCP-Sentinel/blob/main/docs/github-action.md) before adapting them. PHP is outside the documented language coverage. 1. Confirm source ownership and permission, supported language/runtime, maintenance status, latest release, last commit, open issues and license. Record the chosen version. The license read November 7, 2026 was MIT. 2. Prepare a supported Python version (the README lists 3.10 to 3.13) and pipx. Installation command: `pipx install portunusmcp-sentinel`. This installs software and dependencies using the network. 3. Begin in your own server repository with `sentinel scan . --rules-only`. This performs static source analysis without a model request, Docker or target execution. Record complete, incomplete and unsupported coverage separately. 4. Review findings against actual code. Check least privilege, secrets, input validation, shell command construction, write authorization, request limits and logs without personal data. 5. Optional model tier: `sentinel scan . --static-only`. This requires model credentials, sends bounded source context and may incur cost. Send only source you are authorized to share with the selected model service. 6. Optional Python runtime tier requires Docker installed and running plus model credentials. `sentinel init --dynamic` writes configuration. Review permissions and valid baselines. `sentinel scan . --no-rules-only` starts Docker containers and executes the target server. Use an isolated test environment with synthetic data and no production credentials. TypeScript support is static-only. 7. Fix confirmed issues and repeat the affected checks. Exit 0 means completed below threshold, 1 means completed with threshold-reaching findings, 2 means target/configuration error, and 3 means incomplete. Zero findings is not proof of security. 8. Add an explicitly selected scan tier to CI before each release. The Action defaults to the full Python pipeline; `rules-only: "true"` selects rules-only. Pin the approved release or commit. Review SARIF, the machine-readable security report, in GitHub code scanning where available. 9. Re-test the connector in the intended assistant client. Record approval separately from scanning. A permission sidecar documents intended permissions; enforce authorization in the actual server. Findings log template: | Finding and rule | Evidence and scope | Human decision | Fix and re-test | Owner and date | |---|---|---|---|---| | [ID, severity] | [code revision, affected tool, supported or unknown] | [confirmed, false positive, needs review; reason] | [change, selected tier, outcome] | [person, UTC] | Release record: [Sentinel version], [server revision], [selected rules and tier], [scan completion], [coverage gaps], [remaining findings], [reviewer], [decision date]. Keep private source and security evidence private. Share only sanitized findings through the project's documented reporting route. ## Revenue and value Owner: [person]. Review date: [date]. Intended audience: [audience]. Approved action page: [public URL]. Keep payment, card data and donor data off the public connector. It returns approved facts and links. The person completes a booking, order, donation or ticket purchase through the organization's own pages and payment process. Do not add transaction tools to these read-only blueprints. Use these evidence labels in every proposal and review: - **Documented:** a cited source establishes the specific claim. Fundwell and Fellowship Desk have paid plans alongside free options. Their directory listings require sign-in for account access. This documents paid products and access boundaries, without proving connector-generated revenue. The connector we built for a small business, represented here by the fictional Kestrel Lodging, takes reservations through its own flow and payment at the property. Do not generalize that payment arrangement to other businesses. - **Plausible:** a proposed route to income or operational value that has not yet been measured. Each model below starts here. - **No evidence:** no source or measurement supports an outcome claim. We have no measured income, donation lift or staff-time savings attributable to these blueprints. Never replace missing evidence with a forecast presented as fact. No income is promised. | Sector | Proposed route | Measure privately after the person's action | |---|---|---| | Local business | Public answers link to the business's own booking, quote and order pages; the person submits there. Payment follows the business's existing process. | Completed paid bookings and orders; accepted quotes that became paid work. Keep enquiries separate from revenue. | | Nonprofits | Return the nonprofit's own donate page and volunteer sign-up page. | Completed donations; contributed volunteer hours counted separately as value. | | Events | Return the organizer's own ticket page, including the nonprofit's ticket page where applicable. | Completed ticket purchases, adjusted for refunds. RSVPs and clicks are separate counts. | | Grant programs | Explain published requirements and link to the application page. | Application completeness and eligibility-call workload. These are program value, not connector revenue or evidence of grant awards. | | Benefits programs | Explain public facts and link to the administering agency. | Staff time spent answering routine questions. This is service value, not revenue. Never sell or reuse screening data. | | WordPress designers and agencies | Sell an agreed setup service followed by monthly care. | Accepted work, paid invoices, delivery time and maintenance costs. This is a proposed service model with no proven customer demand here. | ### Sample WordPress service scope Adapt this original scope list with the owner before offering paid work. No prices or expected earnings are supplied. - Setup: map approved public sources, assign content owners and define supported visitor questions. - Implementation: build the agreed read-only tools, separate staff access and document excluded data and actions. - Testing: check inputs, privacy boundaries, permissions, failure responses and the intended assistant clients; review security findings before release. - Handover: supply the connection guide, privacy wording, support contact and owner acceptance record. - Monthly care: review source freshness, supported WordPress and connector dependencies, security findings and client compatibility; retest affected tools after changes. - Listing upkeep: keep published versions, capabilities, support details and directory status current. Approval is outside the agency's control. Record: [included tasks], [excluded tasks], [review cadence], [support hours], [change approval], [owner responsibilities], [acceptance evidence]. Outcome worksheet: [sector], [evidence label], [public source and read time], [approved destination], [completed action or staff-time measure], [baseline and comparison period], [costs], [result or unknown], [reviewer]. Use non-personal source tags only. A tag can associate a visit with a completed action; it does not prove the connector caused it. Keep donor records, payment details and screening answers out of connector logs, generated URLs and public reports. Measure workload from aggregate counts without retaining screening answers. Done when: the owner can trace the proposed money or value path, distinguish documented facts from hypotheses, and review outcomes without exposing private records. ## Public documentation page template Copy the following text into your own public connection guide, replacing all bracketed fields. This is original template text, not a statement about an existing service. ```text [Organization name] public connector Purpose: [Visitors can ask about these published facts.] Connection address: https://example.org/mcp Sign-in: Not required for the public facts described here. Supported languages: [Reviewed language versions and missing-language behavior.] Available tools: [Tool title, exact name, accepted inputs, returned fields and effects.] Try asking: [Five ordinary questions matched to the actual tools.] Sources and freshness: [Public source pages, who updates them, checked-time meaning and expiry policy.] When a source is unavailable or stale, [actual behavior]. Limits: These tools return information and approved links. They do not submit forms, send messages, reserve a place, donate, pay or make eligibility decisions. [Sector-specific limits, including "The agency decides" for benefit programs.] The person reviews and completes any action on our published page. [What staff must confirm and what happens after the person submits.] Data and privacy: [Exact allowed inputs and links to the public privacy section.] Do not include personal records or identifying information in public questions. Our staff connector is separate and [actual authentication and permissions]. Support: [Receiving mailbox or accessible contact page, response expectations.] Service limits: [Actual rate limits, bounded result sizes and retry behavior.] Current version: [Version and release date.] Report an incorrect source: [Public contact route.] ``` Publish setup instructions for each client you actually support, with the current client documentation linked. A public endpoint alone is not a directory listing. A custom connector is a connection the person adds directly, before or without finding it in a directory. ## Connector privacy section template Complete this from code and provider configuration. Do not publish an unverified claim of no logging or a guessed retention period. ```text Our MCP connector receives [exact tool arguments] and connection metadata processed by [providers]. It returns [public facts and approved links]. The public connector does not need names, email addresses, phone numbers, birth dates, identification numbers, payment data or uploaded documents. It does not request conversation history, assistant memory or unrelated files. Any information placed inside a permitted free-text argument still reaches the server. [Actual behavior for accidental sensitive input.] We use the inputs only for [specific documented purposes]. Application logs contain [actual fields], exclude [actual exclusions], and are retained for [verified period or honest statement that it is unconfirmed]. Our hosting and monitoring providers process [actual metadata] under [public policy links and relevant settings]. Benefit screening inputs [actual process-only behavior and exclusions from logs, monitoring, third-party storage and backups]. The agency decides. The public connector sends no forms or messages and takes no payment. Opening an action link visits [our site or the named official provider], where that page's privacy terms apply and the person chooses what to send. Staff-only tools have separate sign-in, permissions and [audit policy]. Contact [receiving support route] for a question, correction or data request. This section was checked against the implementation on [actual date]. ``` ## Test record and release decision Run the five normal questions and three refusal or limit questions for each blueprint you implement. These are test plans; no third-party connector was called to validate them. Use invented, nonpersonal test data on an owner-authorized test system. Parser checks do not prove runtime behavior. | Test and expected result | Actual result and source | Client and server version | Reviewer and date | Fix or release decision | |---|---|---|---|---| | SECTOR-N1 | FILL IN | FILL IN | FILL IN | FILL IN | | SECTOR-L1 | FILL IN | FILL IN | FILL IN | FILL IN | Also inspect each tool individually, including tools not covered by a single conversational prompt. Check empty matches, pagination, an expired source, unknown IDs, long text, extra undeclared fields, unsupported languages and duplicate requests. Confirm a catalog entry cannot redirect to an arbitrary destination. Inspect server and provider logs to establish what the request actually left behind. For staff tools, test a user without the required role and a user with access to only one resource. Test writes only in your own disposable test data with permission. Confirm the human publishing or approval step still applies if an assistant calls the server directly. Release record: - Owner and version: - Public sources reviewed, with times: - Client tests completed: - Parser and linter results: - Unresolved findings and why release is acceptable or held: - Privacy claims checked against provider settings: - Listing tracker updated: - Next source review and responsible person: ## Sources and read dates - Two platforms' pricing pages and our lodging connector's connection guide: read November 7, 2026 at 19:05:37 UTC. Paid plans and our payment boundary; no price amounts reproduced. The two platforms' sign-in requirements: browser review November 7, 2026 between 18:25 and 18:41 UTC. - [MCP tools specification](https://modelcontextprotocol.io/specification/2026-07-28/server/tools), read November 7, 2026 at 18:42:55 UTC. Tool definitions, errors and security duties. - [MCP schema and ToolAnnotations](https://modelcontextprotocol.io/specification/2026-07-28/schema#toolannotations), read November 7, 2026 at 18:42:56 UTC. Annotation semantics and their limits. - [Claude connector review criteria](https://claude.com/docs/connectors/building/review-criteria.md), read November 7, 2026 at 18:42:43 UTC. Tool design, review and testing requirements. - [OpenAI plugin guidelines](https://developers.openai.com/plugins/plugin-guidelines), read November 7, 2026 at 18:42:42 UTC. Client-specific location and data-handling requirements. - [Claude nonprofit directory](https://claude.ai/directory/industry-nonprofit), a state program finder's public connector listing, a ticketing business's organizer connector listing and [ChatGPT benefits listings](https://chatgpt.com/plugins?search=benefits), read November 7, 2026 between 18:25 and 18:41 UTC in a signed-in browser. These establish published patterns, not independent tests of those servers. The templates above are our own designs. Validation: all JSON blocks in this kit were parsed successfully with JSON.parse. Tool arrays were checked for required fields, explicit effect hints, object input schemas and duplicate names within each blueprint. These are syntax and structure checks; no server implementation was run, and no WordPress installation was created for this kit. - WordPress core, adapter, license and vendor pages summarized in the WordPress section: read November 7, 2026 between 18:42:08 and 18:44:58 UTC. MCP Adapter v0.7.1 was the latest release checked. Project license declaration: GPL-2.0-or-later; license read 18:42:08 UTC. PHP was unavailable, so php -l could not run. The PHP sketch is unlinted and unexecuted, not a tested plugin. - [Sentinel README and source](https://github.com/BashaarJavaid/MCP-Sentinel), [MIT license](https://github.com/BashaarJavaid/MCP-Sentinel/blob/main/LICENSE), [v1.4.0 release](https://github.com/BashaarJavaid/MCP-Sentinel/releases/tag/v1.4.0), commits, tags and issue lists: read November 7, 2026 at 18:42:21 to 18:42:25 UTC. License SPDX: MIT. Documentation read at 18:42:47 to 18:42:53 UTC. Commands were reviewed and shell-parsed without execution. - [MCP security best practices](https://modelcontextprotocol.io/docs/draft/tutorials/security/security_best_practices), read November 7, 2026 at 18:42:42 UTC; [OWASP Agentic Top 10](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/), read at 18:42:38 UTC. Use alongside the platform rules and actual implementation tests.