Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
AUTH0_DOMAIN=dev-xxxxxxxxxx.us.auth0.com
AUTH0_AUDIENCE=https://bedrock-agentcore.us-west-2.amazonaws.com
AWS_REGION=us-west-2
AWS_ACCOUNT_ID=123456789
Original file line number Diff line number Diff line change
@@ -0,0 +1,360 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Calling Registry as an MCP Tool from Kiro\n",
"\n",
"#### Discover agentic capabilities from the AWS Agent Registry across your organization directly from your Kiro IDE, without writing a single line of code\n",
"\n",
"## Overview\n",
"Being able to search across a registry of agentic capabilities built across your organization directly in your IDE like Kiro is a superpower. This example shows how to configure an AWS Agent Registry with Auth0 Dynamic Client Registration (DCR) to enable secure, zero-config discovery of agents and tools.\n",
"\n",
"**What is Dynamic Client Registration?** \n",
"\n",
"Dynamic Client Registration is an OAuth and OpenID Connect protocol that lets client applications automatically register with an authorization server instead of requiring manual pre-registration. The DCR protocol is formally defined in RFC 7591, with optional registration management extensions in RFC 7592. It was designed to work within the Open Authorization (OAuth) and OpenID Connect (OIDC) ecosystems. It enables automatic creation of client IDs, secrets, and metadata (redirect URIs, scopes), often used for automation, AI agents, and dynamic scaling.\n",
"\n",
"In the case of using your AWS Registry MCP in your IDE, Dynamic Client Registration allows your IDE to automatically get its own unique credentials for the AWS Registry access instead of requiring a manual setup. This enables the IDE to programmatically request and refresh its own access tokens, completely removing the need for you to manually copy and paste them.\n",
"\n",
"![Kiro MCP JSON](images/0_authflow_dcr.png)\n",
"\n",
"### Key Features\n",
"- Create an Auth0-secured AWS Agent Registry with CUSTOM_JWT authorizer\n",
"- Seed the registry with sample agent records\n",
"- Search records using OAuth bearer tokens\n",
"- Connect the registry as an MCP server in Kiro for IDE-native discovery"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tutorial Details\n",
"\n",
"| Information | Details |\n",
"|:---|:---|\n",
"| Tutorial type | Interactive |\n",
"| AgentCore components | AWS Agent Registry |\n",
"| Auth method | Auth0 DCR (Dynamic Client Registration) |\n",
"| Inbound Auth IdP | Auth0 (CUSTOM_JWT) |\n",
"| Outbound Auth | OAuth Bearer Token |\n",
"| Tutorial components | Create Auth0 DCR Server, OAuth search, MCP setup on Kiro |\n",
"| Tutorial vertical | Cross-vertical |\n",
"| Example complexity | Easy |\n",
"| SDK used | boto3 |\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Prerequisites\n",
"\n",
"- **Auth0 account** with a tenant configured\n",
"- **Python 3.10+** with `boto3`, `python-dotenv`, `requests`\n",
"- **Kiro/Claude IDE** (for the MCP integration step)\n",
"- `.env` file configured from `.env.example`\n",
"\n",
"\n",
"\n",
"_______________________________________"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Step 1: Auth0 Setup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"\n",
"### 1. Create an Auth0 Account & Tenant\n",
"\n",
"1. Sign up at [auth0.com](https://auth0.com) if you don't already have an account\n",
"2. Create a new tenant (or use an existing one) — this acts as your authorization server\n",
"3. Note your **Auth0 Domain** (e.g., `your-tenant.auth0.com`)\n",
"4. Go to Dashboard > Settings > Advanced and enable Dynamic Client Registration (DCR).\n",
"\n",
"### 2. Register an API (Resource Server)\n",
"\n",
"1. Navigate to **Applications → APIs** in the Auth0 Dashboard\n",
"2. Click **Create API**\n",
"3. Provide a **Name** (e.g., `AWS Agent Registry API`)\n",
"4. Set the **Identifier (Audience)** to URL: `https://bedrock-agentcore.us-west-2.amazonaws.com` \n",
"5. Set **Allow Skipping User Consent** to `true` (optional but convenient for testing)\n",
"6. Select the **Signing Algorithm** — `RS256` is recommended\n",
"7. As a best practice for security purpose\n",
" - Set **Token Lifetime** to 3600 seconds (1 hour) or less\n",
" - Go to **Settings → Advanced Settings → Grant Types** and enable **Authorization Code, Refresh Token, Client Credentials**\n",
"8. Add a user to the API's assigned users list. This user will be used to generate the access token for the registry search. Go to **User Management** > **Users** > **Add a user** .\n",
" \n",
"\n",
"> **⚠️ Caution:** DCR enables dynamic registration of clients — your Auth0 tenant will see third-party clients created automatically by each MCP client (e.g., Kiro) that connects. Using Dynamic Client Registration effectively requires attention to both its security implications and the practical realities of deploying it at scale. Because DCR automates registration, you must ensure that only trusted clients can register and that the registration workflow cannot be exploited.\n",
"\n",
"\n",
"### 3. Enable authentication at domain level\n",
"\n",
"Since DCR creates a brand new client app in Auth0, it won't have any connections enabled by default. Auth0 needs to know which connections (login methods) the client can use\n",
"1. Navigate to **Authentication → Database → Username-Password-Authentication-> Settings -> toogle on [Promote Connection to Domain Level]** in the Auth0 Dashboard\n",
"\n",
"\n",
"### 4. Configure .env\n",
"\n",
"Copy `.env.example` to `.env` and fill in your values.\n",
"\n",
"### 5. Create the Registry and Seed it with sample records.\n",
"Follow Step 2 and 3 in the notebook, to create the registry and seed it with sample records.\n",
"\n",
"\n",
"### 6. Add your AWS Agent Registry API as Allowed Audience to the Oauth on regitsry.\n",
"Kiro sends the MCP server URL as the `audience` in the Auth0 authorization request (Otherwise it wont find the service). This will be a two step process :\n",
"1. Create an API in Auth0 with the MCP URL as the identifier.\n",
"2. Update the Registry's OAuth configuration to allow the API as an allowed audience.\n",
"\n",
"For this lab: \n",
"1. Note the Registry ID created. In the Auth0 dashboard, navigate to **Applications → APIs** and create an API using the registry's MCP endpoint URL as **Identifier**.\n",
"Mcp url: `https://bedrock-agentcore.us-west-2.amazonaws.com/registry/<REGISTRY_ID>/mcp`\n",
"\n",
"2. In this lab, you do not need to manually update the Auth configurations of the Registry Auth configuration. The `create_registry` helper for this notebook has been written to automatically add `https://bedrock-agentcore.us-west-2.amazonaws.com/registry/<REGISTRY_ID>/mcp` to the registry's `allowedAudience` after registry creation. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"# Step 2: Create Registry with Auth0 CUSTOM_JWT Authorizer\n",
"\n",
"This creates a new AWS Agent Registry configured with Auth0 as the OAuth identity provider. The helper:\n",
"1. Creates the registry with a `CUSTOM_JWT` authorizer pointing to your Auth0 tenant's OIDC discovery URL\n",
"2. Polls until the registry reaches `READY` status\n",
"3. Automatically adds the MCP endpoint URL to the registry's `allowedAudience`\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install python-dotenv strands-agents bedrock-agentcore bedrock-agentcore-starter-toolkit"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys, os\n",
"sys.path.insert(0, os.path.abspath('..'))\n",
"from seed_records import create_registry, seed\n",
"\n",
"registry = create_registry(\n",
" name=\"auth0-demo-registry-dcr\",\n",
" description=\"Demo registry with Auth0 OAuth for notebook walkthrough\",\n",
")\n",
"registry_id = registry[\"registryId\"]\n",
"print(f\"Registry ID: {registry_id}\")\n",
"print(f\"Status: {registry['status']}\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# STEP 3: Seed Registry with Sample Capability Records\n",
"\n",
"\n",
"We'll populate the registry with four sample agent records (weather, order-status, customer-support, inventory-lookup). Each record is created as `DRAFT`, submitted for approval, and auto-approved so it appears in search results.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from seed_records import seed\n",
"\n",
"records = seed(registry_id=registry_id)\n",
"print(f\"\\nSeeded {len(records)} records:\")\n",
"for r in records:\n",
" print(f\" • {r['name']} ({r['recordId']})\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"from seed_records import _cp_client\n",
"cp = _cp_client()\n",
"for r in cp.list_registries()['registries']:\n",
" if r['name'] == 'auth0-demo-registry-dcr':\n",
" print(f'Registry: {r[\"registryId\"]}')\n",
" recs = cp.list_registry_records(registryId=r['registryId']).get('registryRecords', [])\n",
" for rec in recs:\n",
" print(f'{rec[\"recordId\"]:15s} {rec[\"status\"]:10s} {rec[\"name\"]}')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# STEP 4: Create another API in Auth0 with the MCP URL as the identifier. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"Kiro sends the MCP server URL as the `audience` in the Auth0 authorization request (Otherwise it wont find the service). This will be a two step process :\n",
"1. Create an API in Auth0 with the MCP URL as the identifier.\n",
"2. Update the Registry's OAuth configuration to allow the API as an allowed audience.\n",
"\n",
"Use the registry_id that was created above to generate the MCP url `https://bedrock-agentcore.us-west-2.amazonaws.com/registry/<REGISTRY_ID>/mcp`\n",
"\n",
"- [DO THIS]In the Auth0 dashboard, navigate to **Applications → APIs** and create an API using the registry's MCP endpoint URL as **Identifier**.\n",
"- In this lab,the `create_registry` helper for this notebook automatically adds `https://bedrock-agentcore.us-west-2.amazonaws.com/registry/<REGISTRY_ID>/mcp` to the registry's `allowedAudience` after registry creation. No action needed here.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# STEP 5 : Add AWS Agent Registry MCP Server to Kiro"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"\n",
"Now that the registry is working with OAuth search, add it to Kiro as an MCP server for IDE-native discovery.\n",
"\n",
"### 4.1 Add to `mcp.json`\n",
"\n",
"Add the following to your Kiro MCP configuration (`.kiro/settings/mcp.json`):\n",
"\n",
"```json\n",
"{ \"mcpServers\" : {\n",
"\"dcr-registry-server_xx\": {\n",
" \"type\": \"http\",\n",
" \"url\": \"https://bedrock-agentcore.us-west-2.amazonaws.com/registry/<registry_id>/mcp/\",\n",
" \"disabled\": false\n",
" }\n",
"}\n",
"}\n",
"\n",
"```\n",
"![Kiro MCP JSON](images/1_kiro_mcp_json.png)\n",
"\n",
"### 4.2 Authenticate\n",
"\n",
"Enable and authenticate the MCP on your Kiro/Claude\n",
"When Kiro connects to the MCP server, it will:\n",
"- Discover the Auth0 authorization server via the registry's well-known endpoint\n",
"- Use DCR to auto-register as an OAuth client (POST /oidc/register)\n",
"- Obtain an access token via PKCE authorization code flow\n",
"- Use the token to call the registry search MCP\n",
"\n",
"| Authorization PKCE | Successful Auth |\n",
"|:---:|:---:|\n",
"| ![Authorization PKCE](images/2_authorization_pkce.png) | ![Successful Auth](images/3_successful_auth.png) |\n",
"\n",
"\n",
"### 4.3 Search from Kiro\n",
"Open Kiro chat and ask it to search the registry:\n",
"\n",
"\"Use the AWS registry to search for weather records\"\n",
"\n",
"![Kiro MCP JSON](images/4_kiro_search.png) \n",
"\n",
"### Useful Reference Commands\n",
"\n",
"View the authorization server metadata:\n",
"\n",
"```\n",
"curl -X POST https://<domain url>/oidc/register\\\n",
" -H \"Content-Type: application/json\" \\\n",
" -d '{\n",
" \"client_name\": \"test-mcp-client\",\n",
" \"redirect_uris\": [\"http://localhost:65358/callback\"],\n",
" \"grant_types\": [\"authorization_code\"],\n",
" \"response_types\": [\"code\"],\n",
" \"token_endpoint_auth_method\": \"none\"\n",
" }'\n",
"\n",
"```\n",
"\n",
"Manually register a client via DCR:\n",
"\n",
"```\n",
"https://<domainurl>/.well-known/oauth-authorization-server\n",
"```\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Clean Up"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#Cleanup your registry and records\n",
"\n",
"from seed_records import delete_registry\n",
"delete_registry(registry_id)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading