This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content
Note: Maple Route covers only a few official pages, so it can't answer every immigration question and may leave out rules that apply to you. It's a reference for spotting possible options and policy changes, not legal advice. For your situation, please talk to a licensed immigration consultant (RCIC) or a lawyer.
What I Built
Maple Route is a multi-agent AI system that answers questions about a small set of Canadian immigration topics, using only official pages stored in a Sanity Knowledge Base:
- Express Entry points (CRS criteria)
- open work permits for spouses and family members
- post-graduation work permit eligibility
- 2026 changes to the Ontario Immigrant Nominee Program
- a few related canada.ca pages, such as the Global Talent Stream
Four AI agents work on each question: one understands your situation, one reads the relevant Knowledge Base entries, one writes the answer, and one checks every statement against its source. A final code step removes anything the sources don't support. Maple Route tells you which options might apply, and flags a rule you mention if it has changed. If a question is outside these pages, it says so instead of guessing.
I built it with tech workers in mind, because the rules they rely on change often. Express Entry stopped giving points for job offers in March 2025. Spousal open work permits were narrowed. Post-graduation work permit rules have changed several times. But blog posts, forum threads and AI chatbots keep repeating the old versions. People planning a move, often reading in their second language, can't easily tell which version is current, and getting it wrong can cost them months.
You describe your situation in plain words: "I'm a software developer in Toronto with a job offer", or "I read that a job offer gives me 50 extra Express Entry points". Maple Route then:
- answers only from a Sanity Knowledge Base of official pages, never from the model's own memory;
- puts a citation on every statement, and removes any statement it can't back with a source;
- checks the rules you mention, and shows a Changed callout when one is out of date: what you heard, what the current rule says, and the official source;
- says plainly when its sources don't cover your question.
Here's the difference it makes. I asked the same model the same question with and without the Knowledge Base:
Question: I read that a job offer gives me 50 or 200 extra points in Express Entry. Is that still true?
Same model, no Knowledge Base: "Yes — having a valid job offer can still add points in the Express Entry system… NOC 00: 200 points… other skilled: 50 points."
Maple Route: "Job offer points are no longer added to the Comprehensive Ranking System score for any Express Entry candidate. [1]"
⚠ Changed. Before: A job offer grants 50 or 200 extra points in Express Entry. Now: As of March 25, 2025, job offer points have been removed from the CRS for all current and future candidates. — [1] Express Entry: Comprehensive Ranking System (CRS) criteria, Canada.ca
The full side-by-side for all test questions is in eval/results.md.
Demo
Live: https://maple-route.vercel.app
Try one of these:
- I read that a job offer gives me 50 or 200 extra points in Express Entry. Is that still true? (shows the Changed callout)
- Does my spouse get an open work permit if I come to Canada on a work permit?
- I graduated from a Canadian college program two years ago. Can I still get a post-graduation work permit?
- Can I get a work permit in Australia? (it says this is outside its sources instead of guessing)
It's a free project running on free tiers, so there's a daily answer limit shown on the page. Repeated questions are served from a cache.
Code
klee1611
/
maple-route
Multi-agent assistant for Canadian work permit and PR rules, grounded in a Sanity Knowledge Base, with citations and changed-rule detection.
Maple Route
A multi-agent system that answers questions about Canadian work permit and permanent residence pathways for tech workers in Ontario. It answers only from a Sanity Knowledge Base of official pages, cites a source for every claim, and flags rules that are no longer current.
Live: https://maple-route.vercel.app
Information, not legal advice. Not affiliated with the Government of Canada.
Architecture
flowchart LR
U[Browser<br/>Next.js] -->|POST /api/ask<br/>SSE stream| API[FastAPI<br/>Vercel function]
API --> L[(Upstash Redis<br/>limits + cache)]
API --> G
subgraph G[LangGraph]
O[orchestrator] --> P[policy_agent]
P --> S[synthesizer]
S --> V[verifier]
V -->|outdated or unsupported,<br/>up to 2 times| P
V --> F[finalize]
end
P <-->|Context MCP| KB[(Sanity<br/>Knowledge Base)]
V <-->|Context MCP| KB
G -.-> Groq[Groq LLMs]
G -.-> LS[LangSmith]
| Node | Does | Code |
|---|---|---|
| orchestrator | Extracts the user's profile and any rules they state as fact ("premises"). No tools. | app/graph/nodes.py |
| policy_agent | Fixed pipeline: pick ≤ 3 Knowledge Base entries (plus the change timeline) → |
Python (FastAPI, LangGraph) with Groq models, and a Next.js frontend, deployed as one Vercel project.
How I Used Sanity
The Sanity Knowledge Base is the core of Maple Route. It is the agents' only source of policy facts.
What I pointed Sanity Context at. I kept the Knowledge Base small and focused. It has five website sources, all official pages:
| Source | Topic |
|---|---|
| canada.ca: Express Entry CRS criteria | Express Entry points |
| canada.ca: Open work permits for family members | Spouse and family work permits |
| canada.ca: Post-graduation work permit eligibility | Post-graduation work permits |
| canada.ca: Immigration, Refugees and Citizenship | IRCC home page and a few related pages, such as the Global Talent Stream (3 documents) |
| ontario.ca: 2026 OINP updates | Ontario Immigrant Nominee Program changes |
That's deliberately narrow: enough to show the approach on rules that changed recently, not a complete guide to Canadian immigration. Questions outside these pages get "I can't answer this from my sources" instead of a guess.
Because they're website sources, the Knowledge Base can re-check the live pages for changes, so answers follow the current version of each page without a redeploy.
The best surprise: the Knowledge Base builds its own change history. From these pages, the build produced a policy timeline entry with "What is now outdated" and "What is currently active" sections and effective dates. I had planned to hand-model rule changes as separate documents. I didn't need to, because the Knowledge Base did it from the sources.
Which Sanity Context tools the agent uses. The backend connects to a Context MCP endpoint in Knowledge Base mode (read-only, with a read token) and uses two tools:
-
initial_context: the outline of the Knowledge Base's entries. The policy agent uses it to choose which 1–3 entries a question needs, plus the change timeline. -
knowledge_base_read: the full text of those entries, each ending with a numbered list of the sources it was built from.
The endpoint serves only the Knowledge Base, so nothing else competes with it.
What the agents do with the content. The run is a LangGraph graph of five steps:
orchestrator → policy_agent → synthesizer → verifier → finalize
▲ │
└── recheck (max 2 times) ─┘
- Orchestrator: pulls out your situation and any rule you state as fact ("I read that…").
-
Policy agent: reads the chosen entries with
knowledge_base_readand extracts findings. Each finding cites a reference number from the entry's Sources list. - Synthesizer: writes the answer using only those findings.
- Verifier: checks every statement, and every rule you mentioned, against the entry text it cites, including the change timeline. Each one is marked supported, unsupported, outdated or conflict. If something is outdated or unsupported, the draft goes back to the policy agent ("Found a rule that changed — rechecking").
- Finalize (plain code, no LLM): removes unsupported statements and builds the Changed callouts with both sources.
Two design choices kept the answers honest:
- The model never writes URLs. It cites a reference number, and code looks up the title, URL and date in the entry's own Sources list. A citation that isn't in the entry is dropped, so a made-up source can't reach the user.
- Retrieved content is data, not instructions. Every prompt says so, and only statements backed by a Knowledge Base source survive the final step.
The page streams each agent's progress as it happens, shows a "✓ Checked" mark next to each statement, and lists the sources under the answer, so the Knowledge Base's provenance stays visible to the user.
Sanity Project Details
-
Sanity project ID:
xi8sftv7 -
Knowledge Base: the Policy Knowledge Base, served through Sanity Context MCP at
https://api.sanity.io/v1/context/organizations/omqxvfyjj/mcp/maple-route-policy
Maple Route gives information from official sources, not legal advice. For your specific case, talk to a licensed immigration consultant (RCIC) or lawyer. It's an independent project, not affiliated with the Government of Canada.

Top comments (0)