fix(bedrock-kb-retrieval-mcp-server): support managed knowledge bases and add agentic retrieval - #4574
Conversation
QueryKnowledgeBases always sent `vectorSearchConfiguration`, which managed
knowledge bases (`type: MANAGED`) reject outright:
ValidationException: Incompatible configuration: vectorSearchConfiguration
is not supported for managed knowledge bases. Use
managedSearchConfiguration instead.
Every query against a managed knowledge base failed, even though
ListKnowledgeBases discovered it successfully.
Data-source filtering had a quieter failure. Managed knowledge bases expose
data-source identity as `_data_source_id`, not the `x-amz-bedrock-kb-*`
reserved keys. Filtering a managed knowledge base on the vector key is
accepted by the API but matches nothing, so `data_source_ids` returned zero
results with no error - the agent concludes the data source is empty.
Changes:
- Detect the knowledge base type and build the matching search configuration.
The type comes from the `get_knowledge_base` call discovery already makes,
so the common path costs no extra API call, and is cached.
- Filter on the metadata key appropriate to the knowledge base type.
- Nest reranking under whichever search configuration is in use.
- Recover from an unknown type: if the shape is rejected, retry once with the
other one. This keeps the server working without
`bedrock:GetKnowledgeBase`. Errors unrelated to configuration shape, and
mismatches on a knowledge base whose type is known, are not retried.
- Report `type` from ListKnowledgeBases so agents can see it.
- Raise the boto3 floor to 1.43.0. Earlier versions do not model
`managedSearchConfiguration` and fail client-side parameter validation
before the request is sent.
Verified against a managed and a vector knowledge base in us-west-2 through
the MCP protocol: queries succeed for both types from one server instance,
and data-source filtering scopes results correctly on a managed knowledge
base. Existing behaviour for vector knowledge bases is unchanged.
…ge bases
Adds an AgenticQueryKnowledgeBases tool backed by AgenticRetrieveStream, which
plans a multi-step retrieval strategy across one or more managed knowledge bases
and can synthesise a cited answer. This is the only way to get a generated answer
from a managed knowledge base, since RetrieveAndGenerate rejects them:
ValidationException: This operation is not supported for managed knowledge bases.
AgenticRetrieveStream is a streaming operation while an MCP tool call returns a
single result, so the stream is consumed server-side and returned as one aggregate.
Observed stream shape for a default call: 4 trace events, ~440 responseEvent answer
chunks, and a single terminal result event. The terminal event already carries the
complete answer and citations, so the streamed chunks are used only as a fallback.
Raw events are deliberately not forwarded - there are hundreds per call and they
would crowd out the content the model needs.
The tool returns results, and when generation is on, the answer plus citations
mapped to result indexes. A condensed per-step trace is available behind
include_trace for debugging why results were or were not found.
Details:
- Managed knowledge bases only. The service rejects other types with an opaque
message, so the type is checked up front and reported actionably, reusing the
type detection added for Retrieve.
- Data-source filtering goes through retrievalOverrides using the managed metadata
key, matching the Retrieve path.
- Several knowledge base ids become several retrievers in one call.
- Modelled error events in the stream are raised rather than silently dropped.
- byteContent is a Blob and not JSON serialisable; its presence is flagged instead
of being embedded.
Verified end to end over MCP against a live managed knowledge base: answer with 13
citations over 10 results, results-only mode, trace, data-source scoping confirmed
to return only the requested source, and a vector knowledge base correctly refused.
|
Additional live validation, beyond the end-to-end table in the description. Fallback retry path, verified against a live managed knowledge base. The description Results come back on the retry. The same call with Multiple knowledge bases in one call. Two managed knowledge bases returned 11 results
Reranking — clarifying the caveat in the description. In my test account reranking Remaining mock-only coverage, for transparency: a successful explicit |
…user context Self-review of the preceding two commits turned up four issues, all fixed here. Reranking region validation was wrong. A single flat region allowlist let reranking_model_name='AMAZON' through in us-east-1, where that model is not offered, so the request failed at the API with an opaque error instead of failing fast. Availability differs per model: amazon.rerank-v1:0 is offered in us-west-2, eu-central-1, ca-central-1 and ap-northeast-1 but not us-east-1, while cohere.rerank-v3-5:0 is offered in all five. Validation is now per (region, model) and names the supported regions. ACL-aware data sources were unreachable. Neither tool exposed userContext, so content in SharePoint, OneDrive or Confluence data sources with per-document ACLs could not be retrieved, and agentic retrieval's full-document expansion step failed with "UserContext is required for ACL-aware data sources" while still returning a partial result. Both tools now take an optional user_id. Verified against a live managed knowledge base: without it the failure is reported, with it the failure clears and results are correctly filtered to that user's authorised subset. The search-configuration fallback discarded what it learned. When the knowledge base type could not be determined, a successful retry was not recorded, so every later call repeated the failed attempt first. The recovered type is now cached. Agentic retrieval surfaced nextToken with no way to send one back, making the token useless. It now accepts next_token. Also hardened the result loop to tolerate a result without a content key rather than raising KeyError.
The README additions shifted the line number of an existing, already-reviewed baseline entry. detect-secrets fails until the baseline reflects the new position. Only the line number and generated_at timestamp change; the entry count is unchanged at 65 files / 126 entries.
Fixes
Summary
Amazon Bedrock managed knowledge bases (
knowledgeBaseConfiguration.type == "MANAGED")do not work with this server today, and there is no way to get a generated answer from one.
This makes both work.
Changes
1.
QueryKnowledgeBasesfailed on every call against a managed knowledge baseretrieval.pyalways sentretrievalConfiguration={'vectorSearchConfiguration': {...}},which
Retrieverejects for a managed knowledge base:ListKnowledgeBasesdiscovers such a knowledge base happily, so it looks usable and thenfails on every query.
There is a quieter second half. Managed knowledge bases expose data-source identity as
_data_source_id, not thex-amz-bedrock-kb-*reserved keys. Filtering a managedknowledge base on the vector key is accepted by the API and matches nothing, so
data_source_idsreturns an empty result set with no error and the caller concludes thedata source is empty. Fixing only the configuration key would leave
data_source_idssilently broken.
from the
get_knowledge_basecalldiscover_knowledge_basesalready makes for the ARN,so the common path costs no extra API call, and it is cached per knowledge base id.
rerankingConfigurationunder whichever search configuration is in use.bedrock:GetKnowledgeBase): retry once with the other shape if the API rejects it byname, then cache what that retry proved so later calls go direct. Errors unrelated to
configuration shape are not retried, and neither is a mismatch on a knowledge base whose
type was already known.
ListKnowledgeBasesreports each knowledge base'stype, so a client can tell whichtool applies.
boto3floor to>=1.43.0.managedSearchConfigurationfirst appears in theRetrieveinput model there; 1.42.50 does not have it, and the previously declared floorresolves to a version that fails client-side parameter validation before a request is sent.
Vector knowledge base behaviour is unchanged.
2. New tool:
AgenticQueryKnowledgeBasesRetrieveAndGeneraterejects managed knowledge bases outright(
ValidationException: This operation is not supported for managed knowledge bases.), soAgenticRetrieveStreamis the only way to get a generated answer from one. This server didnot expose it.
AgenticRetrieveStreamis a streaming operation whereas an MCP tool call returns a singleresult, so the stream is consumed server-side and returned as one aggregate. Observed shape
for a default call: 4 trace events, ~440
responseEventanswer chunks, and a singleterminal
resultevent. The terminal event already carries the complete answer andcitations, so the streamed chunks are only a fallback. Raw events are deliberately not
forwarded — there are hundreds per call and they would crowd out the content the model
actually needs.
Returns a single JSON object:
resultsalways;answerandcitationswhengenerate_responseis true;tracewheninclude_traceis true;warnings,failuresand
nextTokenonly when non-empty.Knowledge Base with id ... is not supported for Agent.... The type is checked up frontand reported actionably, reusing the detection above.
retrievalOverrideswith the managed metadata key.next_token, so thenextTokenit surfaces is actually usable.byteContentis aBloband not JSON serialisable; its presence is flagged rather thanembedded.
3. ACL-protected content was unreachable
Neither tool exposed
userContext, so content in data sources with per-document ACLs(SharePoint, OneDrive, Confluence) could not be retrieved. Agentic retrieval degraded
partially rather than loudly: its full-document expansion step failed with
UserContext is required for ACL-aware data sourceswhile still returning a partial result.Both tools now take an optional
user_id.4. Reranking availability is per model, not per region
A single flat region allowlist let
reranking_model_name='AMAZON'through inus-east-1,where that model is not offered, so the request failed at the API with an opaque error
instead of failing fast. Verified with
ListFoundationModelsacross 12 regions:amazon.rerank-v1:0is offered inus-west-2,eu-central-1,ca-central-1andap-northeast-1but notus-east-1;cohere.rerank-v3-5:0is offered in all five.Validation is now per
(region, model)and names the supported regions.User experience
Before — with a managed knowledge base:
QueryKnowledgeBasesfails 100% of the time with aValidationExceptionAMAZONreranking inus-east-1fails with an opaque errorAfter:
QueryKnowledgeBasesworks, anddata_source_idsactually scopes resultsAgenticQueryKnowledgeBasesreturns a cited answer, or results only viagenerate_response=falseuser_idreaches ACL-protected content, filtered to that user's authorised subset(region, model)reranking pairs fail immediately with the supported listListKnowledgeBasesreportstype, so a client can pick the right toolTesting
75unit tests pass;ruff checkandruff formatclean.Unit tests alone were not treated as sufficient: mocking the runtime client hides both
Retrieve bugs, since neither client-side parameter validation nor the server's filter-key
semantics are exercised. So everything was also verified against live managed and vector
knowledge bases in
us-west-2, both directly and end to end over MCP JSON-RPC.End to end over MCP — 10/10: tools registered;
ListKnowledgeBasesreportstypeforboth kinds; Retrieve on managed (previously always failed); Retrieve on vector (unchanged);
Retrieve
data_source_idson managed returns results (previously 0, silently); agenticanswer with 13 citations over 10 results;
generate_response=falsehonouringnumber_of_results;include_trace; agenticdata_source_idsscoped to exactly therequested source; vector knowledge base refused with an actionable message.
Input-combination matrix — 34/34, covering Retrieve × knowledge base type × reranking
model, data-source filters (valid / multiple / non-existent),
number_of_resultsbounds(1 / 10 / 100 / 101 / 0), type-detection modes (management client present, absent, bogus id),
and agentic ×
generate_response×include_trace× iteration caps × retriever sets(one, two, managed+vector, vector only, empty, bogus).
Specific behaviours confirmed live rather than only mocked:
managedSearchConfigurationsucceeds with bothAMAZONandCOHEREon a managed knowledge base.
turn returned results only from that source (20 / 20 / 12), a non-existent id returned 0,
and the vector key returned 0 against the same knowledge base that returns 20 unfiltered.
vector shape is attempted, rejected, retried as managed, and the learned type cached.
user_idresolves the ACL failure: without it the run reportsUserContext is required for ACL-aware data sources; with it the failure clears andresults narrow to the user's authorised subset.
Not reproducible in my environment, and therefore only unit tested: warning/failure
surfacing, binary-content flagging, in-stream modelled error events, and
nextTokenpagination (the service never returned a token for my corpus).
Checklist
If your change doesn't seem to apply, please leave them unchecked.
Is this a breaking change? (Y/N) N
New parameters are optional and appended after existing ones, so positional callers are
unaffected and omitting them preserves current behaviour. Vector knowledge base behaviour is
unchanged. The reranking region check now refuses an unavailable
(region, model)pair thatpreviously passed the check and then failed at the API — a clearer failure for a request that
could not have succeeded.
RFC issue number: n/a — this is a fix plus a tool on an existing server, not a new server.
Checklist:
Notes for reviewers
memoryConfigurationexists onAgenticRetrieveStreamin newer models but is not in thepublic botocore version pinned here, so it is not exposed. Straightforward to add later.
environment flag like
BEDROCK_KB_RERANKING_ENABLED, say so and I will gate it — itinvokes a foundation model and so costs more per call than
QueryKnowledgeBases.Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.