MCP Connector Lint

Documentation

Everything needed to connect MCP Connector Lint and to reproduce every check locally.

Connect

Remote MCP endpoint: https://mcp-lint.superintelligencesystems.ca/mcp (Streamable HTTP, JSON responses, no authentication).

In Claude, add a custom connector with that URL, then confirm three tools appear: validate_manifest, check_tool_annotations and lint_listing_text. Any MCP client that speaks Streamable HTTP can use the same endpoint.

Tool input

validate_manifest

{
  "manifest": {
    "name": "Example Connector",
    "url": "https://api.example.com/mcp",
    "transport": "streamable-http",
    "authentication": "none",
    "service_domain": "example.com",
    "tools": [ /* tools/list entries or simplified objects */ ],
    "listing": { /* optional listing draft; checked with lint_listing_text rules */ }
  },
  "expect": "read-only"
}

check_tool_annotations

{ "tools": [ /* raw tools/list entries, or simplified objects with top-level readOnlyHint */ ], "expect": "read-only" }

lint_listing_text

{
  "listing": {
    "name": "Example Connector",
    "one_liner": "Checks a connector before it is submitted to the directory.",
    "description": "Long description, up to 2,000 characters.",
    "categories": ["Developer tools"],
    "docs_url": "https://example.com/docs",
    "privacy_url": "https://example.com/privacy",
    "support_contact": "support@example.com",
    "reviewer_note": "No account needed",
    "icon_url": "https://example.com/icon.png",
    "slug": "example-connector",
    "authentication": "none"
  }
}

Output

{
  "ok": false,
  "verdict": "fail",
  "ruleset": "2026-11-03.1",
  "summary": { "errors": 2, "warnings": 1, "infos": 0 },
  "findings": [
    { "rule": "MNF-008", "severity": "error", "path": "manifest.url",
      "message": "host \"localhost\" is a loopback or private address",
      "fix": "Publish the server on a public HTTPS hostname." }
  ],
  "guidance": "Fix the 2 blocking errors before submitting. Warnings are advisory, but each one is the kind of thing a reviewer notices."
}

ok is false only when there is a blocking error. Findings are sorted and de-duplicated, so identical input produces identical output. A validation failure is a result, not an error: the call succeeds and returns the report.

Rules

58 deterministic rules across the three tools. The rationale column cites the directory requirement each rule encodes.

RuleSeverityCheckWhy
MNF-001errorManifest must be a JSON objectEvery other check needs named fields; an array or scalar has none.
MNF-002errorServer name is requiredThe directory shows the server name and reviewers use it to identify the connector.
MNF-003warningServer name over 100 charactersThe listing name field is capped at 100 characters; a longer server name will not fit it.
MNF-004errorLocal transport cannot be listedThe directory requires a remote server; stdio or local-only transports are refused.
MNF-005warningSSE transport is legacyStreamable HTTP is the current remote transport; SSE still works but is the older spec revision.
MNF-006errorRemote URL is requiredThe portal's first step asks for the connector URL; there is nothing to scan without it.
MNF-007errorURL must use HTTPSConnector URLs must be remote HTTPS; plain HTTP and WebSocket URLs are refused.
MNF-008errorURL points at a loopback or private hostA localhost or RFC 1918 address is not reachable by the reviewer's machine or the portal scan.
MNF-009errorStatic bearer token authentication blocks listingDirectory auth is OAuth 2.0 for account-scoped tools or none for public data; a static token is refused.
MNF-010warningAuthentication mode is missing or unrecognisedThe portal asks how users sign in, so the manifest should state none or OAuth 2.0 explicitly.
MNF-011errorManifest must expose at least one toolA connector with no tools has no review surface and no reason to be listed.
MNF-012warningFirst-party service domain is not declaredThe directory requires the server to call its own first-party API; declaring the service domain makes that checkable.
MNF-013errorServer URL does not match the declared service domainThe server domain must match the service it fronts; a mismatch is how proxy servers get refused.
MNF-014warningManifest and listing names differReviewers match the connector to its listing; two different names for one product read as two products.
ANN-001errorTool entry is not an objecttools/list returns objects; anything else cannot carry a name or annotations.
ANN-002errorTool name is requiredAn unnamed tool cannot be called or reviewed.
ANN-003errorTool name over 64 charactersThe directory caps tool names at 64 characters, snake_case or kebab-case.
ANN-004warningTool name is not snake_case or kebab-caseThe directory accepts snake_case or kebab-case names; spaces and mixed case are flagged in review.
ANN-005errorTool title is requiredThe portal flags tools whose title is missing; the title is the human label shown to users.
ANN-006warningTool title is longTitles are labels; a long sentence is hard to scan in the connector's tool list.
ANN-007errorTool description is requiredThe description is what the model reads to decide when to call the tool.
ANN-008warningTool description is very shortA description under 20 characters cannot state what the tool returns.
ANN-009errorTool has no side-effect annotationEvery tool must set readOnlyHint true, or destructiveHint, so clients know what it does.
ANN-010errorreadOnlyHint and destructiveHint are both trueThe two hints contradict each other; clients use them to decide whether to ask for confirmation.
ANN-011warningTool character is ambiguousreadOnlyHint false with destructiveHint false says the tool acts on data but hides what kind of action it takes.
ANN-012warninginputSchema is missing or not an object schemaMCP expects an object JSON Schema so clients can validate arguments and render them.
ANN-013warningDescription contains instructions to the modelTool descriptions describe the tool; hidden instructions or prompt-injection phrasing are refused in review.
ANN-014warningDescription contains a URL, contact or promotionCross-promotion and contact details belong in listing fields, not tool descriptions.
ANN-015warningWrite-verb name is marked read-onlyA create/update/delete style name with readOnlyHint true is a contradiction a reviewer will test.
ANN-016warningRead-verb name is marked destructiveA get/list style name with destructiveHint true is a contradiction a reviewer will test.
ANN-017errorDuplicate tool nametools/list must be unambiguous; duplicate names make a call target undefined.
ANN-018errorDestructive tool in a read-only connectorThe caller declared the connector read-only, so a destructive tool is a contract mismatch.
LST-001errorListing name is requiredThe portal cannot save a listing without a name.
LST-002errorListing name over 100 charactersThe directory caps the listing name at 100 characters.
LST-003warningListing name has stray whitespaceLeading, trailing or doubled spaces are invisible in review and look careless in the directory.
LST-004errorOne-liner is requiredThe portal asks for a one-liner; it is the line that appears under the name.
LST-005errorOne-liner over 200 charactersThe directory caps the one-liner at 200 characters.
LST-006warningOne-liner is very shortUnder 20 characters the one-liner cannot say what task the connector completes.
LST-007errorDescription is requiredThe description is where the listing explains what each tool does and what it does not do.
LST-008errorDescription over 2,000 charactersThe directory caps the description at 2,000 characters.
LST-009warningDescription is thinUnder 200 characters rarely covers what each tool does, who it is for and what it does not do.
LST-010errorCategories must number 1 to 5The listing accepts one to five categories.
LST-011warningCategories contain duplicates or empty valuesA repeated or blank category is a form error reviewers have to sort out.
LST-012errorDocumentation URL is requiredThe portal requires a documentation URL, and it must resolve.
LST-013errorDocumentation URL is not HTTPSDocumentation links are fetched by reviewers; plain HTTP or a malformed URL fails the check.
LST-014errorPrivacy-policy URL is requiredThe portal requires a privacy-policy URL for every connector.
LST-015errorPrivacy-policy URL is not HTTPSThe privacy link is clicked in review; plain HTTP or a malformed URL fails the check.
LST-016errorSupport contact is requiredThe listing must name a support route a user can actually reach.
LST-017warningSupport contact looks like a placeholderexample.com, todo and tbd addresses do not reach anyone.
LST-018warningUnverifiable superlative in the copySuperlatives such as best or world-class are not checkable and draw reviewer questions.
LST-019warningContact details inside listing textThe directory asks for contact details in their own fields, not inside the name, one-liner or description.
LST-020warningInstructions to the model inside listing textListing copy is read by people; instruction or prompt-injection phrasing is refused in review.
LST-021warningSlug is missing or invalidThe slug is permanent once published; it should be lowercase, hyphenated and short.
LST-022warningIcon is missingThe listing asks for an icon; a connector without one ships an unfinished card.
LST-023errorIcon URL is not HTTPSIcons should be served over HTTPS; a malformed or insecure icon URL fails the asset check.
LST-024warningAuthless listing has no reviewer noteFor authless connectors the portal asks for a note such as "no account needed"; leaving it blank stalls review.
LST-026errorListing payload is not a JSON objectThe listing fields are read by name; an array or scalar has none.
LST-025warningReviewer note mentions credentials for an authless connectorIf the connector needs no account, a note containing a password or token contradicts it.

Limits

REST API

Same engine, same report, for testing outside an MCP client:

POST /api/v1/validate-manifest
POST /api/v1/check-tool-annotations
POST /api/v1/lint-listing-text
GET  /health
GET  /rules

The request body is the tool argument object shown above. Responses are application/json; errors are {"error":{"code":"…","message":"…"}} with a 4xx status and an actionable message.

Run it locally

npm install
npm test          # deterministic suite
npm run dev       # wrangler dev, http://localhost:8787
npm run typecheck

Source and issue tracker: https://github.com/devops-gm88/mcp-connector-lint.