Documentation Assistant
Build an assistant that answers questions about a documentation site you choose, with links to the pages it used. Amazon Titan embeds the pages and your questions, MongoDB Atlas Vector Search finds relevant passages, and Claude on Amazon Bedrock writes the response. MongoDB also stores the conversation, so you can continue a thread after restarting the dev server. The included example is configured for the Mastra documentation; you can adapt the ingestion script and agent instructions for another site.
Why we built this
A docs assistant needs somewhere to keep the embeddings, somewhere to keep the conversation, and a model. Wiring those parts together is most of the work. File-backed storage also becomes a problem when you deploy to a runtime with a read-only filesystem, such as Bedrock AgentCore.
One Atlas cluster handles vector search and conversation storage, while Bedrock provides both models. You can run the agent locally and deploy it without changing where the data is stored.
Demo
Prerequisites
- MongoDB Atlas account: create a cluster, a database user, and an IP access list entry for your computer. Set
MONGODB_URIto the cluster's connection string with that database user's credentials. The free cluster tier supports Atlas Vector Search.MONGODB_DATABASEnames the database used for documents and conversations; it defaults tomastra_docs. - AWS account: use an account with access to Amazon Bedrock. Bedrock charges for model calls, including local ingestion and questions.
- Bedrock model access: choose a region where the chat and embedding models are available. Set
AWS_REGIONto that region (default:us-east-1). For a first use of Claude, submit Anthropic's use case details from the Bedrock Model catalog if prompted. The IAM identity you use locally needsbedrock:InvokeModeland, for streamed responses,bedrock:InvokeModelWithResponseStream. Access to the default Claude inference profile must also cover its destination regions. - AWS credentials for local development: use the standard AWS credential chain, such as an SSO profile configured with
aws configure ssoand signed in withaws sso login --profile <profile>. Install the AWS CLI if you use this path. SetAWS_PROFILEif you use a named profile. Access keys through the standard AWS environment variables are another option; no separate Bedrock API key is used. - Bedrock model IDs:
BEDROCK_MODEL_IDdefaults tous.anthropic.claude-sonnet-4-6, andBEDROCK_EMBED_MODEL_IDdefaults toamazon.titan-embed-text-v2:0. Use model IDs available to your account and region.EMBED_DIMENSIONdefaults to1024and must match the embedding model's output and the Atlas vector index. - Run one ingestion at a time. A successful run removes obsolete chunks and pages excluded by
DOCS_LIMITfrom the Mastra documentation corpus. Failed runs retain older records, though pages written before the failure may already be updated. DOCS_LIMIToptionally limits how many pages the ingestion script reads from the documentation index; the default is60. The included example uses the Mastra documentation index.
Quickstart 🚀
- Clone the template
- Run
npx create-mastra@latest --template mongodb-bedrock-agent. - Run
cd mongodb-bedrock-agentandnpm install.
- Run
- Add your credentials
- Run
cp .env.example .envand fill in the values described under Prerequisites.
- Run
- Load the documentation
- Run
npm run ingestto embed the example documentation corpus and store it in Atlas. Check that the command finishes successfully and reports inserted chunks. A failed fetch, empty page, or embedding error stops the run before cleanup; retry after fixing the reported error.
- Run
- Start the dev server
- Run
npm run dev. - Open Mastra Studio, select Mastra Docs Agent, and ask “How do I give a Mastra agent memory?” Look for an answer based on the retrieved documentation with a Sources list linking the pages used.
- Run
Try it out
- In the same thread, ask “Show me that as a TypeScript snippet.” The agent can use the earlier question as context without you repeating it.
- Open the Studio trace for a question and follow the query embedding on Bedrock, vector search in Atlas, and answer generation.
- With the included example corpus, ask “How do I define a tool in Mastra?” and follow the rendered page and raw Markdown links in the Sources list to inspect the passages behind the answer.
- Stop
npm run dev, start it again, and reopen the same thread. Ask a follow-up question to explore the conversation stored in MongoDB.
Customization
- Open the project in your coding agent and describe the change you want. For example: “Adapt this docs assistant to our API reference. Explore the ingestion script, search tool, and agent instructions, then propose a plan before changing code.”
- To use your own documentation site, update
LLMS_TXT, the link pattern, and the reconciliation URL filter inscripts/ingest.ts, adjust the subject insrc/mastra/agents/docs-agent.ts, and runnpm run ingestagain.
For related memory concepts, see the Mastra semantic recall documentation.
Deploy to Amazon Bedrock AgentCore
agent.ts implements the AgentCore HTTP contract (POST /invocations, GET /ping) and maps each user and session pair to a Mastra memory thread. agentcore/agentcore.json declares the runtime; the Dockerfile builds the required ARM64 image.
- Copy
agentcore/aws-targets.example.jsontoagentcore/aws-targets.jsonand set your AWS account id and region. - In AWS Secrets Manager, create an Other type of secret in that region. Use the Plaintext editor and store only your MongoDB connection URI, without JSON or surrounding quotes. Use the default
aws/secretsmanagerencryption key. - Copy the secret's complete ARN into both
MONGODB_SECRET_ARNinagentcore/agentcore.jsonandResourceinagentcore/mongodb-secret-policy.json, replacing the example ARN. SetAWS_REGIONin the runtime configuration to the secret's region as well. The policy grants the runtime role access to that one secret. - Deploy and invoke the runtime:
npx @aws/agentcore@0.31.1 deploy
export AGENTCORE_USER_ID="your-own-operator-id"
npx @aws/agentcore@0.31.1 invoke --user-id "$AGENTCORE_USER_ID" --prompt "How do I define a tool in Mastra?"scripts/ask.sh "your question" wraps that invoke call and renders the answer as Markdown in your terminal.
Invocation JSON is limited to 64 KiB (UTF-8 bytes), including requests without Content-Length. Larger uploads return HTTP 413; uploads that do not finish within 30 seconds return HTTP 408 and close the connection. These application limits apply independently of AgentCore service quotas.
This deployment uses IAM authentication. Restrict bedrock-agentcore:InvokeAgentRuntime and bedrock-agentcore:InvokeAgentRuntimeForUser to trusted operators or your backend and the specific runtime ARN. The CLI example is an operator demo, not end-user authentication.
For an app with multiple users, authenticate each user in your backend, derive runtimeUserId from that verified identity, and generate and store a separate runtimeSessionId for each conversation. Check ownership before reusing a session. Call InvokeAgentRuntime with those server-owned values; never forward user or session IDs supplied by a browser. Both AgentCore headers are required by this server, and identity fields in the JSON body are rejected. The memory key includes both IDs, so two users with the same session ID have separate histories.
The AgentCore user-id header does not verify end-user identity. A principal allowed to invoke for users must therefore be trusted to supply the correct identity. Do not expose the container's HTTP port directly or grant these IAM permissions to untrusted end users. Local Studio is for development and should remain private.
The runtime uses its IAM execution role for Bedrock and calls Secrets Manager's GetSecretValue at startup to load the MongoDB URI. The URI stays out of the image and the deployment configuration. If you use a customer-managed KMS key instead of the default encryption key, grant the runtime role kms:Decrypt on that key and allow the role in the key policy.
Local development still reads MONGODB_URI from .env; it takes precedence when set. agentcore/.env.local does not inject arbitrary variables into a deployed runtime. To pick up a rotated secret, restart the runtime so it reads the new value.
About Mastra templates
This is an official Mastra template for exploring documentation search with MongoDB Atlas and Amazon Bedrock. Official templates live in the Mastra monorepo and are synchronized to standalone repositories.
