Skip to content
Back to skills

Guides

ASecurity

A *skill* here is a named capability **A2A callers can dispatch to**. It lives on the agent card, not in your Python code: adding one does not create a new handler — it advertises an existing capability so callers can target it. ::: warning Not the same as a `SKILL.md` skill If you're trying to teach *your own* agent a procedure it loads mid-turn, that's a [`SKILL.md` skill](/guides/skills) — a different subsystem that happens to share the word. This page is only about what other agents can c...

  • 11 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 2, 2026
ai-agentspythongobashreactgit

Security analysis

A96/100
  • mediumUses curl or wget to download content

Pro scans all 21 files and shows the line behind each finding

Scanned October 2, 2026

npx -y skills add protoLabsAI/protoAgent --skill guides --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Guides?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Guides
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/protolabsai-guides/badge)](https://www.skillsdirectory.com/skills/protolabsai-guides)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Add a custom skill

A *skill* here is a named capability **A2A callers can dispatch to**. It lives on the
agent card, not in your Python code: adding one does not create a new handler — it
advertises an existing capability so callers can target it.

::: warning Not the same as a `SKILL.md` skill
If you're trying to teach *your own* agent a procedure it loads mid-turn, that's a
[`SKILL.md` skill](/guides/skills) — a different subsystem that happens to share the
word. This page is only about what other agents can call over A2A.
:::

## When you need a skill

- You want another agent (via A2A) to invoke a specific mode of behaviour — e.g. `pr_review` vs. `bug_triage`.
- You want a planner to rank your agent against a specific goal.
- You want per-skill cost telemetry (cost-v1 samples are keyed by `(agent, skill)`).

You don't need a skill for "things the chat UI does" — the React console chat is already covered by the default dispatch path.

## 1. Declare it in config

Card skills are config-driven ([#570](/reference/configuration#a2a)) — declare them in the `a2a:` section of `config/langgraph-config.yaml`, **not** by editing `server/a2a.py`. Each entry is a spec:

```yaml
a2a:
  skills:
    - id: summarize_pr
      name: Summarize Pull Request
      description: Fetch a GitHub PR and return a three-bullet summary of what it changes and why.
      tags: [github, summarization]
      examples:
        - "summarize https://github.com/protoLabsAI/protoAgent/pull/64"
```

The server merges these (plus any contributed by plugins via `register_a2a_skill`) and falls back to the template's `chat` placeholder when none are set. A plugin can ship card skills the same way — `registry.register_a2a_skill(spec)` — so a distributable extension carries its own advertised capabilities.

**IDs are sticky**. `cost-v1` samples, `effect-domain-v1` declarations, and a consumer's routing all key off the `id`. Pick one and don't rename later.

## 2. (Optional) Declare an effect

If the skill actually mutates shared state a planner cares about (creates a PR, files an issue, updates a board), declare it under `effect-domain-v1`:

```python
"capabilities": {
    "streaming": True,
    "pushNotifications": True,
    "extensions": [
        {"uri": "https://proto-labs.ai/a2a/ext/cost-v1"},
        {
            "uri": "https://proto-labs.ai/a2a/ext/effect-domain-v1",
            "params": {
                "skills": {
                    "file_bug": {
                        "effects": [{
                            "domain": "protomaker_board",
                            "path": "data.backlog_count",
                            "delta": 1,
                            "confidence": 0.9,
                        }],
                    },
                },
            },
        },
    ],
},
```

Only declare effects for skills that actually mutate shared state. Over-declaring confuses the L1 planner into routing your agent for goals it can't move.

## 3. Teach the LLM about the skill

Skill dispatch doesn't add code paths — the A2A handler just forwards the caller's message to the same LangGraph runtime that handles chat. What makes a skill *do something* is that the system prompt teaches the LLM how to behave when it sees a request matching the skill's intent.

Add the skill's behaviour description to your persona file, **`config/SOUL.md`** (the wizard writes it; `graph/prompts.py::build_system_prompt` reads it into the system prompt — you don't edit `prompts.py`):

```markdown
You handle general chat plus these skills:

- **summarize_pr** — when the user sends a GitHub PR URL, fetch the PR
  with `github_get_pr`, then return a three-bullet summary: what changed,
  why, and any risks. Keep each bullet under two sentences.
```

The LLM routes by reading the user's message. Skill IDs on the card exist for callers; skill *behaviour* lives in `SOUL.md`.

## 4. Verify on the card

```bash
curl http://localhost:7870/.well-known/agent-card.json | jq '.skills[] | .id'
# "chat"
# "summarize_pr"
```

And hit it via A2A:

```bash
curl -X POST http://localhost:7870/a2a \
    -H 'Content-Type: application/json' \
    -d '{
      "jsonrpc": "2.0",
      "id": "1",
      "method": "message/send",
      "params": {
        "message": {
          "role": "user",
          "parts": [{"text": "summarize https://github.com/protoLabsAI/protoAgent/pull/64"}]
        },
        "metadata": {"skillHint": "summarize_pr"}
      }
    }'
```

## 5. Test it

Assert your config declares the skill (it flows to the card via `_resolved_skill_specs`):

```python
def test_config_advertises_summarize_pr():
    from graph.config import LangGraphConfig
    cfg = LangGraphConfig.from_yaml("config/langgraph-config.yaml")
    assert "summarize_pr" in {s["id"] for s in cfg.a2a_skills}
```

## Related

- [Agent card reference](/reference/agent-card) — the full card shape
- [Extensions reference](/reference/extensions) — `cost-v1`, `effect-domain-v1`, `a2a.trace`
- [A2A endpoints reference](/reference/a2a-endpoints) — how callers reach skills

Files in this skill

  • acp-runtime.md7.7 KB
  • add-a-skill.md5 KB
  • agent-snapshots.md9.8 KB
  • browser-automation.md12.4 KB
  • build-with-a-coding-agent.md27.4 KB
  • building-react-plugin-views.md30.4 KB
  • bundles.md10.5 KB
  • cli.md24.7 KB
  • coder.md4.6 KB
  • coding-agents.md23.6 KB
  • command-palette.md16.9 KB
  • communication-plugins.md3.2 KB
  • customize-and-deploy.md9.5 KB
  • delegates.md18.7 KB
  • deploy-docker.md14.8 KB
  • deploy-proxmox.md8.1 KB
  • deploy.md8.3 KB
  • developer-flags.md3.8 KB
  • discord.md10.9 KB
  • evals.md20.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.