| name | support-add-service |
| description | Research a vendor's support routes and write a new registry entry for them, so the next request to that vendor needs no research at all. Finds the real ticket URL, support and abuse addresses, community forum, status page, plan tiers and response times, required account identifiers, escalation path and pre-contact checks; reaches each target to see whether it actually resolves; records every claim with the date and whether it was confirmed, merely referenced, or inferred; and records the plausible-looking routes that turn out to be dead. Use when a lookup finds no entry for a vendor, or when the user wants to add a service, extend the registry, or teach the plugin about a company they deal with. |
support-add-service
This is how the registry grows. Twilio ships as the reference entry; everything else gets added
here, by the user or by whoever forks the plugin.
Write to ~/.claude-plugins/contact-support/services/<slug>.json unless the user says the entry is meant to be
contributed upstream, in which case write it into the plugin's data/services/ and say that it
will need committing.
Schema: ${CLAUDE_PLUGIN_ROOT}/schema/service.schema.json. Read it. Then read the Twilio entry —
${CLAUDE_PLUGIN_ROOT}/data/services/twilio.json — as the worked example of the level of detail
that makes an entry useful rather than decorative.
Procedure
1. Fix the identity
Slug, name, aliases. Aliases matter more than they look: acquired brands, the bare domain, product
names that route to the same desk. This is what makes lookup work when the user says "SendGrid" and
means Twilio.
Then find the separate desks. Vendors acquire companies and keep their support organisations
apart for years. A product that looks like it belongs to this vendor and is actually handled
elsewhere is the single most expensive routing error there is, and finding it is the highest-value
five minutes of this whole procedure.
2. Find the routes
Search, then read. Look for:
- The ticket or case submission URL, and whether it needs a login.
- Support email addresses — and be sceptical.
support@vendor.com and help@vendor.com are
guessable and often wrong. An address goes in only if the vendor publishes it.
- Abuse, fraud and security addresses, which are usually different from support and usually the only
correct route for their category.
- The community forum. Check whether it still exists; vendors retire forums and redirect to Stack
Overflow, Discourse or Discord, and the old URL often keeps resolving.
- The status page.
- Support plan tiers, prices, and the response time per tier per priority.
- Phone support: which tiers, and whether any number is actually published.
- Sales, for when the blocker is commercial.
Escalate through fetch routes rather than giving up on a page. A vendor page that returns nothing to
a fetcher is usually client-rendered rather than absent — that fact is itself a gotcha worth
recording.
3. Reach each target
For every URL, observe the real status and the redirect chain:
for u in <urls>; do
echo "$u : $(curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}' -A 'Mozilla/5.0' --max-time 20 "$u")"
done
Then read the ones that matter. Both steps are needed, and the reason is the interesting part:
- A 200 can front an empty page. A client-rendered help centre returns 200 with nothing but a
<title> to any non-browser client. The host is up; the page proves nothing.
- A 301 can front a dead resource. A vanity URL redirecting to an expired invite looks perfectly
healthy to a link checker.
- A 403 does not mean gone. Many vendors bot-wall their help centre. Confirm through a browser
before writing it off.
Record what you actually observed in evidence, in enough detail that a later reader can judge the
claim without redoing the work.
3a. Take addresses from hrefs, not from prose
Never record an address you read as text. Extract the link target:
curl -s -A 'Mozilla/5.0' --max-time 30 "<url>" | grep -oiE 'mailto:[^"'"'"'>]{3,60}' | sort -u
A page's visible text and its mailto: href can disagree — Twilio's spam-reporting article prints
spam@twilio.com and links stopspam@twilio.com. When they diverge, the href is operative and the
printed string is what every search snippet, markdown converter and language model has. Record the href
as the channel and the printed string in known_dead, with the mismatch as the reason. This is one
grep and it is the difference between a working address and a dead one.
Raw HTML also beats a rendered read here: pages whose prose is client-rendered often still carry their
mailto: hrefs in the served markup.
3b. When a help centre is unreadable, read the one it replaced
Vendors migrate help centres to client-rendered apps that give a fetcher nothing. The predecessor was
usually server-rendered, article IDs usually survive the migration, and the Wayback Machine usually has
it:
curl -s -o /dev/null -w '%{redirect_url}\n' --max-time 30 -A 'Mozilla/5.0' \
"https://web.archive.org/web/2024/https://<old-help-host>/hc/en-us/articles/<id>-<slug>"
Find candidate article IDs through the CDX index
(https://web.archive.org/cdx/search/cdx?url=<old-host>/hc/en-us/articles/*&fl=original&collapse=urlkey),
which lists every archived article and is the fastest way to discover that a vendor documents things you
did not know to look for — business hours, a no-login fallback, priority definitions.
A fact read this way is confirmed as of the snapshot's date, not today. That is still confirmed,
but the snapshot date belongs in evidence, and where a live page corroborates it, say so.
4. Grade every claim
confirmed — reached or read it directly. Requires evidence; the validator enforces this.
referenced — the vendor links or names it, but it was not reached. A login gate or a bot wall
usually lands here.
inferred — deduced. Rare, and it should make you uncomfortable.
Never promote a guess to confirmed because it is probably right. The whole value of the registry
is that its confident statements are true.
5. Record the dead ends
known_dead is the part of an entry that saves the most time and is the most tempting to skip.
Anything that looked right and was not goes here, with the date and what to use instead: 404s, dead
invites, retired hosts, guessable addresses with no evidence behind them.
This is what stops the next session — and the next revalidation pass — spending the same twenty
minutes rediscovering it.
6. Fill in the operational fields
identifiers[], with where_to_find for each and required_for naming the channels that block
without it. Mark anything that authenticates secret: true so it is recognisable and refusable.
priority_levels[] in the vendor's own words. escalation[] as an ordered ladder with a real
trigger on each rung. before_you_contact[] — the checks that either resolve the issue or preempt
the desk's first question.
good_for and not_for on each channel. not_for is the field that prevents misrouting, so it
deserves as much thought as good_for.
7. Set the revalidation window
revalidate_after_days: 90 for a stable vendor, 30 for one mid-reorganisation, 180 for something
that has not moved in years. Judge by how much churn the research turned up.
last_verified is today's absolute date. verified_by and method say what was actually done and,
importantly, what was not — an entry that admits it could not read the help centre bodies is more
useful than one that quietly implies it did.
8. Validate
"${CLAUDE_PLUGIN_ROOT}/scripts/check_registry.py"
Fix everything it reports before finishing. An entry that fails schema validation will break a
lookup at the worst possible moment — mid-incident.
9. Report
What was found, what could not be confirmed and why, the dead ends recorded, and the revalidation
date. Then offer support-account so the account profile can be filled in while the vendor's
identifier list is fresh.
Guardrails
- One vendor per entry, not one product. Products differ inside an entry via
products and
separate_desks.
- No address, URL or phone number that was not found in a vendor-published source. Third-party
listing sites are a known vector for fake support numbers, and one in this registry would send the
user to a scammer.
- No credentials in the entry.
identifiers[] describes fields; it never holds values.
- Do not pad. An entry with four confirmed channels and an honest
known_dead list beats one with
twelve speculative ones.