Skip to content

Authenticated Extended Card Example

This example demonstrates how to serve a richer agent card to authenticated callers using the extended_card_provider callback.

Server

examples/authenticated_card/server.py
"""Authenticated extended card example.

Run:
    uvicorn examples.authenticated_card.server:app --reload
"""

from fastapi import Request

from a2akit import A2AServer, AgentCardConfig, CapabilitiesConfig, SkillConfig, TaskContext, Worker


class EchoWorker(Worker):
    async def handle(self, ctx: TaskContext) -> None:
        await ctx.complete(f"Echo: {ctx.user_text}")


async def provide_extended_card(request: Request) -> AgentCardConfig:
    """Return a richer card for authenticated callers.

    In production, inspect request.headers["Authorization"] to verify
    the caller and tailor the returned card (e.g., expose premium skills).
    """
    auth = request.headers.get("Authorization", "")
    skills = [
        SkillConfig(
            id="echo",
            name="Echo",
            description="Echoes your input.",
            tags=["demo"],
        ),
    ]
    if auth.startswith("Bearer "):
        skills.append(
            SkillConfig(
                id="premium-echo",
                name="Premium Echo",
                description="Premium echo with formatting.",
                tags=["demo", "premium"],
            )
        )

    return AgentCardConfig(
        name="Extended Card Demo",
        description="Agent with authenticated extended card.",
        version="1.0.0",
        protocol="http+json",
        capabilities=CapabilitiesConfig(),
        skills=skills,
    )


server = A2AServer(
    worker=EchoWorker(),
    agent_card=AgentCardConfig(
        name="Extended Card Demo",
        description="Agent with authenticated extended card.",
        version="1.0.0",
        protocol="http+json",
    ),
    extended_card_provider=provide_extended_card,
)
app = server.as_fastapi_app(debug=True)

The provider inspects the Authorization header and returns additional skills for authenticated callers.

Client

examples/authenticated_card/client.py
"""Client example -- fetch authenticated extended card.

Start the server first:
    uvicorn examples.authenticated_card.server:app

Then run this client:
    python -m examples.authenticated_card.client
"""

import asyncio

from a2akit import A2AClient


async def main():
    async with A2AClient("http://localhost:8000") as client:
        print(f"Public card skills: {len(client.agent_card.skills)}")

        extended = await client.get_extended_card()
        print(f"Extended card skills: {len(extended.skills)}")
        for skill in extended.skills:
            print(f"  - {skill.name}: {skill.description}")


if __name__ == "__main__":
    asyncio.run(main())

Running

Start the server:

uvicorn examples.authenticated_card.server:app --reload

Run the client:

python -m examples.authenticated_card.client

Expected output:

Public card skills: 0
Extended card skills: 1
  - Echo: Echoes your input.

The public card has no skills (none declared on the base AgentCardConfig), while the extended card returns the skills defined by the provider callback. With a Bearer token, the provider would return an additional premium skill.