Client Agent Discovery, Registries, and Agent Card Security
- 3 hours ago
- 8 min read

Course: Agent Discovery & Agent Cards
Level: Medium to Advanced
Type: Individual
Duration: 7 to 10 days
Objective
This assignment tests your ability to build the Client Agent side of agent discovery, design and operate a shared Agent Registry, and harden an agent discovery system against trust and security failures. By completing this assignment, you will have implemented the complete five-step Client Agent discovery workflow, built both exact and LLM-assisted skill matching, run a self-registering agent registry, and demonstrated how proper Agent Card validation catches a simulated spoofed card attack.
Problem Statement
You are required to build a Client Agent that discovers Remote Agents autonomously using Agent Cards — without any hardcoded URLs or skill names. The Client Agent must resolve Agent Cards from base URLs, match skills using both exact and semantic strategies, and delegate tasks end to end. You will then scale this to a shared registry where agents self-register on startup, and finally harden the system by adding authentication and card validation that catches a deliberately injected spoofed card.
Tasks
Task 1: Implement the Five-Step Client Agent Discovery Workflow (25 marks)
Write a Python module (discovery.py) that implements the complete five-step discovery workflow as five named functions: resolve_well_known_url(base_url), fetch_agent_card(url), parse_agent_card(raw_json), match_skill(card, task_description), and extract_endpoint_and_auth(card, skill_id).
resolve_well_known_url must append /.well-known/agent.json to a base domain and return the full URL. fetch_agent_card must make an HTTP GET request, handle non-200 responses with a clear error, and return the parsed JSON. parse_agent_card must validate that the card has the required top-level fields (name, skills, url) and raise a descriptive ValueError if any are missing.
match_skill must first attempt exact match by skill id. If no exact match is found, it must fall back to returning None with a clear message. extract_endpoint_and_auth must return a dict with the base URL and the auth scheme from the card's authentication block.
Write a discover_and_delegate(base_url, task_description, skill_id) function that calls all five steps in sequence and prints the result of each step. Test it against at least two different Agent Card servers (you may reuse servers from Assignment 1).
Handle at least three error cases explicitly: card not found (HTTP 404), card missing required fields, and skill not found. Each must raise a specific, descriptive exception — not a generic Exception.
Task 2: Implement LLM-Assisted Semantic Skill Matching (20 marks)
Extend discovery.py with a function match_skill_semantic(card, task_description, llm_client) that uses an LLM to select the best matching skill from the card's skills array when exact id matching fails.
The function must construct a prompt that includes the task description and the full list of skill names and descriptions from the card, instruct the LLM to return the id of the best matching skill (or 'none' if no skill is suitable), and parse the LLM's response to extract the skill id.
Demonstrate the semantic matcher with at least three task descriptions that would not match any skill by exact id but should match by semantic meaning. Show the LLM's reasoning by including the prompt and response in your submission.
Write a compare_matching.py script that runs both the exact matcher and the semantic matcher on the same set of five task descriptions against the same Agent Card. For each description, show which matcher succeeded, which failed, and explain why.
Write a 100 to 150 word analysis of when semantic matching is necessary, when it introduces risk, and what makes a skill description easier or harder for an LLM to match correctly.
Task 3: Build a Self-Registering Agent Registry (25 marks)
Write a FastAPI server (registry.py) implementing an in-memory Agent Registry with three endpoints: POST /register (accepts a full Agent Card JSON body and stores it, keyed by the agent's url field), GET /search (accepts a query parameter skill that returns all cards containing a skill whose name or description contains the query string, case-insensitive), and DELETE /deregister (accepts a url query parameter and removes the matching card).
Write a Remote Agent server (remote_agent.py) that on startup sends a POST /register request to the registry with its own Agent Card, and on shutdown (using a FastAPI lifespan handler) sends DELETE /deregister to remove itself.
Start the registry and two instances of remote_agent.py (use different ports and different skill sets). Use curl or httpx to confirm both agents appear in GET /search results. Then stop one agent and confirm it is removed from the registry.
Write a Client Agent script (registry_client.py) that: accepts a plain English task description as input, calls GET /search on the registry with a keyword extracted from the task, receives the list of matching Agent Cards, selects the best card using your skill matcher from Task 2, and delegates a mock task to the selected agent's endpoint.
Include terminal output showing: both agents registered, a search that returns both, a search that returns only one, a deregistration, and the Client Agent finding and selecting the correct agent for two different task descriptions.
Task 4: Add Authentication and Validate Agent Cards (20 marks)
Update your remote_agent.py Agent Card to include an authentication block with scheme: apiKey and a header name of X-Agent-Key. Update registry_client.py to read the auth scheme from the card and attach the correct header when delegating a task.
Write a validate_card(card, trusted_domains) function in discovery.py that checks: (a) the card's url field uses HTTPS, (b) the card's url domain is in the trusted_domains list, (c) all skills have non-empty descriptions of at least 8 words, and (d) the authentication block is present and has a valid scheme. Return a structured dict with a passed boolean and a list of validation failure messages.
Simulate a spoofed card attack: create a file spoofed_card.json that contains a card with a plausible-looking name and skills, but whose url field points to a domain not in your trusted_domains list and whose skills have vague one-word descriptions. Run validate_card on it and show the output.
Extend registry_client.py to call validate_card on every card returned by the registry before considering it for delegation. Log a warning and skip any card that fails validation. Demonstrate this by injecting the spoofed card into the registry via POST /register and showing that the Client Agent skips it.
Write a 120 to 160 word analysis of what real-world threats the validation function defends against, and what threats it does not cover that a production system would also need to address.
Task 5: Analysis and Reflection (10 marks)
Write a reflection (200 to 300 words) covering: one decision you made in your registry design that you would change in a production system and why; the most surprising failure mode you encountered during this assignment and how you diagnosed it; and one limitation of the discovery approach you built that a more mature registry or protocol would need to address.
Bonus (Optional — up to +10 Marks)
Add a GET /search endpoint variant that uses LLM-assisted semantic matching to find the best card for a plain English task description, not just a keyword filter.
Add a heartbeat mechanism: remote agents send a POST /heartbeat to the registry every 30 seconds, and the registry marks agents as stale and removes them if no heartbeat is received for 90 seconds.
Extend validate_card to check that the card's url actually responds to an HTTP GET request at /.well-known/agent.json and that the response matches the card being validated. Flag any card whose published version differs from the registered version.
Evaluation Rubric
Criteria | Marks |
Five-Step Discovery Workflow | 25 |
LLM-Assisted Semantic Skill Matching | 20 |
Self-Registering Agent Registry | 25 |
Authentication and Card Validation | 20 |
Analysis and Reflection | 10 |
Total | 100 |
Deliverables
discovery.py — the five-step discovery workflow module with exact and semantic skill matching and card validation.
registry.py — the FastAPI Agent Registry server.
remote_agent.py — the self-registering Remote Agent server.
registry_client.py — the Client Agent that uses the registry for discovery, with validation integrated.
compare_matching.py — the exact vs semantic matching comparison script.
spoofed_card.json — the spoofed card used in the security demonstration.
Terminal output or screenshots showing: all registry operations, the spoofed card being skipped, and the Client Agent selecting the correct agent for two different tasks.
A README.md with instructions for starting the registry, running the remote agents, and executing the client.
Submission Guidelines
Submit your work via the course LMS (for example, Moodle or Google Classroom).
File Naming Convention: <YourName>_AgentDiscovery_Assignment2.zip
Inside the ZIP:
remote_agent.py
registry_client.py
compare_matching.py
spoofed_card.json
requirements.txt
screenshots/ (folder with terminal output images)
Deadline: 7 days from the date of release.
Late Submission Policy
Up to 24 hours late: 10% penalty applied to the final mark.
24 to 48 hours late: 20% penalty applied to the final mark.
Beyond 48 hours: submission will not be accepted.
Important Instructions
The five discovery functions in discovery.py must be independent and testable in isolation. Do not merge them into a single monolithic function.
The registry must be purely in-memory. Do not use a database or file system for storage. The registry data resets when the server restarts — this is expected.
The deregistration endpoint on remote_agent.py must be called from a FastAPI lifespan handler, not from a signal handler or atexit. Test that it fires when you stop the server with Ctrl+C.
The spoofed card must be realistic enough that a naive system would accept it. A card with no name or an empty skills array does not demonstrate the attack — the goal is to show that a structurally valid card can still be malicious.
Plagiarism of any kind will result in disqualification from the assignment.
Guidance and Tips
For the semantic matcher, keep the prompt short and deterministic. Ask the LLM to return only the skill id, nothing else. Parse the response with a strip() and a direct comparison, not a regex, to avoid brittle extraction.
When building the registry search, do not require an exact word match. Use Python's in operator or a simple contains check so that a search for 'invoice' matches a skill described as 'extracts line items from invoice PDFs'.
Test your deregistration lifespan handler by watching the registry's in-memory store before and after stopping the remote agent. Add a GET /agents endpoint to the registry that lists all registered cards — this makes debugging much easier.
For the auth header in registry_client.py, read the header name from the card's authentication block rather than hardcoding X-Agent-Key. The card is the contract — trust it.
When validating card URLs, use Python's urllib.parse.urlparse to extract the scheme and netloc. Do not use string splitting — it breaks on edge cases like ports and paths.
Instructor Note
The most important habit this assignment is designed to build is thinking from the Client Agent's perspective. Every decision in your registry design, your skill descriptions, and your validation logic should be evaluated through the question: what does a Client Agent that has never seen my code need in order to use this correctly? A registry that works perfectly when everything goes right is not enough. A submission that handles missing cards, bad skill descriptions, stale registrations, and spoofed cards gracefully — and can explain why each failure mode matters — will always score higher than one that only covers the happy path.
Call to Action
Ready to transform your business with AI-powered intelligence that accelerates insights, enhances decision-making, and unlocks the full value of your data?
Codersarts is here to help you turn complex data workflows into efficient, scalable, and evidence-driven AI systems that empower teams to make smarter, faster, and more confident decisions.
Whether you’re a startup looking to build AI-driven products, an enterprise aiming to optimize operations through data science, or a research organization advancing innovation with intelligent data solutions, we bring the expertise and experience needed to design, develop, and deploy impactful AI systems that drive measurable business outcomes.
Get Started Today
Schedule an AI & Data Science Consultation:
Book a 30-minute discovery call with our AI strategists and data science experts to discuss your challenges, identify high-impact opportunities, and explore how intelligent AI solutions can transform your workflows and performance.
Request a Custom AI Demo:
Experience AI in action with a personalized demonstration built around your business use cases, datasets, operational environment, and decision workflows — showcasing practical value and real-world impact.
Email: contact@codersarts.com
Transform your organization from data accumulation to intelligent decision enablement — accelerating insight generation, improving operational efficiency, and strengthening competitive advantage.
Partner with Codersarts to build scalable AI solutions including RAG systems, predictive analytics platforms, intelligent automation tools, recommendation engines, and custom machine learning models that empower your teams to deliver exceptional results.
Contact us today and take the first step toward next-generation AI and data science capabilities that grow with your business ambitions.

Comments