mcpField
A
add-intent-router

add-intent-router

github.com/redisAgent workflows17411 installsUpdated today
Repository

About add-intent-router

A skill for replacing an agent’s routing decision with Redis Iris Intent Router. It guides developers through defining example-based intents, provisioning the router, wiring one match call, and checking matched and fallback paths.

Key features

  1. 01Define routes and example phrasings in YAML
  2. 02Provision and configure an Intent Router
  3. 03Match messages to ranked intents
  4. 04Attach targets without interpreting them
  5. 05Verify matching and fallback behavior

Use cases

  1. 01Replace keyword or regex routing
  2. 02Replace a classifier call used only for routing
  3. 03Route messages to tools or sub-agents
  4. 04Test empty-result fallback paths

MCP support

The skill recommends using an available docs MCP to check framework routing APIs and Redis Intent Router concepts before coding. If none is available, it directs the developer to inspect the installed package source.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/redis/agent-skills --skill add-intent-router

After installing, type/add-intent-routerin Claude Code to confirm it loaded.

Details

From the project README

Add Intent Router

One match() call in place of the code that decides where a message goes. The Router embeds the message, finds the nearest example phrasings, groups them by intent, applies a threshold, and returns the matching intents best first, each with the target you attached. No match is an empty result, not an error. The routes and their phrasings are content, not code: ask first, write intents.yaml, provision, load, then wire.

1. Discover

Read the project:

  • Find where the agent decides what to do with a message: if "refund" in text, a regex table, a match statement, a classifier prompt ("Classify this message as one of ..."), or a router node or conditional edge in a graph.
  • List every route it can take and what each one does: call a tool, hand off to a sub-agent, pick a prompt, or answer directly.
  • Find real phrasings: test fixtures, logs, the keywords in the if/else, the examples in the classifier prompt.
  • Async agent? amatch and adefine are the async twins; every other method is sync only.

Then ask the developer these five questions, nothing more. A shrug takes the default.

AskIf the answer isConfigure
What are the routes today?A listOne intent each in intents.yaml. Names use letters, digits, ., _ and -
Give three to five real phrasings for each routePhrasingsexamples for that intent. An intent with no examples never matches
What does each route dispatch to?A tool, a sub-agent, a prompttarget: {type, ref, args}. The Router stores it and never interprets it
The code already knowsNo target; dispatch on the intent name
What should happen when nothing matches?Fall back to the general agent (default)Keep the existing default path for an empty result
Ask a clarifying questionThat branch on an empty result
Which embedding model?OpenAI (default)--provider openai --model text-embedding-3-small --dimensions 1536
Anotheriris intent-router service models lists what the deployment offers. The choice is fixed once the Router exists

2. Get current facts from MCP

Do this before writing code. Never guess framework APIs from memory.

  • Framework docs: query an available docs MCP (Context7, or the framework's own) for how the installed version routes: conditional edges, handoffs, or tool choice.
  • Redis docs: if the Redis docs MCP is connected, use it for Intent Router concepts (intents, examples, thresholds).
  • No MCP available: read the installed package source in the virtualenv. Say so in the report.

3. Configure

Write intents.yaml from the answers and commit it: it is the reviewable record of the routes.

intents:
  - name: track_order
    description: Where an order is and when it arrives
    examples: ["where is my order", "track my package", "has my parcel shipped yet"]
    target: {type: tool, ref: orders.track}
  - name: refund_request
    examples: ["I want my money back", "refund this order", "return and refund"]
    target: {type: agent, ref: refunds}
    minScore: 0.4   # stricter than the Router's default for this one

Provision from the terminal on a self-managed suite. A cloud profile refuses the control-plane commands with cloud_unsupported: the person creates the Router in Iris → Intent Router → New Intent Router and its key in Iris → Access & Identity. Add --local for a local stack (it assumes 127.0.0.1:9400 and 9401), or let the person export IRIS_INTENT_ROUTER_SERVICE_URL, IRIS_INTENT_ROUTER_SERVICE_TOKEN, IRIS_INTENT_ROUTER_URL, IRIS_IDENTITY_URL and IRIS_IDENTITY_TOKEN. Full reference: iris intent-router <command> --help (for example iris intent-router service create --help).

iris --json --no-input intent-router service create --name support --provider openai --model text-embedding-3-small --dimensions 1536 --role read --dry-run
iris --json --no-input intent-router service create --name support --provider openai --model text-embedding-3-small --dimensions 1536 --role read --wait --write-env .env
iris --json --no-input intent-router service check <routerId from the result> --env-file .env
Run the CLI as an agent
  1. Always put --json --no-input before the product name. You get one JSON value on stdout, errors as one JSON value on stderr, and no prompts.
  2. Dry-run first: it sends nothing and lists every missing setting. If anything is missing, stop and hand off (step 4) before any write.
  3. Always deliver keys with --write-env PATH (or --write PATH on service key). Never run create or key with --json and no file: that prints the key into your transcript.
  4. On credential_required, stop. Tell the person which variable to set (details.env) and link details.obtain. Never ask for a secret in chat, pass one on the command line, or echo, cat or grep an env file.
  5. On resource_exists, ask whether to --reuse or pick another name. Never delete to retry. If create fails with details.created: true, run the command in details.command.

--write-env .env writes IRIS_INTENT_ROUTER_URL, IRIS_INTENT_ROUTER_ID and IRIS_INTENT_ROUTER_API_KEY. Add the same three names to .env.example with empty values. Never commit .env.

Two keys, never one:

KeyRoleMint
Agent (in .env)read: match and list--role read on create
Authoring, for loading intents.yamlwriteiris intent-router service key ROUTER_ID --role write --write .env.authoring; load it only in the shell that runs intents add, never in the agent's .env

Load the intents with the authoring key. intents add is one atomic batch: an existing name is replaced, and nothing is written if any intent is invalid:

iris --json --no-input intent-router intents add --file intents.yaml
iris --json --no-input intent-router intents list --all

Re-run intents add after every change to intents.yaml.

4. Wire the decision point

Create once at startup:

from redis_iris import IntentRouter

router = IntentRouter.from_env()

Replace the decision with one call:

found = router.match(message)  # await router.amatch(...)
if found.best:
    route = found.best.name  # "track_order"
    target = found.best.target  # what intents.yaml attached, or None
    # dispatch exactly where the old if/else or classifier branch did
else:
    ...  # question 4: the existing fallback path

found.best.score is the score, higher is closer. match(message, limit=3) returns the next candidates, and min_score= overrides every threshold for one call. A limit above the server's cap is rejected, not clamped.

Where it goes (confirm names in step 2):

FrameworkReplace
LangGraphthe router node or the function behind the conditional edge: return the next node from found.best
OpenAI Agents SDKthe triage agent or handoff choice, when it only picks a route
Google ADKthe routing agent or before_agent_callback choice
CrewAIthe manager's delegation choice, when it is a fixed set of routes
Plain loopthe if/else or match statement

Remove what it replaced: the keyword lists, the regex table, the classifier prompt and its model call. Keep the dispatch code; only the choice moves.

The SDK raises on a missing setting or an outage. Ask whether a Router failure may fail the turn; most agents catch it and take the question 4 fallback.

5. Verify

  1. iris intent-router service check ROUTER_ID --env-file .env passes every hop: token, Router READY, Identity Service, a key granting the Router, one data read.
  2. iris intent-router intents list --all shows every intent from intents.yaml with its example count.
  3. iris intent-router match "<a phrasing that is not in the examples>" --limit 3 returns the right intent first.
  4. iris intent-router match "<something no route covers>" returns an empty list.
  5. Run the agent once with each, and show it took the matched route and the fallback.
  6. Unset IRIS_INTENT_ROUTER_API_KEY and confirm ConfigurationError names it.

Wrong intent first: add phrasings to the right intent or raise its minScore, re-run intents add. Everything empty: lower the Router's or the intent's threshold (intents update NAME --min-score). With the noop embedding provider, matching is lexical overlap, not semantic.

6. Report

List the five answers, the intents and example counts in intents.yaml, the embedding model, keys minted and their roles, where match() went and what it replaced, the fallback path, verification output, and anything you could not confirm over MCP.

Comments

Markdown supported