DEV Community

Humphery
Humphery

Posted on

Building “Exhibit”: An AI-Powered Portfolio Agent with Mastra, A2A, and Telex

By Humphery Otuoniyo

As developers, showcasing our work effectively can sometimes be as challenging as building the projects themselves. I recently built Exhibit, an intelligent agent that generates personalized developer portfolios directly from GitHub repositories and a preferred tech stack. In this article, I’ll walk you through the process of building the agent using Mastra, setting up the A2A protocol for agent communication, and integrating it with Telex for a seamless front-end experience.


1. Why Exhibit?

The motivation behind Exhibit was simple: developers often have many repositories on GitHub, but not all of them are portfolio-ready. Manually curating projects and writing polished descriptions can be time-consuming. Exhibit automates this process by:

  • Fetching GitHub repositories using the user’s username.
  • Selecting projects that match the user’s tech stack.
  • Generating a clean, structured portfolio in Markdown format.
  • Organizing sections such as Introduction, Tech Stack, Projects, and Contact information.

This ensures developers have a professional, ready-to-publish portfolio in minutes.


2. Building the Agent with Mastra

Mastra provides a framework for building intelligent agents that can combine AI models, tools, and memory. Here’s how I defined the Exhibit Agent:

import { Agent } from "@mastra/core/agent";
import { Memory } from "@mastra/memory";
import { LibSQLStore } from "@mastra/libsql";
import { githubRepoTool } from "../tools/exhibit-tool";
import { scorers } from "../scorers/exhibit-scorer";

export const exhibitAgent = new Agent({
  name: "Exhibit Agent",
  instructions: `
    You are Exhibit — an AI that generates a professional portfolio from GitHub repositories...
  `,
  model: "google/gemini-2.5-flash",
  tools: { githubRepoTool },
  scorers: scorers,
  memory: new Memory({
    storage: new LibSQLStore({ url: "file:../mastra.db" }),
  }),
});
Enter fullscreen mode Exit fullscreen mode

Key highlights:

  • Tools integration: The agent uses githubRepoTool to fetch repositories and metadata.
  • Custom scoring: I implemented scorers to evaluate the quality, completeness, and appropriateness of tool usage in generating the portfolio.
  • Memory: Using LibSQLStore ensures the agent remembers previous interactions, improving follow-up portfolio generations.

3. Setting Up the A2A Protocol

A2A (Agent-to-Agent) is Mastra’s protocol for sending structured messages between clients and agents. It follows the JSON-RPC 2.0 specification. Here’s how the A2A route was defined:

import { registerApiRoute } from "@mastra/core/server";

export const a2aAgentRoute = registerApiRoute("/a2a/agent/:agentId", {
  method: "POST",
  handler: async (c) => {
    const mastra = c.get("mastra");
    const agentId = c.req.param("agentId");
    const body = await c.req.json();

    const agent = mastra.getAgent(agentId);
    const messages = body.params?.messages || [];

    const mastraMessages = messages.map(msg =>
      `${msg.role}: ${msg.parts.map(p => p.text || JSON.stringify(p.data)).join("\n")}`
    );

    const response = await agent.generate(mastraMessages);
    return c.json({ jsonrpc: "2.0", id: body.id, result: response });
  },
});
Enter fullscreen mode Exit fullscreen mode

This route:

  • Receives user messages in JSON-RPC format.
  • Converts them into the string format expected by agent.generate.
  • Returns the agent’s response, including artifacts and portfolio text.

With this, any client can communicate with Exhibit securely and reliably.


4. Integrating with Telex

Telex acts as a front-end interface for your agents. It provides a low-code platform to create workflows and connect your A2A agent nodes. For Exhibit:

  1. I defined an A2A node pointing to the deployed agent:
{
  "id": "exhibit_agent",
  "name": "exhibit agent",
  "type": "a2a/mastra-a2a-node",
  "url": "https://rapid-purple-library-8c383acc-5862-46c4-b9ea-3451fc36ac61.mastra.cloud/a2a/agent/exhibitAgent"
}
Enter fullscreen mode Exit fullscreen mode
  1. Created a workflow where users input:
  • GitHub username
  • Preferred tech stack
  1. The agent processes this input, fetches repositories, and outputs a ready-to-use Markdown portfolio.

This integration makes it possible to test and deploy Exhibit without building a full front-end from scratch.


5. Testing the Agent

Once deployed, you can test Exhibit via any HTTP client (like Postman or curl) using JSON-RPC messages:

curl -X POST "https://<your-mastra-domain>/a2a/agent/exhibitAgent" \
-H "Content-Type: application/json" \
-d '{
  "jsonrpc": "2.0",
  "id": "test-1",
  "method": "generate",
  "params": {
    "message": {
      "role": "user",
      "parts": [{"kind": "text", "text": "GitHub username: octocat, tech stack: JavaScript, React"}]
    }
  }
}'
Enter fullscreen mode Exit fullscreen mode

The response will contain the portfolio Markdown text, ready to save or display.


6. What I Learned

  • Mastra’s flexibility allows for combining AI, tools, and memory efficiently.
  • A2A protocol simplifies structured communication between agents and clients.
  • Telex integration enables low-code testing and workflow management.
  • Automating portfolio generation can save developers hours while ensuring professionalism.

7. Next Steps

  • Add portfolio customization options, like themes or formats.
  • Integrate more GitHub analytics (stars, commits) for project selection.
  • Explore multi-agent workflows to build a complete developer dashboard.

Exhibit is now live and working! This project demonstrates the power of combining AI agents, structured messaging, and low-code workflows to automate developer-focused tasks. Code for the project can be found at my GitHub

Top comments (0)