CtrlK
BlogDocsLog inGet started
Tessl Logo

deporvillage/gemini-a2a-tile

Gemini Enterprise A2A configuration and rules.

73

Quality

73%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/scaffold-gemini-agent/

name:
scaffold-gemini-agent
description:
Scaffolds a complete A2A agent specifically configured for Gemini Enterprise compatibility, including the JSON-RPC root path and a health check.

Scaffold Gemini A2A Agent

Steps

Step 1 — Gather requirements

Ask the user for:

  • Agent Name
  • Description
  • Public URL (from tunnel/deployment)

Step 2 — Generate main.py

Use the following template which includes the root JSON-RPC POST and GET health check:

import uvicorn
from starlette.responses import JSONResponse
from starlette.routing import Route
from starlette.requests import Request
from starlette.middleware.base import BaseHTTPMiddleware
from a2a.server.apps.jsonrpc.starlette_app import A2AStarletteApplication
from a2a.server.request_handlers.default_request_handler import DefaultRequestHandler
from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore
from card import agent_card
from agent import <AgentName>Executor

class LoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        if request.method == "POST":
            print(f"\n>>> [A2A REQUEST] {request.method} {request.url.path}")
        return await call_next(request)

a2a_app_builder = A2AStarletteApplication(
    agent_card=agent_card,
    http_handler=DefaultRequestHandler(
        agent_executor=<AgentName>Executor(),
        task_store=InMemoryTaskStore(),
    ),
)

app = a2a_app_builder.build()
app.add_middleware(LoggingMiddleware)

async def health_check(request: Request):
    return JSONResponse({"status": "running", "discovery": "/.well-known/agent-card.json"})

app.routes.append(Route("/", health_check, methods=["GET"]))

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

Step 3 — Generate agent_card.json (Validator-compliant)

Ensure it uses camelCase and the protocolVersion field:

{
  "protocolVersion": "v1",
  "name": "<name>",
  "description": "<description>",
  "url": "<public-url>/",
  "version": "1.0.0",
  "capabilities": { "streaming": true },
  "skills": [
    {
      "id": "main_skill",
      "name": "Main Skill",
      "description": "<skill-description>",
      "tags": [],
      "inputModes": ["text/plain"],
      "outputModes": ["text/plain"]
    }
  ],
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "securitySchemes": {
    "geminiAuth": {
      "type": "oauth2",
      "description": "Google OAuth2 authentication for Gemini Enterprise",
      "flows": {
        "authorizationCode": {
          "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline",
          "tokenUrl": "https://oauth2.googleapis.com/token",
          "scopes": {
            "openid": "Get user identity",
            "profile": "Access user profile",
            "email": "Access user email"
          }
        }
      }
    }
  },
  "security": [
    {
      "geminiAuth": ["openid", "profile", "email"]
    }
  ]
}

Checklist

  • JSON keys are camelCase
  • protocolVersion is "v1"
  • Root path handles POST (JSON-RPC) and GET (Health Check)
  • All events include both task_id and context_id
  • The authorizationUrl includes ?access_type=offline
  • Identity is extracted via Google UserInfo introspection (not JWT decoding)

skills

scaffold-gemini-agent

tile.json