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

# list_notes

> 필터와 선택적 keyword로 노트 목록 조회 — 가벼운 메타데이터만

## 개요

`list_notes`는 노트 디스커버리의 가벼운 단계예요. 제목, 참가자, 날짜, 소스 유형 등 메타데이터만 반환하며, 내용을 읽지 않고 **어떤 노트가 있는지 알아야 할 때** 알맞은 도구예요.

`query.keyword`가 제공되면 결과 집합은 `recordingStartAt` 내림차순 대신 전문 검색(full-text) 관련도(동점 시 `createdAt` 내림차순)로 재정렬돼요.

**주요 사용 사례:**

* "폴더 X에 어떤 노트가 있지?"
* "어떤 노트가 keyword Y에 매칭되지?"(존재 여부만 확인)
* 날짜 범위로 필터링해 큰 워크스페이스 좁히기.

**핵심 기능:**

* [`search_notes`](./search-notes)(심층, 문서 반환), [`get_note_transcript`](./get-transcript)(원본 transcript)와 함께 3단계 모델을 이뤄요.
* 목록 경로에서 cursor 기반 페이지네이션.
* 미완성 노트는 자동으로 제외해요. 녹음이 시작된 적 없고 제목이 기본 placeholder인 노트는 MCP 레이어에서 필터링돼요.

<Tip>
  **토큰 효율.** `list_notes` 페이지는 노트당 약 50 토큰을 반환해요. `search_notes`로 문서를 불러오거나(노트당 \~1,500 토큰) `get_note_transcript`로 transcript를 불러오는 것(노트당 \~3,000–5,000 토큰)과 비교하면, 가진 것을 찾는 가장 저렴한 방법이에요.
</Tip>

## 파라미터

| Parameter              | Type   | Required | Description                                                                                                                     |
| ---------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `query.keyword`        | string | Optional | 선택적 keyword. 있으면 전문 검색 관련도로 재정렬해요.                                                                                              |
| `workspaceGuid`        | string | Optional | 특정 workspace를 대상으로 지정(`list_workspaces`에서 GUID 확인). 생략하면 접근 가능한 모든 workspace를 검색해요. workspace 범위 key는 자동으로 자신의 workspace를 검색해요. |
| `pagination.cursor`    | string | Optional | 이전 `nextCursor`에서 받은 cursor.                                                                                                    |
| `pagination.size`      | number | Optional | 페이지당 결과 수(기본값 `20`, 최대 `100`).                                                                                                  |
| `filter.folderId`      | string | Optional | 폴더로 제한(재귀적 — 하위 폴더 포함).                                                                                                         |
| `filter.createdAtFrom` | string | Optional | ISO 8601 datetime, `createdAt`의 포함 하한.                                                                                          |
| `filter.createdAtTo`   | string | Optional | ISO 8601 datetime, `createdAt`의 배제 상한.                                                                                          |

### query.keyword (선택)

목록을 관련도 모드로 전환해요. 매칭은 서버의 전문 검색 인덱스가 노트 제목과 단락 내용을 기준으로 점수를 매겨요. keyword가 있으면 `nextCursor`는 `null`이에요(심층 검색 인덱스에는 안정적인 목록 cursor가 없어요).

keyword 검색은 user 범위와 workspace 범위 API key 모두에서 동작해요. `workspaceGuid`를 생략하면 접근 가능한 모든 workspace를 검색하고(workspace 범위 key는 자동으로 자신의 workspace를 검색해요), 특정 workspace를 대상으로 하려면 명시적인 `workspaceGuid`를 전달하세요.

### workspaceGuid (선택)

특정 workspace를 대상으로 지정해요. 사용 가능한 GUID는 `list_workspaces`에서 확인하세요. 생략하면 접근 가능한 모든 workspace를 검색해요 — workspace 범위 key는 자동으로 자신의 workspace를 검색해요.

### filter.folderId (선택)

제공되면 목록은 해당 폴더와 모든 하위 폴더로 재귀적으로 범위가 좁혀져요. 폴더 접근은 서버 측에서 인가돼요. 접근 권한이 없는 folderId를 전달하면 `404`를 반환해요.

### filter.createdAtFrom / filter.createdAtTo (선택)

`createdAt`에 대한 반열린 `[from, to)` 범위 필터예요. 둘 다 시간대가 포함된 ISO 8601 datetime을 받아요(예: `2026-04-01T00:00:00Z`).

### pagination (선택)

`{ cursor, size }`. 기본값 `size: 20`, 최대 `100`. 이전 응답의 `nextCursor`를 사용해 페이지를 넘기세요.

## 응답 형식

### 성공 응답

```json theme={"system"}
{
  "content": [
    {
      "noteGuid": "abc-123-def",
      "title": "OKR Q2 Planning",
      "webUrl": "https://platform.tiro.ooo/notes/abc-123-def",
      "createdAt": "2026-04-15T10:00:00Z",
      "updatedAt": "2026-04-15T11:30:00Z",
      "recordingDurationSeconds": 3625,
      "sourceType": "live-voice",
      "participants": [
        { "name": "Alice Kim", "email": "alice@example.com" },
        { "name": "Bob Park", "email": null }
      ]
    }
  ],
  "notes": [],
  "total": 137,
  "totalSize": 1,
  "nextCursor": "eyJvZmZzZXQiOjUwfQ=="
}
```

<Note>
  응답은 각 노트를 `content`(권장)와 `notes`(레거시 별칭) 양쪽에 담아요. 클라이언트가 선호하는 쪽을 고르고 다른 쪽은 무시하세요.
</Note>

**필드 설명:**

| Field                                | Type           | Description                                                                               |
| ------------------------------------ | -------------- | ----------------------------------------------------------------------------------------- |
| `content[]`                          | array          | 노트(선호 필드).                                                                                |
| `content[].noteGuid`                 | string         | 고유 노트 식별자 — `search_notes`, `get_note_transcript` 등에 전달해요.                                |
| `content[].title`                    | string         | 노트 제목.                                                                                    |
| `content[].webUrl`                   | string         | Tiro 웹 앱에서 노트로 바로 가는 링크.                                                                  |
| `content[].createdAt`                | string         | ISO 8601 생성 타임스탬프.                                                                        |
| `content[].updatedAt`                | string         | ISO 8601 마지막 수정 타임스탬프.                                                                    |
| `content[].recordingDurationSeconds` | number         | 녹음 길이(초)(녹음이 아닌 소스는 `0`).                                                                 |
| `content[].sourceType`               | string         | `live-voice`, `recording`, `text`, `video`, `webpage`, `offline-mode`, `onboarding` 중 하나. |
| `content[].participants[]`           | array          | 참가자별 `{ name, email }`. 둘 중 어느 쪽이든 `null`일 수 있어요.                                         |
| `total`                              | number         | 백엔드의 필터 전 개수.                                                                             |
| `totalSize`                          | number         | MCP 측 미완성 노트 필터 적용 후 개수(`total`보다 작을 수 있어요).                                              |
| `nextCursor`                         | string \| null | 다음 페이지를 위한 cursor. 더 이상 결과가 없거나 keyword 검색이 활성화되면 `null`.                                 |

<Warning>
  **페이지네이션 팁.** `total`과 `totalSize`는 다를 수 있어요. `total`이 센 미완성 노트가 `totalSize` 전에 필터링돼요. `while (totalSize < total)`로 반복하지 말고 `nextCursor`로 페이지를 넘기세요.
</Warning>

## 사용 예시

### 예시 1: 특정 폴더의 노트

**요청:**

```json theme={"system"}
{
  "filter": {
    "folderId": "455765"
  }
}
```

폴더 `455765`와 그 하위 폴더에서 가장 최근의 완성 노트 20개를 반환해요.

### 예시 2: 날짜 범위로 최근 노트

**요청:**

```json theme={"system"}
{
  "filter": {
    "createdAtFrom": "2026-04-01T00:00:00Z",
    "createdAtTo": "2026-05-01T00:00:00Z"
  },
  "pagination": {
    "size": 50
  }
}
```

### 예시 3: keyword 목록 (관련도 순위)

**요청:**

```json theme={"system"}
{
  "query": {
    "keyword": "OKR"
  },
  "pagination": {
    "size": 30
  }
}
```

제목이나 단락이 `OKR`에 매칭되는 노트를 관련도 순으로 반환해요. 응답의 `nextCursor`는 `null`이에요. 더 필요하면 같은 keyword와 더 큰 `size`로 다시 호출하세요.

### 예시 4: 페이지네이션 탐색

**첫 페이지:**

```json theme={"system"}
{
  "pagination": { "size": 50 }
}
```

**다음 페이지 (이전 응답의 `nextCursor` 사용):**

```json theme={"system"}
{
  "pagination": {
    "size": 50,
    "cursor": "eyJvZmZzZXQiOjUwfQ=="
  }
}
```

## 어떤 단계를 언제 쓸지

<AccordionGroup>
  <Accordion title="list_notes를 쓸 때…">
    폴더, 날짜, keyword 존재 여부로 **어떤 노트가 있는지 알아야** 할 때예요. 메타데이터만 반환하고 노트당 약 50 토큰이에요. 가장 저렴한 디스커버리 도구예요.
  </Accordion>

  <Accordion title="search_notes를 쓸 때…">
    주제 이면의 결정, action item, 팀의 결론 등 **맥락을 이해해야** 할 때예요. 매칭된 노트와 그 주요 문서(one-pager, custom)를 반환해요. 노트당 약 1,500 토큰이에요.

    LLM이 사용자 질문에 답하기 위해 문서 내용이 필요할 때 `list_notes`에서 [`search_notes`](./search-notes)로 전환하세요.
  </Accordion>

  <Accordion title="get_note_transcript를 쓸 때…">
    대화에서 **정확한 발화를 인용해야** 할 때예요. 타임스탬프가 있는 전체 transcript를 반환해요. 회의 시간당 \~3,000–5,000 토큰으로, 최후의 수단이에요.

    [`get_note_transcript`](./get-transcript)를 참고하세요.
  </Accordion>
</AccordionGroup>

## 자주 발생하는 오류

### 유효하지 않은 datetime

<Error>
  ```json theme={"system"}
  {
    "error": "Invalid createdAtFrom format. Expected ISO 8601 datetime.",
    "code": "INVALID_DATE_FORMAT",
    "statusCode": 400
  }
  ```
</Error>

**해결 방법:** 시간대가 포함된 ISO 8601 datetime을 사용하세요(예: `2026-04-01T00:00:00Z`).

## 토큰 사용량

| Mode                                  | Tokens per note      |
| ------------------------------------- | -------------------- |
| `list_notes` (메타데이터만)                 | \~50                 |
| `search_notes` (문서 포함)                | \~1,500              |
| `get_note_transcript` (전체 transcript) | 회의 시간당 \~3,000–5,000 |

<Tip>
  **디스커버리 흐름.** `list_notes`로 관심 있는 noteGuid를 먼저 찾으세요. 문서 내용이 필요할 때만 `search_notes`로 전환하세요. 그대로 인용해야 할 때만 `get_note_transcript`를 사용하세요.
</Tip>
