Tag Matching¶
Smart service selection with ± operators
Overview¶
When multiple providers offer the same capability, tags determine which one gets selected. MCP Mesh uses a scoring system with preference operators.
Tag Operators¶
| Operator | Prefix | Meaning | Effect |
|---|---|---|---|
| Required | none | Must be present | Provider rejected if missing |
| Preferred | + | Bonus if present | Higher score if present |
| Excluded | - | Must NOT be present | Provider rejected if present |
Examples¶
# Required: must have "claude"
# Preferred: bonus for "opus"
# Excluded: never use "experimental"
tags = ["claude", "+opus", "-experimental"]
Scoring Algorithm¶
Point Values¶
| Tag Type | Points |
|---|---|
| Required (present) | 5 points |
| Preferred (present) | 10 bonus points |
| Preferred (missing) | 0 points |
| Excluded (present) | Provider eliminated |
Scoring Example¶
Available providers:
# Provider A: claude-haiku
tags = ["claude", "haiku", "fast"]
# Provider B: claude-sonnet
tags = ["claude", "sonnet", "balanced"]
# Provider C: claude-opus
tags = ["claude", "opus", "premium"]
# Provider D: claude-experimental
tags = ["claude", "experimental"]
Consumer request:
Scoring:
| Provider | Calculation | Score | Result |
|---|---|---|---|
| claude-haiku | claude(5) | 5 | Candidate |
| claude-sonnet | claude(5) | 5 | Candidate |
| claude-opus | claude(5) + opus(10) | 15 | SELECTED |
| claude-experimental | ELIMINATED | - | Has "experimental" |
Use Cases¶
Cost Optimization¶
# Prefer cheaper models, exclude premium
@mesh.tool(dependencies=[{
"capability": "llm",
"tags": ["claude", "+haiku", "-premium"]
}])
Quality Prioritization¶
# Prefer highest quality
@mesh.tool(dependencies=[{
"capability": "llm",
"tags": ["claude", "+opus", "+premium"]
}])
Production Safety¶
# Never use experimental or beta
@mesh.tool(dependencies=[{
"capability": "database",
"tags": ["postgres", "-experimental", "-beta", "-staging"]
}])
Multi-Preference¶
# Multiple preferences (additive scoring)
@mesh.tool(dependencies=[{
"capability": "storage",
"tags": [
"s3", # Required
"+fast", # Prefer fast
"+ssd", # Prefer SSD
"+replicated", # Prefer replicated
"-beta" # Exclude beta
]
}])
Tie Breaking¶
The resolver's tiebreaker is HighestScoreThenVersion:
- Score — highest tag-match score wins
- Version — among equal scores, higher semver wins
- Agent ID — among equal scores and versions, the lowest agent ID wins
Exactly one candidate is selected, and the sort is stable, so an unchanged topology resolves the same way every time. See Tiebreaker for the canonical description.
Combining with Versions¶
Tags work with version constraints:
@mesh.tool(dependencies=[{
"capability": "api",
"tags": ["rest", "+v2", "-deprecated"],
"version": ">=2.0.0,<3.0.0"
}])
Both tags AND version must match.
Namespace Interaction¶
Tags operate within namespaces:
@mesh.tool(dependencies=[{
"capability": "database",
"tags": ["+primary"],
"namespace": "production" # Only search production
}])
Best Practices¶
1. Use Descriptive Tags¶
# ✅ Good - clear categories
tags = ["llm", "claude", "sonnet", "balanced", "production"]
# ❌ Bad - vague
tags = ["service", "v1"]
2. Required + Preferred¶
# ✅ Good - required base, preferred optimization
tags = ["claude", "+opus", "+fast"]
# ❌ Bad - all required (too strict)
tags = ["claude", "opus", "fast"] # May find nothing
3. Safety Exclusions¶
# ✅ Always exclude unsafe options in production
tags = ["database", "-experimental", "-beta", "-test"]
4. Document Tag Conventions¶
# Project tag conventions:
# - llm providers: claude, openai, local
# - quality tiers: haiku, sonnet, opus
# - environments: production, staging, development
# - stability: stable, beta, experimental
Debugging¶
Check Available Tags¶
curl http://localhost:8000/agents | jq '.agents[].capabilities | to_entries[] | {capability: .key, tags: .value.tags}'
Test Matching¶
See Also¶
- Architecture - System overview
- Schema Matching - Per-shape disambiguator that runs after version
- Audit Trail - Debug "why did my dep wire to producer X?"
- DDDI - Distributed Dynamic Dependency Injection overview
- Dependency Injection - DI patterns
- Capabilities & Tags - Full reference