Skip to content
Nexxtool AI

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

Set it up

Claude

  1. Open Settings, Connectors and choose Add custom connector.
  2. Name: Nexxtool AI. Remote MCP server URL: https://nexxtool.ai/mcp/connect.
  3. Leave the OAuth Client ID and Secret empty in Advanced settings: the app registers itself.
  4. Choose Add, then Connect. A Nexxtool AI page opens: sign in and press Allow.

ChatGPT

  1. 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).
  2. 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).
  3. 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:

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

ToolWhat it doesUses a check?Changes your account?
get_guidelinesYour rules and facts as short text (up to 4,000 characters). The AI calls it before it drafts.NoNo
check_replyChecks the exact text the AI wants to send. Returns pass or block, the reasons and a check id.One checkAdds a history entry
fix_replyChecks, 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 checkedAdds history entries
list_rule_setsYour rule sets and their rules.NoNo
check_historyYour recent checks (a short preview and the reasons, up to 50).NoNo
get_usageChecks 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.NoNo
history_summaryCounts 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.NoNo
explain_blockAfter 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.NoNo
test_rulesA dry run: tries up to 10 sample replies against a saved rule set or unsaved draft rules. Nothing is saved.NoNo
bulk_checkChecks 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 replyAdds history entries
import_from_websiteReads the public policy pages of your website and drafts rules and facts. Nothing is saved.NoNo
setup_rulesGuided setup from your answers: one rule set and basic facts. Calling it again with the same name updates it.NoYes
save_rule_setSaves a rule set and facts that you approved. It refuses to run unless approval is given.NoYes

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

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.