github / github/github-mcp-server

Feature Request: `get_agent_card` tool — load ALP-compatible agents directly from GitHub repos

オープン
#2,299 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る
enhancement request ai review
主要言語
Go
スター
33k
フォーク
5k
平均マージ
2日 1時間
マージ済み PR(30日)
52

説明

## Summary

Add a `get_agent_card` tool to the GitHub MCP Server that reads a
structured agent descriptor file from any repository and returns it as a
parsed, schema-validated JSON object.

The tool defaults to `agent.alp.json` at the repo root, with an optional
`filename` parameter to support any structured agent descriptor format a
developer may use.

This closes the last gap between an agent living in a GitHub repo and that
agent being live in any MCP-compatible runtime (Kiro, Claude Code, Claude
Desktop, VS Code, Cursor) — in one tool call.

---

## Background: what ALP is

Agent Load Protocol (ALP) is an open, MCP-compatible format for describing
complete AI agents as a single portable artifact — the Agent Card
(`agent.alp.json`).

What MCP is to tools, ALP is to entire agents.

An Agent Card declares:

- `id`, `name`, `description` — agent identity
- `persona` — the full system prompt
- `tools[]` — MCP-compatible tool endpoints (local or proxied HTTP)
- `memory` — session/persistent memory config
- `llm` — provider preference (any, user-resolved)
- `server.url` + `server.transport` — where the ALP Server lives
- `toolsets`, `security.read_only`, `pagination` — runtime control fields
- (mirrors concepts already in the GitHub MCP Server)

Current version: v0.9.0

Spec + reference implementation:
https://github.com/RodrigoMvs123/agent-load-protocol

Live demo MCP endpoint:
https://agent-load-protocol.onrender.com/mcp

Any MCP host can load the live demo agent today with:

```json
{
"mcpServers": {
"hello-agent": {
"type": "http",
"url": "https://agent-load-protocol.onrender.com/mcp"
}
}
}
```

---

## The gap this tool closes

The GitHub MCP Server already has `get_file_contents`, which can read any
file from a repo — including `agent.alp.json`.

However, it returns a raw base64-encoded blob. The caller must:

1. Decode
2. JSON-parse
3. Validate manually

before the agent can be used.

`get_agent_card` would instead return a typed, schema-validated JSON object
directly usable by any ALP-aware runtime.

This is the difference between `GET /blob` and `GET /agent` — structured
semantics vs raw bytes.

---

## Agent definitions: file vs. API level

Developers today define agents in two fundamentally different ways.

### API-level definition (e.g. Anthropic Managed Agents)

When using a managed agent platform, the agent is defined entirely inside
an API call — no file is ever committed to a repository:

```json
POST /v1/agents
{
"name": "My Assistant",
"model": "claude-sonnet-4-20250514",
"system_prompt": "You are a helpful assistant.",
"tools": [
{ "type": "bash" },
{ "type": "web_search" }
],
"mcp_servers": [
{ "type": "http", "url": "https://my-server.com/mcp" }
]
}
```

The platform responds with an `agent_id`. The definition lives in managed
infrastructure, not in the GitHub repo. A developer following this path
has no descriptor file for `get_agent_card` to read.

**This is outside the scope of `get_agent_card`.** The tool operates on
files committed to a repository. API-level agent definitions are not
reachable by a file-reading tool — this is an explicit boundary, not a
gap to be solved here.

### File-level definition (repo-committed descriptor)

When a developer commits a structured agent descriptor to their repo,
`get_agent_card` can read it, parse it, validate it, and return a typed
object in one call — regardless of which format the descriptor follows.

This is the scope `get_agent_card` is designed for.

---

## Proposed tool

**Tool name:** `get_agent_card`
**Toolset:** `repos` (existing) — or a new lightweight `alp` toolset
**Required OAuth scope:** `repo` (same as `get_file_contents`)

### Input parameters

| Parameter | Type | Required | Description |
|------------|--------|----------|-------------|
| `owner` | string | yes | Repository owner |
| `repo` | string | yes | Repository name |
| `ref` | string | no | Branch, tag, or commit SHA (defaults to repo default branch) |
| `path` | string | no | Path to the card file (defaults to `agent.alp.json` at repo root) |
| `filename` | string | no | Override the descriptor filename (defaults to `agent.alp.json`). Supports any structured agent descriptor format stored in the repo. |

### Filename parameter — design rationale

Developers building agents with different frameworks may store their agent
descriptor under different filenames:

- `agent.alp.json` — ALP format (default)
- `.github/agent.json` — GitHub-native convention
- `agent-card.json` — AI Catalog alignment
- Any other structured JSON descriptor

The `filename` parameter is not a format selector — it is a filepath
instruction to the GitHub file API. The tool fetches whatever file lives
at that path, decodes the base64 content, parses it as JSON, and returns
it as a structured object.

Validation behavior:

- If `alp_version` is present in the parsed JSON → ALP schema validation
runs and any offending fields are reported
- If `alp_version` is absent → ALP validation is skipped and the raw
parsed JSON is returned as-is

This means the tool works correctly for any JSON descriptor format. A
caller using ALP gets schema validation automatically. A caller using a
different format gets a clean JSON object without ALP-specific errors.

| Convention | filename value | ALP validation |
|---|---|---|
| ALP (default) | `agent.alp.json` | ✅ runs |
| AI Catalog | `agent-card.json` | skipped, raw JSON returned |
| GitHub-native | `.github/agent.json` | skipped, raw JSON returned |
| Custom | any `.json` path | skipped, raw JSON returned |

This avoids permanent lock-in to a single format while remaining
immediately useful today.

### Output (parsed Agent Card object)

```json
{
"alp_version": "0.9.0",
"id": "my-agent",
"name": "My Agent",
"persona": "You are a helpful assistant.",
"tools": [
{
"name": "search",
"description": "Search the knowledge base.",
"endpoint": "https://my-server.com/api/search"
}
],
"server": {
"url": "https://my-alp-server.com",
"transport": "http"
},
"llm": { "provider": "any" },
"memory": { "enabled": false }
}
```

If the file is not found at the given path, the tool returns a clear error.
If the file exists but fails ALP schema validation, the tool returns a
validation error identifying the offending fields.

---

## How it unlocks the full GitHub → Kiro flow

With this tool approved and shipped, the end-to-end flow becomes:

```
Developer commits agent.alp.json to any GitHub repo

Kiro (or any MCP host) calls get_agent_card { owner, repo }

GitHub MCP Server fetches + parses + validates the card

ALP runtime (Kiro) reads persona → injects into LLM context
ALP runtime reads tools[] → registers MCP-compatible endpoints

Agent is live in the Kiro chat window
```

No local clone. No manual config. One tool call.

This is the scenario that ALP's remote card mode (v0.6.0) was designed for:

- Ship `agent.alp.json` in your GitHub repo
- Point a runtime at it
- Agent is live

The GitHub MCP Server is the natural discovery bridge — it already sits
between GitHub and every major IDE.

`get_agent_card` completes that bridge.

---

## Real-world implementation — `hello-agent-alp-kiro` (ALP v0.9.0)

Since this issue was opened, a real ALP v0.9.0 agent following this exact
pattern has been built, deployed, and tested in Kiro.

**Repository:** https://github.com/RodrigoMvs123/hello-agent-alp-kiro
**Live Agent Card:** https://hello-agent-alp-kiro.onrender.com/agent
**Live MCP endpoint:** https://hello-agent-alp-kiro.onrender.com/mcp

All 4 tools (`greet`, `echo`, `get_agent_card`, `chat`) have been verified
in Kiro.

### How the flow works today (without get_agent_card)

Kiro currently uses `get_file_contents` to read the card:

```
get_file_contents({
owner: "RodrigoMvs123",
repo: "hello-agent-alp-kiro",
path: "agent.alp.json"
})
→ returns base64 blob → manual decode → manual JSON parse → no schema validation
```

Then `create_workflow_dispatch` to trigger deployment:

```
create_workflow_dispatch({
owner: "RodrigoMvs123",
repo: "hello-agent-alp-kiro",
workflow_id: "deploy.yml"
})
→ GitHub Actions injects secrets → agent deploys to Render → Kiro connects to /mcp
```

This works. But the `get_file_contents` step is the exact gap described in
this issue.

### What get_agent_card would replace

Exactly one step:

```
// today
get_file_contents({ owner, repo, path: "agent.alp.json" })
→ base64 blob, no validation, caller parses manually

// with get_agent_card
get_agent_card({ owner: "RodrigoMvs123", repo: "hello-agent-alp-kiro" })
→ typed, schema-validated Agent Card
→ runtime.deploy block surfaced directly — trigger, workflow path, credential refs
→ clear error if agent.alp.json is missing or malformed
```

The `runtime.deploy` block (new in ALP v0.9.0) is what makes this
structured:

```json
"runtime": {
"deploy": {
"trigger": "github_actions",
"workflow": ".github/workflows/deploy.yml",
"credentials": [
{ "ref": "GEMINI_API_KEY", "source": "github_secrets" },
{ "ref": "RENDER_API_KEY", "source": "github_secrets" },
{ "ref": "RENDER_SERVICE_ID", "source": "github_secrets" }
]
}
}
```

When `get_agent_card` returns this as a typed object, Kiro knows
immediately — without parsing a blob — that this agent deploys via GitHub
Actions, what workflow to trigger, and what credentials are declared. The
rest of the flow follows automatically.

The pattern works today with `get_file_contents` as a workaround.
`get_agent_card` makes it first-class.

---

## Alignment with existing GitHub MCP Server patterns

| GitHub MCP Server feature | ALP equivalent |
|---|---|
| `--toolsets` flag / `GITHUB_TOOLSETS` env var | ALP `toolsets.groups` + `toolsets.active` |
| `--read-only` flag | ALP `security.read_only` + per-tool `readonly: false` |
| `--dynamic-toolsets` beta | ALP `tools_discovery.mode: "dynamic"` |
| `server.json` manifest at repo root | ALP `server.alp.json` manifest at server root |
| `--insiders` / insiders URL | ALP `server.channel: "insiders"` + `insiders_url` |
| Tool description env-var overrides | ALP `description_override_key` per tool |
| Deprecated tool aliases | ALP `tools[].aliases` + `tools[].deprecated` |

ALP modeled several of these fields directly from the GitHub MCP Server
architecture.

`get_agent_card` is a natural extension in the same direction.

---

## Implementation sketch

```go
// In pkg/github/repos.go (or a new alp.go file in the repos toolset)

func GetAgentCard(owner, repo, ref, path, filename string) (*ALPCard, error) {
// 1. Resolve filename (default: "agent.alp.json")
if filename == "" {
filename = "agent.alp.json"
}
// 2. Resolve path (default: filename at repo root)
if path == "" {
path = filename
}
// 3. Call existing GetFileContents(owner, repo, path, ref)
// 4. Decode base64 content
// 5. json.Unmarshal into map[string]interface{} or ALPCard struct
// 6. If alp_version field present → validate against ALP schema
// If alp_version field absent → skip validation, return raw parsed JSON
// 7. Return parsed struct (or validation error)
}
```

The implementation wraps `get_file_contents` — no new GitHub API calls
needed.

ALP JSON schema:
https://github.com/RodrigoMvs123/agent-load-protocol/blob/main/schema/agent.alp.schema.json

---

## Optional: server.alp.json companion endpoint

ALP v0.3.0+ defines a `server.alp.json` manifest that ALP-aware clients
read before the full agent card to understand server capabilities:

- Supported transports
- Auth methods
- Available channels

A companion tool:

- `get_alp_server_manifest`
- or `include_server_manifest` (boolean flag on `get_agent_card`)

would surface this in one call.

This mirrors the GitHub MCP Server's own `server.json` at the repo root.

---

## Considered alternative: use get_file_contents directly

Yes, `get_file_contents` already works. A client can:

1. Fetch file
2. Decode base64
3. Parse JSON manually

However, a dedicated tool is still valuable:

- **Structured output** — returns a typed object, not a blob
- **Schema validation** — catches malformed ALP cards early
- **Discoverability** — `get_agent_card` is self-explanatory
- **Default path resolution** — encodes `agent.alp.json` convention
- **Filename flexibility** — `filename` parameter supports other formats
- **Explicit scope boundary** — tool is repo-scoped by design; API-level
agent definitions (e.g. Anthropic Managed Agents) are outside its scope
- **Future-proofing** — centralizes validation logic

---

## Alignment with the MCP Server Cards specification (SEP-2127)

This proposal is directly relevant to the active MCP specification work on
SEP-2127: MCP Server Cards (modelcontextprotocol/specification#2127),
which defines a standard for pre-connection server discovery via
`.well-known/mcp/server-card.json`.

Several open questions in SEP-2127 map precisely to patterns ALP already
implements in production:

| SEP-2127 open question | ALP v0.9.0 answer |
|---|---|
| Should `tools[]` be included in the Server Card? | ALP `tools[]` with `endpoint`, `input_schema`, `description` — static, opt-in, runtime-agnostic |
| How should dynamic vs. static primitives be handled? | ALP proxy mode: card declares static tool shapes; ALP Server forwards calls to existing HTTP endpoints — zero LLM-side ambiguity |
| What is the relationship between Server Card and Agent Card? | ALP `agent.alp.json` is the Agent Card — identity + persona + tools + memory in one artifact, served at `/agent` |
| How does pre-connection discovery work without `.well-known`? | ALP `server.alp.json` at server root + `AGENT_CARD_URL` env var for remote loading from GitHub raw URLs |
| Who hosts the Server Card if the repo owner doesn't control `.well-known`? | ALP remote card mode (v0.6.0): card lives in the GitHub repo, a hosted ALP Server reads it — no `.well-known` control needed |

The live ALP reference server at https://agent-load-protocol.onrender.com/mcp
already implements all of the above and is loadable today in any
MCP-compatible runtime. This makes `get_agent_card` not just a
GitHub-specific convenience tool, but a concrete early implementation of
the discovery pattern SEP-2127 is standardizing.

SEP-2127 was also linked to this issue by the specification maintainers,
confirming the connection between the two efforts.

---

## References

- ALP repository: https://github.com/RodrigoMvs123/agent-load-protocol
- ALP live MCP endpoint: https://agent-load-protocol.onrender.com/mcp
- ALP JSON schema: https://github.com/RodrigoMvs123/agent-load-protocol/blob/main/schema/agent.alp.schema.json
- ALP SPEC.md: https://github.com/RodrigoMvs123/agent-load-protocol/blob/main/SPEC.md
- ALP pip library (v0.7.0): `pip install alp-server`
- hello-agent-alp-kiro repo: https://github.com/RodrigoMvs123/hello-agent-alp-kiro
- hello-agent live agent card: https://hello-agent-alp-kiro.onrender.com/agent
- hello-agent live MCP endpoint: https://hello-agent-alp-kiro.onrender.com/mcp

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。