Verified answers on your platform
Advisor returns the text of the law; your agent writes the answer. The verified-answer gates make every statement of law in that answer a verbatim quotation of Advisor output, with its path, compilation, as-at date, link and verification label. This page says how an agent on your own stack receives them, and how your code checks the result before a user sees it.
"Verified" has one meaning in an answer: the passage's anchor.label, which says whether Advisor compared that text with the authorised PDF on the Federal Register. The verifier script below checks something else: that a quotation matches what Advisor returned.
Before you begin
- A partner API key. See Partner API keys.
- Python 3.9 or later where the verifier runs. It imports nothing outside the standard library.
What your agent already receives
Advisor sends the gates three ways. Which of them reach your model depends on your agent framework, not on Advisor.
| Channel | What it carries | Reaches the model when |
|---|---|---|
| Server instructions | Six rules: call a tool before stating any law, quote text exactly, read the whole section, cite each passage, give its anchor.label, say what Advisor does not hold | Your framework passes the server's instructions to the model |
| Tool descriptions | get_provision_text, search_provisions and find_definition point to the gates | Always: a model sees the description of every tool it can call |
| MCP prompts | lawatlas-verified-answer (the gates, the answer shape and the verifier script) and lawatlas-research (the tool sequence and traps for each kind of question) | Your code calls prompts/get and gives the result to the model |
Many frameworks pass tool descriptions to the model but not server instructions or prompts. Check yours. Where it does not pass them, load the gates yourself with one of the steps below.
The kit
Generated from the same files the server serves as prompts, so the kit and the server cannot say different things at the version they were published with.
| File | For |
|---|---|
advisor-skills.zip | Any loader of Agent Skills folders (SKILL.md plus scripts/): the Claude Agent SDK, Claude Code |
advisor-system-prompt.txt | Any other model: both skills and the verifier script in one text, for the system prompt |
lawatlas-plugin.zip | Claude Code users who sign in with an Advisor subscription. It holds no place for a key, so a partner platform does not use it |
Steps
- Load the gates into your agent. Fetching the prompts when your agent starts is the most reliable way: you always get the version the server is running.
Fetch the prompts
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def advisor_system_prompt() -> str:
headers = {"Authorization": f"Bearer {os.environ['LAWATLAS_API_KEY']}"}
async with streamablehttp_client("https://advisor.lawatlas.ai/api/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
parts = []
for name in ("lawatlas-verified-answer", "lawatlas-research"):
prompt = await session.get_prompt(name)
parts += [m.content.text for m in prompt.messages]
return "\n\n".join(parts)
Agent Skills folder
# Claude Agent SDK or Claude Code: put both skills where your agent loads skills from.
curl -sO https://lawatlas.ai/advisor-kit/advisor-skills.zip
unzip advisor-skills.zip -d .claude/skills/
System prompt file
# Any other model: add this text to the agent's system prompt.
curl -s https://lawatlas.ai/advisor-kit/advisor-system-prompt.txt -o advisor-system-prompt.txt
- Check every quotation with
verify_passage. For each passage of law in the agent's draft, call it with the passage and the provision'slink.url. It compares the passage with the text Advisor stores, so it catches a quotation the agent changed, whatever the agent's own records say. Show the answer only when every passage answersmatch. The call is free.
import json
async def quotation_matches(session, passage: str, link_url: str) -> bool:
result = await session.call_tool("verify_passage", {"passage": passage, "link": link_url})
return json.loads(result.content[0].text).get("verdict") == "match"
- Build the evidence from the tool results your code holds. The skill asks the agent to copy each Advisor result into an evidence file. Your code already holds those results, so write the evidence from them instead: the agent's copy can then no longer agree with a mistake of its own.
import json
def evidence_from(results) -> str:
"""The text of each get_provision_text and find_definition result, as returned."""
out = []
for result in results:
body = json.loads(result.content[0].text)
for item in [body, *(body.get("result") or [])]:
if isinstance(item, dict) and item.get("text"):
link = item.get("link") or {}
label = (item.get("anchor") or {}).get("label", "not returned")
out.append(f"## {item.get('pinpoint', '')} | {link.get('structure_path', 'no stable address')} | {label}")
out.append(item["text"])
return "\n".join(out)
- Run the verifier before the answer is shown. The script is
lawatlas-verified-answer/scripts/advisor_verify.pyinadvisor-skills.zip, and the same source is at the end of thelawatlas-verified-answerprompt. Write the evidence and the agent's draft answer to files, run it, and show the answer only when it exits 0. It checks the answer's shape: every quotation followed by its path, compilation, date, link and verification label. A model can skip a step it was told to take; your code does not.
python3 advisor_verify.py evidence.txt answer.md
Check it worked
Ask your agent "What does section 181 of the Corporations Act 2001 say?". The answer opens with an As at: line naming LawAtlas.ai MCP and the Act's register identifier. Each quotation is followed by a Path: line giving the structural path, the compilation, the as-at date, the Advisor link and Checked: with the passage's anchor.label. The verifier exits 0 and prints VERIFIED COPY.
What to do if it did not
| Problem | Cause | Solution |
|---|---|---|
| The agent states law without calling a tool | Your framework passes neither the server instructions nor the prompts | Load the gates with step 1 |
quoted passage not found verbatim in evidence | The agent paraphrased inside quotation marks, or quoted a search snippet | Quote only from get_provision_text or find_definition, exactly as returned |
Path line does not end with 'Checked:' | The agent left out the passage's verification label | Every passage carries its own anchor.label, as returned |
reading cites a provision not in evidence | The reading relies on a section the agent never fetched | Fetch and quote that section, or remove the reference |