Generates and deploys pro-code AI agents using LangGraph and SAP GenAI Hub to SAP BTP Cloud Foundry as REST APIs, creates Joule capabilities with A2A actions. Supports TypeScript (Express/CAP) and Python.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sap-a2a-agent-toolkit:joule-a2a-agentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill generates a complete pro-code AI agent project that:
evals/evals.jsonreferences/cf-deployment-cap-typescript.mdreferences/cf-deployment-typescript.mdreferences/cf-deployment.mdreferences/joule-capability.mdreferences/langgraph-a2a-agent-cap-typescript.mdreferences/langgraph-a2a-agent-typescript.mdreferences/langgraph-a2a-agent.mdscripts/create-destination.shscripts/scaffold-ts.shscripts/scaffold.pyThis skill generates a complete pro-code AI agent project that:
cf push or MTA)SAP Joule can orchestrate external agents using the A2A (Agent-to-Agent) protocol. The flow is:
/.well-known/agent.jsonThe connection between Joule and your agent uses a BTP Destination + a Joule capability YAML that defines an agent-request action type.
Joule DTA Schema Version 3.28.0+ Required: Code-based agents (BYOA) using the agent-request action type are supported as of DTA schema version 3.28.0. The capability.sapdas.yaml must specify schema_version: "3.28.0".
If your Joule tenant runs an older schema version, the compile will succeed but deploy will fail with: "Schema version defined in config file is greater than the current schema version of Joule".
How to check your tenant's version:
joule login --use-env (or joule login )joule statusOther prerequisites:
npm install -g @sap/joule-studio-clicf login or cf login )joule login or joule login --use-env)extensibility_developer + capabilityadmin for Joule deploymentsmbt (MTA Build Tool): npm install -g mbtcf install-plugin multiapps (required for cf deploy with .mtar files)Before you start, make sure Claude Code is started with the toolkit plugin and you are logged in to both CLIs:
# Start Claude Code with the SAP A2A Agent Toolkit plugin
claude --plugin-dir <path-to-sap-a2a-agent-toolkit>
# Log in to Cloud Foundry
cf login -a https://api.cf.<landscape>.hana.ondemand.com
# Log in to Joule
joule login
When the user asks to create/modify a Joule A2A agent, follow these steps:
Ask the user:
gpt-4.1)If the user is unsure about BTP details, generate the project anyway with placeholder values.
The project can be generated in three configurations:
Run the scaffold script:
bash <skill-path>/scripts/scaffold-ts.sh \
--name <agent-name> \
--framework express \
--namespace <company-namespace> \
--output <output-dir> \
--description "<agent description>" \
--landscape <cf-landscape>
Or manually using references/langgraph-a2a-agent-typescript.md + references/cf-deployment-typescript.md.
<agent-name>/
├── src/
│ ├── index.ts # Express + A2A server entry point
│ ├── agent.ts # LangGraph.js ReAct agent
│ ├── executor.ts # A2A protocol bridge
│ ├── agentCard.ts # Agent Card definition
│ ├── tools.ts # Agent's tools (Zod schemas)
│ └── llm.ts # SAP GenAI Hub configuration
├── joule-capability/
│ ├── capability.sapdas.yaml
│ ├── capability_context.yaml
│ ├── da.sapdas.yaml
│ ├── functions/call_agent.yaml
│ └── scenarios/invoke_agent.yaml
├── package.json
├── tsconfig.json
├── manifest.yml
├── Procfile
├── .env.example
└── README.md
Run the scaffold script:
bash <skill-path>/scripts/scaffold-ts.sh \
--name <agent-name> \
--framework cap \
--namespace <company-namespace> \
--output <output-dir> \
--description "<agent description>" \
--landscape <cf-landscape>
Or manually using references/langgraph-a2a-agent-cap-typescript.md + references/cf-deployment-cap-typescript.md.
<agent-name>/
├── srv/
│ ├── server.ts # CAP bootstrap + A2A Express endpoints
│ ├── agent-executor.ts # LangGraph StateGraph agent orchestrator
│ ├── service.cds # CDS service definition
│ ├── tools/
│ │ └── tools.ts # Agent tools (Zod schemas)
│ └── utils/
│ ├── prompts.ts # System prompt
│ ├── a2aToLangchain.ts # A2A → LangChain converter
│ ├── a2a-operations.ts # A2A event helpers
│ └── helpers.ts # URL helpers
├── joule-capability/
│ ├── capability.sapdas.yaml
│ ├── capability_context.yaml
│ ├── da.sapdas.yaml
│ ├── functions/call_agent.yaml
│ └── scenarios/invoke_agent.yaml
├── package.json
├── tsconfig.json
├── mta.yaml
├── .cdsrc.sample.json
├── .env.example
└── README.md
Run the scaffold script:
python <skill-path>/scripts/scaffold.py \
--name <agent-name> \
--namespace <company-namespace> \
--output <output-dir> \
--description "<agent description>" \
--landscape <cf-landscape>
Or manually using references/langgraph-a2a-agent.md + references/cf-deployment.md.
| Aspect | TS Express | TS CAP | Python |
|---|---|---|---|
| Server | Express + jsonRpcHandler/agentCardHandler | CAP + cds.on("bootstrap") | Starlette + A2AStarletteApplication |
| A2A SDK | @a2a-js/sdk 0.3.10 | @a2a-js/sdk 0.3.10 | a2a-sdk >=0.2.7 |
| LLM | OrchestrationClient | OrchestrationClient | langchain-openai ChatOpenAI (direct AI Core endpoint) |
| Deploy | cf push (manifest.yml) | mbt build && cf deploy (mta.yaml) | cf push (manifest.yml) |
| Auth | Manual | Built-in CAP auth | Manual |
| Agent pattern | createReactAgent | StateGraph (manual) | create_react_agent |
| Interrupt support | Basic (question heuristic) | Full (LangGraph interrupt()) | Structured response format |
| Buildpack | nodejs_buildpack | nodejs_buildpack (via MTA) | python_buildpack |
| Reference | langgraph-a2a-agent-typescript.md | langgraph-a2a-agent-cap-typescript.md | langgraph-a2a-agent.md |
The Joule capability YAML files are identical regardless of language/framework.
Based on the user's requirements:
Define tools — In TypeScript: functions created with tool() and Zod schemas. In Python: functions decorated with @tool. Map each user requirement to a tool function.
src/tools.tssrv/tools/tools.tsapp/tools.pyConfigure the agent — Set the system instruction to match the agent's purpose.
SYSTEM_PROMPT in src/agent.tssrv/utils/prompts.tsSYSTEM_INSTRUCTION in app/agent.pySet up the Agent Card — Name, skills, and supported modes.
src/agentCard.tsagentCard in srv/server.tsapp/agent_card.pyConfigure capability.sapdas.yaml — The scenario description in scenarios/invoke_agent.yaml must clearly describe when Joule should invoke this agent.
Read references/cf-deployment-typescript.md or references/cf-deployment.md.
cd <agent-name>
npm install
npm run build # TypeScript only — must compile before push
cf push
curl https://<app-url>/.well-known/agent.json
Read references/cf-deployment-cap-typescript.md.
cd <agent-name>
npm install
mbt build
cf deploy mta_archives/<agent-name>_1.0.0.mtar
curl https://<agent-name>-srv.cfapps.<landscape>.hana.ondemand.com/.well-known/agent.json
After deployment, create a BTP Destination pointing to the agent's URL:
bash <skill-path>/scripts/create-destination.sh \
--agent-name <agent-name> \
--destination-name <DESTINATION_NAME> \
--landscape <cf-landscape>
The destination name must match system_aliases.<AliasName>.destination in capability.sapdas.yaml.
Read references/joule-capability.md for the complete reference.
# Install Joule CLI (if not installed)
npm install -g @sap/joule-cli
# Authenticate
joule login # or joule login --use-env
# Navigate to the joule-capability directory
cd joule-capability
# Compile + deploy
joule deploy ./da.sapdas.yaml --compile -n "<assistant_name>"
If it doesn't work, check: destination configuration, agent card accessibility, capability scenario description matching, and CF app logs (cf logs <app-name> --recent).
When the user wants to change an existing agent:
Adding a new tool: Add the tool function, register it in the agent, add a skill to the agent card. Redeploy to CF.
Changing the model: Update MODEL_NAME env var. The model must be deployed on your AI Core instance.
Updating the Joule capability: Edit capability.sapdas.yaml and scenario files, recompile and redeploy with joule deploy ./da.sapdas.yaml --compile.
Scaling: Adjust instances and memory in manifest.yml (Express) or mta.yaml (CAP).
Read these before generating code:
references/langgraph-a2a-agent-typescript.md — TypeScript Express templates (jsonRpcHandler, agentCardHandler, createReactAgent, OrchestrationClient)references/langgraph-a2a-agent-cap-typescript.md — TypeScript CAP templates (cds.on bootstrap, StateGraph, interrupt support)references/langgraph-a2a-agent.md — Python templates (A2AStarletteApplication, create_react_agent, langchain-openai with direct AI Core credentials)references/cf-deployment-typescript.md — TypeScript Express: manifest.yml, package.json, cf pushreferences/cf-deployment-cap-typescript.md — TypeScript CAP: mta.yaml, mbt build, cf deployreferences/cf-deployment.md — Python: manifest.yml, requirements.txt, Procfilereferences/joule-capability.md — Multi-file DTA format: capability.sapdas.yaml (schema 3.28.0), da.sapdas.yaml (schema 1.4.0), functions/, scenarios/, multi-turn contextId/taskId patternmessage/send and optionally message/stream methods./.well-known/agent.json for Joule's discovery.OrchestrationClient from @sap-ai-sdk/langchain (auto-reads VCAP_SERVICES).langchain-openai ChatOpenAI pointed at AI Core's OpenAI-compatible endpoint (do NOT use generative-ai-hub-sdk — pydantic version conflict with a2a-sdk).@sap/joule-cli) requires the capabilityadmin and extensibility_developer roles.da.sapdas.yaml uses schema version 1.4.0. The capability.sapdas.yaml uses 3.28.0.joule.ext — the metadata.namespace in capability.sapdas.yaml must be set to joule.ext. Using any other namespace (e.g. mycompany) will cause joule deploy to fail with a namespace validation error. The scaffold scripts default to joule.ext.mbt (npm install -g mbt) for building and the MTA CF CLI plugin (cf install-plugin multiapps) for cf deploy to work with .mtar files. See CAP deploy to CF guide.npx claudepluginhub sap-samples/joule-a2a-agent-toolkitManages SAP Joule digital assistants via CLI: compiles capabilities, deploys assistants, runs BDD tests with Cucumber, lints code, authenticates logins, and troubleshoots errors.
Guides developers to create new AgentCore agent projects on AWS: framework selection (Strands, LangGraph), project scaffolding, first deploy, and invocation. For beginners or 'agentcore create'.
Agent-to-Agent (A2A) protocol implementation patterns for Google ADK - exposing agents via A2A, consuming external agents, multi-agent communication, and protocol configuration. Use when building multi-agent systems, implementing A2A protocol, exposing agents as services, consuming remote agents, configuring agent cards, or when user mentions A2A, agent-to-agent, multi-agent collaboration, remote agents, or agent orchestration.