> ## Documentation Index
> Fetch the complete documentation index at: https://agentcommunicationprotocol.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Discover & Run Agent

> How to discover and run ACP agents via REST and Python SDK

This guide shows how to discover available ACP agents and execute them using different modes (synchronous, asynchronous, and streaming) through both REST API and Python SDK.

## Discover available agents

Before running agents, you need to know what's available. ACP servers expose agent metadata through a discovery endpoint that lists all registered agents with their capabilities. Use REST for simple interactions or Python SDK for richer, programmatic control.

### Using REST API

Send a GET request to the `/agents` endpoint to list available agents:

<CodeGroup>
  ```bash Request theme={null}
  curl http://localhost:8000/agents
  ```

  ```json Response theme={null}
  {
    "agents": [
      { "name": "echo", "description": "Echoes everything", "metadata": {} }
    ]
  }
  ```
</CodeGroup>

### Using Python SDK

For programmatic access, use the Python client to discover agents:

```python theme={null}
import asyncio
from acp_sdk.client import Client

async def list_agents():
    async with Client(base_url="http://localhost:8000") as client:
        async for agent in client.agents():
            print(agent)

if __name__ == "__main__":
    asyncio.run(list_agents())
```

<Note>For discovering agents across multiple servers, consider using a service registry or the [BeeAI Platform](https://beeai.dev) for centralized agent discovery.</Note>

## Run an agent

ACP supports three execution modes, each suited for different use cases:

* **Synchronous**: Best for quick operations where you need immediate results
* **Asynchronous**: Ideal for long-running tasks that you can check later
* **Streaming**: Perfect for real-time applications requiring incremental updates

### Message Format

All agent interactions use a standardized message format:

```bash theme={null}
{
  "role": "user",
  "parts": [
    {
      "content_type": "text/plain",
      "content": "Your message here"
    }
  ]
}
```

Learn more about [Message Stucture](/core-concepts/message-structure).

### Synchronous execution

Synchronous execution blocks until the agent completes processing and returns the full response.

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST http://localhost:8000/runs \
    -H "Content-Type: application/json" \
    -d '{
          "agent_name": "echo",
          "input": [{"role": "user", "parts": [{"content": "Hello"}]}],
          "mode": "sync"
        }'
  ```

  ```json Response theme={null}
  {
    "agent_name": "echo",
    "status": "completed",
    "output": [
      { 
        "role": "agent/echo",
        "parts": [{ "content_type": "text/plain", "content": "Hello" }] 
      }
    ]
  }
  ```
</CodeGroup>

Using Python SDK:

```python theme={null}
import asyncio
from acp_sdk.client import Client
from acp_sdk.models import Message, MessagePart

async def run_sync():
    async with Client(base_url="http://localhost:8000") as client:
        run = await client.run_sync(
            agent="echo",
            input=[Message(parts=[MessagePart(content="Hello")])]
        )
        print(run.output)

if __name__ == "__main__":
    asyncio.run(run_sync())
```

### Asynchronous execution

Asynchronous execution returns immediately with a run ID that you can use to check status and retrieve (poll) results later.

Start async execution:

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST http://localhost:8000/runs \
    -H "Content-Type: application/json" \
    -d '{
          "agent_name": "echo",
          "input": [{"role": "user", "parts": [{"content": "Hello"}]}],
          "mode": "async"
        }'
  ```

  ```json Response theme={null}
  {
    "agent_name": "echo",
    "status": "created",
    "run_id": "12345678-abcd-1234-abcd-123456789abc"
  }
  ```
</CodeGroup>

Check the status/result using the returned `run_id`:

```bash theme={null}
curl http://localhost:8000/runs/<run_id>
```

Using Python SDK:

```python theme={null}
import asyncio
from acp_sdk.client import Client
from acp_sdk.models import Message, MessagePart

async def run_async():
    async with Client(base_url="http://localhost:8000") as client:
        run = await client.run_async(
            agent="echo",
            input=[Message(parts=[MessagePart(content="Hello")])]
        )
        print("Run ID:", run.run_id)

        # Later, retrieve results
        result = await client.run_status(run_id=run.run_id)
        print(result)

if __name__ == "__main__":
    asyncio.run(run_async())
```

### Streaming execution

Streaming execution provides real-time updates using Server-Sent Events (SSE). Ideal for applications that need to show progress or partial results as they're generated.

```bash theme={null}
curl -N -H "Accept: text/event-stream" -X POST http://localhost:8000/runs \
  -H "Content-Type: application/json" \
  -d '{
        "agent_name": "echo",
        "input": [{"role": "user", "parts": [{"content": "Hello"}]}],
        "mode": "stream"
      }'
```

Using Python SDK:

```python theme={null}
import asyncio
from acp_sdk.client import Client
from acp_sdk.models import Message, MessagePart

async def run_stream():
    async with Client(base_url="http://localhost:8000") as client:
        async for event in client.run_stream(
            agent="echo",
            input=[Message(parts=[MessagePart(content="Hello")])]
        ):
            print(event)

if __name__ == "__main__":
    asyncio.run(run_stream())
```
