# Add a website as knowledge

Teaches the agent from a public web page or RSS/Atom feed.

|  |  |
| --- | --- |
| REST | `POST /api/v1/agents/{agent_id}/knowledge/sources` |
| MCP tool | `import_knowledge_from_url` |
| Classification | **Write** |
| Scope | `agents:write` |
| Minimum role on the agent | editor |
| Confirmation | Not needed |
| Retry safety | Send an `Idempotency-Key` header (REST) or `idempotency_key` argument (MCP) to retry safely |
| Success status | 201 |

## What it does

Teaches the agent from a public web page or RSS/Atom feed. Fetching and indexing happen in the background; check list_knowledge_sources. refresh_hours re-imports on a schedule.

## Side effects

Adds a knowledge source. Covo fetches the page in the background (and again every refresh_hours, if set); the agent starts answering from it once processed.

## Inputs

| Name | Type | Required | In | Description |
| --- | --- | --- | --- | --- |
| `agent_id` | string | yes | path | The agent id (agt_...), from list_agents. |
| `url` | string | yes | body |  |
| `refresh_hours` | integer or null | no | body | Default null. |

## Example

REST:

```bash
curl -X POST "https://covo.lanaai.io/api/v1/agents/agt_4edc89bb2964/knowledge/sources" \
  -H "Authorization: Bearer $COVO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"url":"https://example.com/about"}'
```

MCP (POST /mcp):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "import_knowledge_from_url",
    "arguments": {
      "agent_id": "agt_4edc89bb2964",
      "url": "https://example.com/about"
    }
  }
}
```

## Response

Returns an object with `source` and `note`. This is a real response, shortened to two items per list.

201 response:

```json
{
  "source": {
    "id": "53fbb5d6-b760-4ece-bbba-c0852a747a09",
    "tenant_id": "0c368d2d-cd7d-4f6b-9026-b73854e431f8",
    "kind": "website",
    "title": "example.com",
    "filename": null,
    "mime_type": null,
    "size_bytes": null,
    "storage_key": null,
    "source_url": "https://example.com/about",
    "status": "pending",
    "error": null,
    "created_at": "2026-10-07T20:14:41.868Z",
    "updated_at": "2026-10-07T20:14:41.868Z",
    "refresh_hours": null,
    "last_fetched_at": null,
    "content_hash": null,
    "knowledge_base_id": null
  },
  "note": "The page is fetched and indexed in the background; list_knowledge_sources shows its status."
}
```

Over MCP the same object comes back as the tool result, in `structuredContent` and as JSON text.

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | `unauthorized` | No token, or it is unknown, revoked or expired. OAuth apps refresh or reconnect. |
| 403 | `account_suspended` | The account that owns the token is paused. |
| 403 | `insufficient_scope` | The token lacks `agents:write`. |
| 404 | `agent_not_found` | Unknown agent, or not reachable with this token. |
| 400 | `bad_request` | An input is invalid; `field` names it. |
| 409, 422 | `idempotency_in_progress`, `idempotency_key_reused` | See Idempotency on the REST page. |
| 403 | `plan_limit` | The plan is full; `details` has the limit. |
| 429 | `rate_limited` | Wait `Retry-After` seconds. |
