MCP Targets in AgentCore Gateway, Part 2: Which Data Source Wins
This is Part 2 of a two-part series on MCP server targets in Amazon Bedrock AgentCore Gateway. • Part 1: How agents discover tools — DEFAULT vs DYNAMIC listing modes. • Part 2 (this post): Which data source wins — resolving resource conflicts with resourcePriority.
Part 1 covered when AgentCore Gateway discovers what an MCP server can do. This post is about a different question that only shows up once you have more than one MCP server behind the same gateway: when two of them expose the same MCP resource (for example, the same reference document at docs://api-reference), which one does the agent actually get?
The answer is a single, easy-to-misconfigure setting called resourcePriority. It is independent of listing mode, it applies in both DEFAULT and DYNAMIC mode, and its precedence direction is the opposite of what most people assume. That last point is why it deserves its own post.
------------------------------------------------------------------------------------------------------
Quick recap: why resources collide
Here is the detail that sets up the whole problem: how the gateway names things when it returns them to a client.
When AgentCore Gateway returns tools and prompts to a client, it prefixes them with the target name, in the format targetName___toolName. That prefix guarantees two targets can each have a tool called search without colliding, because the client sees docs___search and tickets___search.
Resources do not get that treatment. Resource URIs are passed through exactly as the downstream server returned them, with no target-name prefix. The original URI is preserved as-is so clients can reference it the way the server intended.
The consequence: if two different MCP server targets behind the same gateway both expose a resource with the same URI, say both a latest-docs server and an archive server publish docs://api-reference, the gateway has a genuine conflict. A resources/list call cannot return both under one URI, so it has to pick one. resourcePriority is how you tell it which.
The rule (stated correctly)
Here is the precedence rule, straight from the documented behavior:
The gateway returns the resource from the target with the lowest resourcePriority value. Lower values take precedence. The valid range is 0–1000, and the default is 1000 when you set nothing. If two conflicting targets share the same priority, the gateway returns the resource from the target that was synchronized first.
The part that catches almost everyone: this is not "higher number wins." Think of it like a ranked list or a race result, where #1 is the best position, not #1000. The lower the number, the higher the precedence.
So if you have a latest-docs server and an archive server that both expose docs://api-reference, and you want latest-docs to win, you give latest-docs the lower number:
| Target | resourcePriority | Result |
|---|---|---|
| latest-docs | 1 | Wins the shared URI |
| archive | 1000 (default) | Shadowed for the shared URI |
If you flipped those, giving latest-docs a 1000 and archive a 1, the archive would win, which is almost certainly not what you intended. This is the single most common mistake with this setting, so it is worth a code comment wherever you configure it.
Two practical notes:
- Priority only affects conflicting URIs. Resources with unique URIs are unaffected and always appear in the list, regardless of their priority value.
- Priority is about resource resolution, not tools or prompts. Tools and prompts are namespaced by the targetName___ prefix, so they never collide this way and resourcePriority does nothing for them.
Scenarios in practice
A few patterns where resourcePriority earns its keep.
Scenario 1: Versioned documentation (canonical vs archive)
You run a latest-docs MCP server that serves the current API reference and an archive server that keeps historical versions. Both legitimately expose docs://api-reference. You want agents to always read the current copy, but you do not want to delete the archive, since other unique URIs on it (like docs://api-reference/v1) still matter.
Give latest-docs a resourcePriority of 1 and leave archive at the default 1000. The shared URI resolves to the current docs; the archive's unique URIs keep showing up untouched.
Scenario 2: Primary and failover data sources
A primary-config server and a backup-config server both publish config://feature-flags from replicated stores. During normal operation you want the primary to win, but you want the backup registered and ready.
Set primary-config to 1 and backup-config to 10. Under normal conditions the primary's resource wins. If you later remove or fail the primary target, the backup is already in place and its config://feature-flags becomes the surviving copy, no client change required. (Priority resolves conflicts; it is not automatic health-based failover, but it does let you stage a ranked fallback.)
Scenario 3: Tenant or environment override
You have a shared defaults MCP server that publishes baseline resources like policy://data-retention, and a tenant-overrides server that selectively republishes a few of those URIs with tenant-specific content.
Set tenant-overrides to 1 and defaults to 1000. Where the override server publishes a URI, it wins; everywhere else, the shared defaults flow through unchanged. This gives you a clean "override-by-exception" layering without forking the whole catalog.
Scenario 4: Zero-downtime migration between servers
You are moving ownership of docs://api-reference from an old legacy-docs server to a new docs-v2 server, and you cannot change the URI because clients already reference it.
Register docs-v2 with priority 1 while legacy-docs stays at 1000. The gateway immediately starts serving the resource from docs-v2, but legacy-docs remains as an instant rollback: bump docs-v2 to 1000 (or remove it) and traffic falls back to legacy. The URI never changes, so no client is aware the backing server moved.
A note on the tie-breaker
If two targets share the same priority for a conflicting URI, the gateway returns the resource from the target that was synchronized first. Relying on sync order is fragile, re-synchronizing or recreating a target can flip the winner, so when the choice actually matters, assign distinct priorities rather than depending on the tie-break.
Security: validate resource URIs before you follow them
Because resource URIs come straight from the downstream MCP server target and are not validated or sanitized by the gateway, you have to treat them as untrusted input. A malicious or compromised server could return a URI pointing at an internal endpoint (an SSRF attempt) or a local filesystem path such as file:///etc/passwd.
resourcePriority decides which target's URI wins a conflict; it does nothing to vouch for the safety of that URI. So in your client:
· Validate and sanitize resource URIs against an allowlist before acting on them.
· Never automatically fetch or render a URI returned from an untrusted target.
This matters more once you start ranking targets, because a high-precedence (low-number) target you trusted yesterday could be compromised tomorrow and would still win the conflict.
Bottom Line
resourcePriority is a small tie-breaker with one rule worth tattooing on the back of your hand: lower wins. It only matters when multiple targets share a resource URI, it has nothing to do with listing mode, and it never touches tools or prompts. Give your authoritative source the lowest number, leave everything else at the default 1000, and validate every URI before you follow it.
If you have not read it yet, Part 1 covers the other half of MCP target configuration: how the gateway discovers capabilities in the first place, and when to choose DEFAULT vs DYNAMIC listing mode.
Sources
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article