# 데이터베이스 붙이기

> **이 장에서 배우는 것**
> 워크스페이스에 데이터베이스를 붙이는 법, 지원하는 네 종류, 그리고 붙이기
> **전에** 반드시 정해야 하는 것 — 도구 설정이 아니라 **계정 권한**입니다.
>
> **테이블·SQL이 처음이라면** [데이터베이스란 무엇인가](/guide/it-database)를 먼저 보세요.

## 무엇이 달라지나

지금까지는 자료를 사람이 뽑아 대화에 붙여넣었습니다. 데이터베이스를 붙이면
에이전트가 **직접 조회**합니다.

```
"지난달 반품 건수를 지역별로 뽑아서 표로 정리해줘"
  → 테이블 목록 확인 → 컬럼 확인 → 조회 → 표
```

[자료를 찾아 붙이기](/guide/ai-grounding)에서 본 그라운딩이 문서가 아니라
**우리 데이터**로 확장되는 것입니다.

## 네 종류를 지원합니다

| 종류 | 연결 문자열 |
|---|---|
| PostgreSQL | `postgres://…` 또는 `postgresql://…` |
| MySQL | `mysql://…` |
| MongoDB | `mongodb://…` · `mongodb+srv://…` |
| SQLite | 파일 경로 — `file:…` 또는 `.sqlite` · `.sqlite3` · `.db` |

**종류를 따로 고르지 않습니다.** 연결 문자열 앞부분(스킴)을 보고 판별합니다.
그래서 스킴이 빠지면 연결이 안 붙습니다 — `user:pass@host/db` 처럼 `postgres://`
없이 적는 것이 첫 실패의 대부분입니다.

## 붙이는 법

[MCP 서버 연결하기](/guide/cn-mcp)의 **"안에서 밖으로"**와 같은 방식입니다.
데이터베이스 MCP 주소를 연결로 추가하고, 연결 문자열을 **헤더**로 넣습니다.

```
X-DB-Connection-String: postgres://reader:••••@db.example.com:5432/shop
```

### 여러 개를 붙일 때

헤더 이름 가운데에 **이름**을 넣습니다.

```
X-DB-Primary-Connection-String:   postgres://reader:••••@db1/app
X-DB-Analytics-Connection-String: mysql://reader:••••@db2/analytics
```

그러면 `primary` · `analytics` 라는 이름으로 구분됩니다. 하나만 붙일 때는 이름이
`default` 입니다.

> **연결 문자열을 대화창에 붙여넣지 마세요.** 비밀번호가 들어 있습니다. 연결
> 설정 화면에만 넣으세요 — [자격증명 관리](/guide/cn-mcp)와 같은 원칙입니다.

## 에이전트가 갖는 도구 열 개

[도구는 권한이다](/guide/mcp-security)의 세 갈래로 나눠 보면 이렇습니다.

| 갈래 | 도구 | 성격 |
|---|---|---|
| 연결 | `db_connect` · `db_disconnect` · `db_list_connections` | 상태 |
| 읽기 | `db_list_tables` · `db_describe_table` · `db_select` | 안 바꿈 |
| **원시 질의** | **`db_query`** | **받은 SQL을 그대로 실행합니다** |
| **되돌릴 수 없음** | `db_insert` · `db_update` · **`db_delete`** | 쓰기·삭제 |

### `db_query` 줄을 다시 보세요

`db_query` 는 조회 전용이 아닙니다. **문자열로 받은 SQL을 그대로 실행합니다.**
즉 `db_insert`·`db_update`·`db_delete` 를 전부 꺼도 `db_query` 하나가 켜져
있으면 쓰기를 막은 것이 아닙니다.

`db_delete` 는 조건(`where`)을 필수로 받아 테이블 전체 삭제를 막아두었지만,
지워진 행이 돌아오지는 않습니다.

## 그래서 계정으로 막습니다

도구를 끄는 것보다 **읽기 전용 계정**이 확실합니다.

```
✗ 앱이 쓰는 계정을 그대로 붙이기
✓ SELECT 권한만 가진 계정을 새로 만들어 붙이기
✓ 운영 DB 대신 복제본이나 분석용 DB를 붙이기
```

**차이는 누가 지키느냐입니다.** 도구 설정은 워크스페이스 안에서 누군가 바꿀 수
있지만, 계정 권한은 데이터베이스가 지킵니다. [최소
권한](/guide/mcp-security)이 여기서는 도구 목록이 아니라 **DB 계정**의 문제입니다.

## 연결은 30분 뒤 정리됩니다

`db_connect` 로 연 연결은 **마지막으로 쓴 지 30분**이 지나면 닫힙니다. 긴 작업
중간에 이런 말이 나오면 그 얘기입니다.

```
Connection not found: … It may have expired or been disconnected.
```

**다시 `db_connect` 하면 됩니다.** 예약처럼 사람이 안 보는 작업이라면, 지시에
"연결이 끊겼으면 다시 연결하라"를 적어두세요.

## 붙이기 전 점검

```
□ 읽기 전용 계정인가
□ 운영 DB인가, 복제본인가
□ db_query 가 켜져 있나
   → 켜져 있다면 쓰기 차단은 도구 설정이 아니라 계정으로만 됩니다
□ insert · update · delete 에 사람 승인이 있나
□ 이 워크스페이스에 외부 입력 경로(위젯 · 채널 · 메일)가 함께 있나
```

**마지막 줄이 가장 중요합니다.** 밖에서 들어온 문장이 그대로 질의가 되는 경로가
생기기 때문입니다 — [읽은 것이 명령이 될 때](/guide/mcp-prompt-injection)에서
본 그 구조입니다. 고객이 보낸 메일 본문이 `db_query` 에 닿을 수 있는 구성이라면
읽기 전용 계정은 **선택이 아니라 조건**입니다.

## 자주 하는 오해

### "SELECT만 시키면 되지 않나요"

지시로 정하는 것과 권한으로 막는 것은 다릅니다. 지시는 [지어내거나
흔들릴 수](/guide/ai-hallucination) 있고, 외부 입력에 밀릴 수도 있습니다.
**막는 것은 계정이 합니다.**

### "테이블이 많은데 다 보이나요"

`db_list_tables` 로 목록을, `db_describe_table` 로 컬럼을 봅니다. 다만 계정에
보이는 것만 보입니다 — 그래서 **계정을 좁히는 것이 곧 범위를 좁히는 것**입니다.

---

## 확인

**1. 쓰기 도구를 모두 꺼도 안심할 수 없는 이유는?**

<details>
<summary>답</summary>

**`db_query` 가 받은 SQL을 그대로 실행하기 때문**입니다. 조회 전용이 아니라서
`db_query` 하나만 켜져 있어도 쓰기가 가능합니다.
</details>

**2. 도구 설정보다 읽기 전용 계정이 확실한 이유는?**

<details>
<summary>답</summary>

**지키는 주체가 다르기 때문**입니다. 도구 설정은 워크스페이스 안에서 바뀔 수
있지만, 계정 권한은 데이터베이스가 강제합니다.
</details>

**3. 외부 입력 경로가 같은 워크스페이스에 있으면 왜 위험합니까?**

<details>
<summary>답</summary>

**밖에서 들어온 문장이 질의로 이어질 수 있기 때문**입니다. 프롬프트 주입과 같은
구조라, 이 구성에서는 읽기 전용 계정이 선택이 아니라 조건입니다.
</details>

---

붙인 도구를 직접 눌러봅니다 → [플레이그라운드](/guide/cn-playground)
