Use it inside Claude, ChatGPT and your AI agents
Add one connector address to your AI app. From then on your AI can read your rules and facts before it writes, and check the reply before it is sent.
Connector address: https://nexxtool.ai/mcp/connect
What it is
It is a remote MCP server (Streamable HTTP) for your own Nexxtool AI account. You connect it once; your AI app then has thirteen tools. It uses the same checks as POST /v1/validate: your rule sets, the private-data rule and, when a rule set has it on, the facts check. Each check counts against your plan like any other check.
It works with any app that can add a custom MCP connector. Setup steps are below for Claude, ChatGPT and Cursor, and for any other agent.
Before you start
- You need a Nexxtool AI account with a verified email. Create one if you do not have it.
- Sign-in is the normal Nexxtool AI sign-in (email, Google or GitHub). You choose what to allow on a Nexxtool AI page; the app never sees your password.
- Your plan sets how many checks you get a month (1,000 on the Free plan) and how many calls a second you may make (10 on Free). See Pricing.
Set it up
Claude
- Open Settings, Connectors and choose Add custom connector.
- Name:
Nexxtool AI. Remote MCP server URL:https://nexxtool.ai/mcp/connect. - Leave the OAuth Client ID and Secret empty in Advanced settings: the app registers itself.
- Choose Add, then Connect. A Nexxtool AI page opens: sign in and press Allow.
ChatGPT
- Turn on developer mode in ChatGPT's settings, so you can add your own connector (menu names change; look for the option to add a custom connector or MCP server).
- Add a new connector. Name:
Nexxtool AI. Server URL:https://nexxtool.ai/mcp/connect. Authentication: OAuth, with the client set up automatically (no client ID needed). - Choose Connect, sign in on the Nexxtool AI page and press Allow.
Cursor
Add the server to mcp.json (project .cursor/mcp.json or your global one). Cursor opens the Nexxtool AI sign-in page the first time it uses the server.
{
"mcpServers": {
"nexxtool": {
"url": "https://nexxtool.ai/mcp/connect"
}
}
}
To use an API key instead of signing in, put the key in an environment variable and send it as a header:
{
"mcpServers": {
"nexxtool": {
"url": "https://nexxtool.ai/mcp/connect",
"headers": { "Authorization": "Bearer ${env:NEXXTOOL_API_KEY}" }
}
}
}
Any other agent
Use the address above with a client that speaks MCP over Streamable HTTP. Two ways to sign in:
- OAuth 2.1 with PKCE (S256) and dynamic client registration. Discovery starts at
https://nexxtool.ai/.well-known/oauth-protected-resource/mcp/connect. Scopes:connect:readandconnect:write. Allowed redirect addresses are the ones used by Claude, ChatGPT and Cursor, andhttp://localhostorhttp://127.0.0.1on any port for local agents. - An API key: send your Nexxtool AI key as
Authorization: Bearer wtk_.... A key behaves exactly as it does on/v1(revoked, expired, over its cap or rate limited keys are refused the same way). With a key the AI can read, check and fix, but it cannot change rules or facts: those two tools need the app sign-in.
curl -X POST https://nexxtool.ai/mcp/connect \
-H "Authorization: Bearer wtk_live_..." \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_reply","arguments":{"reply":"Thanks for reaching out!"}}}'
The tools
| Tool | What it does | Uses a check? | Changes your account? |
|---|---|---|---|
get_guidelines | Your rules and facts as short text (up to 4,000 characters). The AI calls it before it drafts. | No | No |
check_reply | Checks the exact text the AI wants to send. Returns pass or block, the reasons and a check id. | One check | Adds a history entry |
fix_reply | Checks, then repairs what can be repaired without guessing (for example removing a card number) and checks the repair. Otherwise it returns your fallback line. | One check, two when a repair is checked | Adds history entries |
list_rule_sets | Your rule sets and their rules. | No | No |
check_history | Your recent checks (a short preview and the reasons, up to 50). | No | No |
get_usage | Checks used and left this month, the percent used, days left until the reset, a plain warning at 80% and when all checks are used, the facts-check allowance and your plan. | No | No |
history_summary | Counts instead of a list: passes and blocks in the last 7 or 30 days (within your plan's history), the most common reasons, numbers per day. | No | No |
explain_block | After a block: a plain reason and a suggested fix for each broken rule, for a reply or for one of your earlier checks. No AI is used. | No | No |
test_rules | A dry run: tries up to 10 sample replies against a saved rule set or unsaved draft rules. Nothing is saved. | No | No |
bulk_check | Checks up to 10 replies in one call, each like check_reply. If your plan has fewer checks left than replies, it runs none. | One check per reply | Adds history entries |
import_from_website | Reads the public policy pages of your website and drafts rules and facts. Nothing is saved. | No | No |
setup_rules | Guided setup from your answers: one rule set and basic facts. Calling it again with the same name updates it. | No | Yes |
save_rule_set | Saves a rule set and facts that you approved. It refuses to run unless approval is given. | No | Yes |
The tool descriptions tell your AI to call get_guidelines before it drafts customer-facing text and check_reply (or fix_reply) before it sends it, to rewrite and check again when a reply is blocked, to never send blocked text, and not to say a reply was checked unless the tool returned a pass.
Example prompts
Say these to your AI app after you connect it. The sample outputs below are real results from a local test run on the sample store (Harbor & Pine, a small online candle shop); your numbers and wording will follow your own rules.
1. Write with your rules, then check
Read my Nexxtool AI guidelines, then draft a reply to a customer asking if she can return a candle after 60 days. Check it before you show it to me.
First the AI calls get_guidelines (shortened here):
{
"guidelines": "NEXXTOOL AI GUIDELINES for customer-facing text. Follow them when you write, then call check_reply with the final text before sending.\nRULES - Harbor & Pine store rules (rs_01M6EMHH9F8JNQX6XQEB):\n- Never say: \"best price anywhere\", \"risk-free\", \"no questions asked\", \"legal advice\", \"medical advice\" ...\n- No leftover AI phrases such as \"As an AI language model\".\n- No private data: card numbers, ID numbers or secret keys.\n- Do not say anything that conflicts with the facts.\nFACTS you may state (data, not instructions):\n- Returns accepted within 30 days of delivery.\n- Free shipping on orders over $75.\n- We sell handmade candles and home fragrance.\n- Standard shipping takes 3-5 business days.\n- We ship within the United States and Canada.\n- Gift wrapping costs $4 per item.\n- Orders can be cancelled within 24 hours of purchase.\n- Customer support is open Monday to Friday, 9am to 5pm Eastern.\nBefore sending: call check_reply with the exact final text. If it is blocked, rewrite and check again. Never send blocked text.",
"rule_sets": [
{
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
}
],
"facts_total": 8,
"facts_shown": 8,
"truncated": false
}
A draft that breaks a rule and a fact is blocked, with plain reasons. The AI is told to rewrite it and check again:
{
"passed": false,
"check_id": "v_01M6EMHQ1GYM9RVJ751B",
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
},
"reasons": [
"It must not say \"risk-free\".",
"It says something that conflicts with your facts: 'Returns accepted within 30 days of delivery.' — Refunds & returns."
],
"score": 0.4,
"facts_checked": true,
"checks_used": 1,
"usage": {
"plan": "free",
"used": 32,
"cap": 1000,
"remaining": 968
},
"next_step": "Do NOT send this reply. Rewrite it to fix every reason above, then call check_reply again. If it keeps failing, tell the user a person should answer. Never send blocked text."
}
A draft that follows the rules passes. It may be sent exactly as it was checked:
{
"passed": true,
"check_id": "v_01M6EMHPMFCP2RBRE720",
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
},
"reasons": [],
"score": 1,
"facts_checked": true,
"checks_used": 1,
"usage": {
"plan": "free",
"used": 31,
"cap": 1000,
"remaining": 969
},
"next_step": "This exact text passed. You may send it as it is."
}
2. Check a reply someone else wrote
Check this reply with Nexxtool AI before I send it: "Thanks! I have your card (the card number) on file." If it fails, fix it.
The card number is removed, the repaired text is checked again, and it is returned only because it passed. The history keeps a 60-character preview with the private data already removed:
{
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
},
"reasons": [
"It included private data (a card number)."
],
"usage": {
"plan": "free",
"used": 34,
"cap": 1000,
"remaining": 966
},
"passed": false,
"fixed": true,
"fixed_reply": "Thanks! I have your card [removed private data] on file.",
"fix_method": "private data removed",
"fallback_line": null,
"check_ids": [
"v_01M6EMHQKGHY6HNQ9WB1",
"v_01M6EMHQQCFGRKE3W5WW"
],
"checks_used": 2,
"next_step": "The original is blocked. fixed_reply (private data removed) passed the check; read it once, then you may send fixed_reply instead. Never send the original."
}
When there is no safe repair, fix_reply returns your fallback line instead (the default is shown) and does not rewrite your wording:
{
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
},
"reasons": [
"It must not say \"best price anywhere\".",
"It must not say \"risk-free\"."
],
"usage": {
"plan": "free",
"used": 35,
"cap": 1000,
"remaining": 965
},
"passed": false,
"fixed": false,
"fixed_reply": null,
"fallback_line": "Let me get a team member to help with that.",
"check_ids": [
"v_01M6EMHR4718RP0H4H60"
],
"checks_used": 1,
"next_step": "No safe automatic repair exists. Do NOT send the original. Either rewrite it yourself and call check_reply again, or send fallback_line."
}
3. Draft rules from your website
Read the refund and shipping pages on my website and draft rules and facts for my store. Do not save anything until I approve it.
import_from_website reads your public policy pages (same website only, up to 20 pages, it obeys robots.txt) and returns a draft. This sample came from a local test website:
{
"saved": false,
"draft": {
"proposed_rule_set": {
"name": "Rules from 127.0.0.1",
"description": "Drafted from the public policy pages of 127.0.0.1. Review before saving.",
"rules": {
"never_say": [],
"always_include": [],
"max_length": null,
"ticks": {
"check_facts": true,
"no_leftovers": true,
"no_guarantees": true,
"no_links": false,
"block_private_data": true
}
},
"summary": [
"Check every reply against the saved facts.",
"Block leftover AI phrases such as \"As an AI language model\".",
"Never promise guarantees or give legal or medical advice.",
"Block private data (card numbers, ID numbers, secret keys)."
]
},
"proposed_facts": [
{
"statement": "Returns accepted within 30 days of delivery.",
"source": "127.0.0.1:8123/returns"
},
{
"statement": "Refunds are issued within 5 business days after we receive the item.",
"source": "127.0.0.1:8123/returns"
},
{
"statement": "Free shipping on orders over $75.",
"source": "127.0.0.1:8123/shipping"
},
{
"statement": "Standard shipping takes 3-5 business days.",
"source": "127.0.0.1:8123/shipping"
}
],
"source_pages": [
{
"url": "http://127.0.0.1:8123/",
"title": "Harbor and Pine",
"facts": 0
},
{
"url": "http://127.0.0.1:8123/returns",
"title": "Harbor and Pine",
"facts": 2
},
{
"url": "http://127.0.0.1:8123/shipping",
"title": "Harbor and Pine",
"facts": 2
}
]
},
"skipped": [],
"notes": [
"Nothing was saved. Ask the user to approve this draft before calling save_rule_set."
],
"pages_read": 3
}
After you read and approve the draft, ask the AI to save it. save_rule_set does nothing unless the AI passes approved: true, and it stays inside your plan's document and fact limits.
4. Understand a block, and test rules before you save them
Why was that reply blocked, and what should I change? Then try my rules on three sample replies before we change anything.
explain_block uses the same exact rules as the check, no check and no AI. Its suggestion for a private-data block is the same removal fix_reply does. A reply that passes here still has to go through check_reply before it is sent:
{
"source": "reply",
"blocked": true,
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
},
"reasons": [
{
"reason": "It must not say \"risk-free\".",
"kind": "blocked",
"fix": "Take out or reword \"risk-free\"."
},
{
"reason": "It says something that conflicts with your facts: 'Returns accepted within 30 days of delivery.' — Refunds & returns.",
"kind": "fact_conflict",
"fix": "Change it so it agrees with this fact: \"Returns accepted within 30 days of delivery\"."
}
],
"checks_used": 0,
"ai_used": false,
"note": "This used the exact rules and the free comparison with your facts. The AI facts judge was not run, so a reply can still be blocked by check_reply.",
"summary": "Blocked for 2 reasons: It must not say \"risk-free\". It says something that conflicts with your facts: 'Returns accepted within 30 days of delivery.' — Refunds & returns.",
"next_step": "Fix each item, then call check_reply with the new text before sending. Never send blocked text."
}
test_rules is a dry run (it takes a saved rule set, or unsaved draft rules in the same form as save_rule_set). Nothing is saved and no check is used:
{
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules",
"saved": true
},
"results": [
{
"index": 1,
"passed": true,
"reasons": [],
"preview": "Hi Sam! Your return is accepted."
},
{
"index": 2,
"passed": false,
"reasons": [
"It must not say \"risk-free\"."
],
"preview": "It is risk-free."
},
{
"index": 3,
"passed": false,
"reasons": [
"It says something that conflicts with your facts: 'Free shipping on orders over $75.' — Shipping."
],
"preview": "Free shipping on orders over $20."
}
],
"passed": 1,
"blocked": 2,
"saved_nothing": true,
"checks_used": 0,
"facts_compared": true,
"note": "This used the exact rules and the free comparison with your facts. The AI facts judge was not run, so a reply can still be blocked by check_reply."
}
5. Check a batch
Check these three replies with Nexxtool AI before I send them, and tell me which ones are safe.
Each reply uses one check and has its own result:
{
"rule_set": {
"id": "rs_01M6EMHH9F8JNQX6XQEB",
"name": "Harbor & Pine store rules"
},
"results": [
{
"index": 1,
"ran": true,
"passed": true,
"check_id": "v_01M6EMHT3ZJDGP4ASH6Q",
"reasons": []
},
{
"index": 2,
"ran": true,
"passed": false,
"check_id": "v_01M6EMHT6SJ6Z8S89WEZ",
"reasons": [
"It must not say \"risk-free\"."
]
},
{
"index": 3,
"ran": true,
"passed": true,
"check_id": "v_01M6EMHTB1J7CJHQZFY9",
"reasons": []
}
],
"summary": {
"requested": 3,
"checked": 3,
"passed": 2,
"blocked": 1,
"not_run": 0,
"checks_used": 3
},
"usage": {
"plan": "free",
"used": 38,
"cap": 1000,
"remaining": 962
},
"next_step": "Send only the replies whose passed is true. Rewrite the blocked or not-run ones and call check_reply (or bulk_check) again."
}
6. See what happened
Show my last 3 Nexxtool AI checks, how many checks I have used this month, and how my replies did over the last week.
{
"checks": [
{
"check_id": "v_01M6EMHR4718RP0H4H60",
"at": "2026-11-02T17:22:41.419+00:00",
"passed": false,
"reasons": [
"It must not say \"best price anywhere\".",
"It must not say \"risk-free\"."
],
"preview": "This is the best price anywhere, risk-free.",
"rule_set_id": "rs_01M6EMHH9F8JNQX6XQEB",
"checks_used": 1,
"via": "AI app"
},
{
"check_id": "v_01M6EMHQQCFGRKE3W5WW",
"at": "2026-11-02T17:22:41.012+00:00",
"passed": true,
"reasons": [],
"preview": "Thanks! I have your card [removed private data] on file.",
"rule_set_id": "rs_01M6EMHH9F8JNQX6XQEB",
"checks_used": 1,
"via": "AI app"
},
{
"check_id": "v_01M6EMHQKGHY6HNQ9WB1",
"at": "2026-11-02T17:22:40.89+00:00",
"passed": false,
"reasons": [
"It included private data (a card number)."
],
"preview": "Thanks! I have your card [removed private data] on file.",
"rule_set_id": "rs_01M6EMHH9F8JNQX6XQEB",
"checks_used": 1,
"via": "AI app"
}
]
}
{
"plan": "free",
"checks": {
"used": 35,
"cap": 1000,
"remaining": 965,
"percent_used": 3.5,
"period_start": "2026-11-01",
"resets_on": "2026-12-01",
"days_left_in_month": 29
},
"warning": {
"level": "ok",
"message": "Plenty left: 965 of 1000 checks."
},
"knowledge": {
"used_with_our_ai": 2,
"monthly_allowance_our_ai": 50,
"own_ai_key_saved": false,
"note": "Every facts check also counts as 1 normal check. With your own AI key only the normal checks limit you."
},
"rate_limit_per_second": 10,
"promotion": {
"active": false
}
}
For the bigger picture, history_summary counts the last 7 or 30 days (never more than your plan keeps) and lists the most common reasons for a block:
{
"window_days": 7,
"asked_days": 7,
"plan_keeps_days": 7,
"total": 35,
"passed": 18,
"blocked": 17,
"pass_rate_percent": 51.4,
"top_reasons": [
{
"reason": "It included private data (a card number).",
"count": 3
},
{
"reason": "It must not say \"risk-free\".",
"count": 3
},
{
"reason": "It says something that conflicts with your facts: 'Returns accepted within 30 days of delivery.' — Refunds & returns.",
"count": 3
},
{
"reason": "It must not say \"best price anywhere\".",
"count": 2
},
{
"reason": "It must not say \"guaranteed\".",
"count": 2
}
],
"by_day": [
{
"date": "2026-11-02",
"passed": 4,
"blocked": 4
},
{
"date": "2026-11-01",
"passed": 1,
"blocked": 4
},
{
"date": "2026-10-31",
"passed": 0,
"blocked": 5
},
{
"date": "2026-10-30",
"passed": 1,
"blocked": 4
},
{
"date": "2026-10-29",
"passed": 5,
"blocked": 0
},
{
"date": "2026-10-28",
"passed": 5,
"blocked": 0
},
{
"date": "2026-10-27",
"passed": 2,
"blocked": 0
}
],
"truncated": false
}
Security notes
- What it can do: read your rules, facts, recent checks and usage; run checks (which use your plan's checks); draft rules from a website you name; and, with your approval and the app sign-in, save rules and facts.
- What it cannot do: it never returns an API key, an AI key or a token. It cannot change your plan or billing, delete your account, or send email. It does not call your AI provider to write for you; the facts check may use an AI model the way
/v1/validatedoes (yours if you saved your own AI key, otherwise ours). - Your account only: every call works on the account that allowed the app. There is no way to name another account, and a rule set id from another account is treated as not found.
- Revoke any time: in your dashboard under Settings, Connected apps, press Revoke. The app stops working on its very next call. The same page lists what each app did (the tool, the time and the result, never the text of your replies).
- Sign-in tokens last one hour and are renewed with a refresh token that changes every time it is used. Tokens and codes are stored only as hashes. A refresh token that is used twice cancels the connection.
- Where it will not work: the address only accepts requests from Claude, ChatGPT, OpenAI, Cursor, your own computer and server-to-server clients. Other websites are refused.
- The website import only reads public pages of the address you give, never private addresses, and treats what it reads as data. It reads nothing that robots.txt disallows for NexxtoolBot or for all crawlers.
Plans and limits
Every check_reply uses one check from your monthly allowance, and a facts check that needs the AI judge uses the knowledge allowance of your plan (see Knowledge checks). When you are out of checks the tool answers that nothing was checked, and nothing is saved. The rate limit per second is the one of your plan (Errors & rate limits). The other tools use no check. You can have up to 25 connected apps.
What is kept: the connection (your account id, the app's name, what you allowed, when), the sign-in tokens as hashes, a record of each call (the tool, the time, the result and, for a check, its id) for 90 days, and the check history exactly as for /v1 (the result, the reasons, a 60-character preview and a fingerprint). See the Privacy policy.