A2A Registry - Service Registration and Discovery¶
AgentApp Extension Field a2a_config¶
In the AgentApp constructor, we introduce an optional parameter a2a_config to extend the configuration of the agent’s A2A protocol information and runtime-related fields.
Its type is AgentCardWithRuntimeConfig, which wraps AgentCard protocol fields and runtime fields into a single data structure for unified management.
The fields in AgentCardWithRuntimeConfig fall into two categories:
1. AgentCard Protocol Fields
The agent_card field can be an AgentCard object or dictionary, containing the following protocol fields:
name: Agent namedescription: Agent descriptionurl: Complete URL of the agent service. By default it can be inferred automatically fromhost/port.version: Agent version. By default it follows the runtime code version.preferred_transport: Preferred transport protocol, such as"JSONRPC".additional_interfaces: List of additional transport interfaces.skills: List of agent capabilities/skills.default_input_modes: Default supported input modes, for example["text"].default_output_modes: Default supported output modes, for example["text"].provider: Provider information, which can be a string, dict, or structured object.documentation_url: Documentation URL.icon_url: Icon URL.security_schemes: Security schemes definition.security: Security requirements configuration.
2. Runtime Fields
host: Host address for the agent to register with the Registry agent registry center. If not specified, the runtime automatically obtains the first non-loopback IP address from all network interfaces of the current deployment machine.port: Port for the agent to register with the Registry agent registry center. Defaults to8080.registry: Registry instance or list, used to register the agent service to centralized agent registries such as Nacos.task_timeout: Timeout in seconds for a task to complete. Defaults to60.task_event_timeout: Timeout in seconds for task events. Defaults to10.wellknown_path: Public path where the AgentCard is exposed. Defaults to"/.wellknown/agent-card.json".
In practice, you only need to pass an appropriate a2a_config when constructing AgentApp. Among these fields, we provide A2A Registry capability, which allows you to specify which centralized agent registries (such as Nacos) the current agent should be registered to via the registry field.
Registry Architecture¶
A2A Registry adopts an extensible plugin-based architecture for registering agent services to different centralized agent registries (such as Nacos).
Core components:
1. A2ARegistry Abstract Base Class
Defines the interface that all Registry implementations must follow:
registry_name(): Returns a short name identifying the Registry (e.g.,"nacos").register(agent_card, a2a_transports_properties): Executes the actual registration logic.
The Runtime captures and logs exceptions during registration to ensure that Registry failures do not block agent service startup.
2. A2ATransportsProperties
Describes one or more A2A transport protocols:
host/port/path: Transport endpoints exposed externally.support_tls: Whether TLS is supported.extra: Additional configuration for each transport channel.transport_type: Transport type (e.g.,"JSONRPC","HTTP").
When an agent exposes services through multiple transport protocols, multiple transport configurations can be provided and registered together.
Registration Process
When AgentApp starts, the Registry registration process is as follows:
Agent Card Publication: Publishes agent metadata (name, version, skills, etc.) to the registry, enabling other agents to discover and understand the agent’s capabilities.
Endpoint Registration: Registers agent service endpoint information (host, port, path), including transport protocol configuration, enabling other agents to connect to the service.
Background Asynchronous Execution: The registration process runs asynchronously in the background and does not block application startup. If a Registry registration fails, the Runtime logs a warning but does not affect normal agent service startup.
Registry Configuration Methods¶
The Runtime supports three ways to configure Registry:
1. Configuration via a2a_config¶
When constructing AgentApp, specify Registry instance(s) via the registry field in the a2a_config parameter:
from agentscope_runtime.engine.app import AgentApp
from agentscope_runtime.engine.deployers.adapter.a2a import (
AgentCardWithRuntimeConfig,
)
from agentscope_runtime.engine.deployers.adapter.a2a.nacos_a2a_registry import (
NacosRegistry,
)
from a2a.types import AgentSkill
from v2.nacos import ClientConfigBuilder
# Create Nacos Registry instance
nacos_config = (
ClientConfigBuilder()
.server_address("localhost:8848")
.username("nacos")
.password("nacos")
.build()
)
nacos_registry = NacosRegistry(nacos_client_config=nacos_config)
# Configure registry in a2a_config
a2a_config = AgentCardWithRuntimeConfig(
agent_card={
"name": "MyAgent",
"description": "My agent description",
# ...
},
registry=[nacos_registry], # Can be a single instance or a list
task_timeout=60,
# ...
)
agent_app = AgentApp(
app_name="MyAgent",
app_description="My agent description",
a2a_config=a2a_config,
)
2. Configuration via Environment Variables¶
If registry is not specified in a2a_config, the Runtime automatically creates Registry instances from environment variables. Currently, the system only implements NacosRegistry, and users can configure the Nacos registry via environment variables:
A2A_REGISTRY_ENABLED: Whether to enable Registry feature (default:True)A2A_REGISTRY_TYPE: Registry type(s), supports comma-separated values (e.g.,"nacos")NACOS_SERVER_ADDR: Nacos server address (default:"localhost:8848")NACOS_USERNAME: Nacos username (optional, for console login)NACOS_PASSWORD: Nacos password (optional, for console login)NACOS_NAMESPACE_ID: Nacos namespace ID (optional, defaults to public)NACOS_ACCESS_KEY: Nacos Access Key (optional, for client authentication)NACOS_SECRET_KEY: Nacos Secret Key (optional, for client authentication)
Environment variables can be set via .env file or system environment variables:
# .env file example
A2A_REGISTRY_ENABLED=true
A2A_REGISTRY_TYPE=nacos
NACOS_SERVER_ADDR=localhost:8848
NACOS_USERNAME=nacos
NACOS_PASSWORD=nacos
NACOS_NAMESPACE_ID=your_namespace_id
# No need to specify registry in a2a_config, will be created from environment variables
agent_app = AgentApp(
app_name="MyAgent",
app_description="My agent description",
)
3. Passing adapter via deploy method¶
When deploying using AgentApp.deploy(), you can pass an A2A Protocol Adapter configured with Registry via the protocol_adapters parameter.
A2AFastAPIDefaultAdapter Parameter Description:
agent_name(required): Agent name for Agent Card (used as fallback ifnameis not specified ina2a_config.agent_card)agent_description(required): Agent description for Agent Card (used as fallback ifdescriptionis not specified ina2a_config.agent_card)a2a_config(optional):AgentCardWithRuntimeConfigobject containing AgentCard protocol fields and runtime configurationagent_card: AgentCard object or dictionary containing protocol fields (name, description, skills, etc.)host: Service host address. If not provided, defaults to callingget_first_non_loopback_ip()to automatically obtain the public IP of the current deployment machineport: Service port number. If not provided, defaults to 8080registry: Registry instance or Registry list for service registration and discoverytask_timeout: Timeout in seconds for task completion (default: 60)task_event_timeout: Timeout in seconds for task events (default: 10)wellknown_path: Public path where AgentCard is exposed (default:"/.wellknown/agent-card.json")
from agentscope_runtime.engine.app import AgentApp
from agentscope_runtime.engine.deployers.adapter.a2a import (
A2AFastAPIDefaultAdapter,
AgentCardWithRuntimeConfig,
)
from agentscope_runtime.engine.deployers.adapter.a2a.nacos_a2a_registry import (
NacosRegistry,
)
from agentscope_runtime.engine.deployers import LocalDeployManager
from v2.nacos import ClientConfigBuilder
# Create Nacos Registry instance
nacos_config = (
ClientConfigBuilder()
.server_address("localhost:8848")
.build()
)
nacos_registry = NacosRegistry(nacos_client_config=nacos_config)
# Create A2A Protocol Adapter configured with Registry
a2a_adapter = A2AFastAPIDefaultAdapter(
agent_name="MyAgent",
agent_description="My agent description",
a2a_config=AgentCardWithRuntimeConfig(
registry=[nacos_registry],
# ...
),
)
# Create AgentApp
agent_app = AgentApp(
app_name="MyAgent",
app_description="My agent description",
)
# Pass adapter in deploy method
deployer = LocalDeployManager(host="127.0.0.1", port=8090)
await agent_app.deploy(
deployer,
protocol_adapters=[a2a_adapter],
# ... other deployment parameters
)
Configuration Priority: The registry explicitly specified via a2a_config has the highest priority. If not specified, it will be automatically created from environment variables. The protocol_adapters passed via the deploy method will override the adapter configured in AgentApp.
Nacos Registry Usage Guide¶
Nacos is a dynamic service discovery, configuration management, and AI agent management platform that makes it easy to build AI Agent applications. Nacos implemented Agent registry capability in version 3.1.0, supporting distributed registration, discovery, and version management for A2A agents.
Note: The prerequisite for using NacosAgentCardResolver is that a Nacos server version 3.1.0 or higher has been deployed.
Before using Nacos Registry, you need to install and start the Nacos server. Here are the quick start steps:
1. Download Installation Package¶
Go to Nacos Github latest stable release, select the Nacos version you want to download, and click to download the nacos-server-$version.zip package in Assets.
2. Extract Nacos Distribution Package¶
unzip nacos-server-$version.zip
# or tar -xvf nacos-server-$version.tar.gz
cd nacos/bin
3. Start Server¶
Linux/Unix/Mac:
sh startup.sh -m standalone
Windows:
startup.cmd -m standalone
Note:
standalonerepresents standalone mode, not cluster mode.
For more detailed installation, configuration, and verification steps, please refer to the Nacos official quick start documentation.
Custom Registry Implementation¶
If you need to integrate other types of centralized agent registries, you can implement a custom Registry. Custom Registry needs to inherit from the A2ARegistry abstract base class and implement the following methods:
Implementation Steps¶
Inherit from
A2ARegistryabstract base classImplement
registry_name()method: Returns a short name for the Registry, used for logging and diagnosticsImplement
register()method: Executes the actual registration logic
Example Code¶
Here is a simple custom Registry implementation example:
from agentscope_runtime.engine.deployers.adapter.a2a.a2a_registry import (
A2ARegistry,
A2ATransportsProperties,
)
from a2a.types import AgentCard
from typing import Optional, List
import logging
logger = logging.getLogger(__name__)
class MyCustomRegistry(A2ARegistry):
"""Custom Registry implementation example."""
def registry_name(self) -> str:
return "my-custom-registry"
def register(
self,
agent_card: AgentCard,
a2a_transports_properties: Optional[
List[A2ATransportsProperties]
] = None,
) -> None:
try:
# Build registration information
if a2a_transports_properties and len(a2a_transports_properties) > 0:
transport = a2a_transports_properties[0]
service_info = {
"agent_name": agent_card.name,
"agent_version": agent_card.version,
"host": transport.host,
"port": transport.port,
}
else:
service_info = {
"agent_name": agent_card.name,
"agent_version": agent_card.version,
}
# Execute registration logic
logger.info(f"[MyCustomRegistry] Registering: {service_info}")
# ...
except Exception as e:
logger.warning(f"[MyCustomRegistry] Registration failed: {e}", exc_info=True)
Using Custom Registry¶
After implementing a custom Registry, you can use it in the following way:
from agentscope_runtime.engine.app import AgentApp
from agentscope_runtime.engine.deployers.adapter.a2a import (
AgentCardWithRuntimeConfig,
)
# Create custom Registry instance
custom_registry = MyCustomRegistry()
# Use in a2a_config
a2a_config = AgentCardWithRuntimeConfig(
registry=[custom_registry],
# ...
)
agent_app = AgentApp(
app_name="MyAgent",
app_description="My agent description",
a2a_config=a2a_config,
)