본문으로 건너뛰기
effidevFlutter · Cloudflare 엣지 · 클라우드 비용 최적화
한국어

MCP 2026-07-28 스펙: 세션이 사라졌다 — 스테이트리스 전환 마이그레이션 가이드

MCP 2026-07-28 스펙 스테이트리스 전환 마이그레이션 가이드

2026년 7월 28일, Model Context Protocol 스펙의 새 리비전이 릴리스되어 현행(Current) 프로토콜 버전이 됐다. 직전 리비전인 2025-11-25에서 8개월 만이다. MCP 공동 창안자 David Soria Parra는 공식 발표에서 이번 릴리스를 “remote MCP가 나온 지 1년이 넘은 이래 MCP에서 가장 중요한” 것이라고 표현했다.

한 줄로 요약하면 이렇다. MCP가 스테이트리스가 됐다. initialize 핸드셰이크가 사라졌고, Mcp-Session-Id 헤더가 사라졌다. 지금 MCP 서버나 클라이언트를 운영하고 있다면 이건 “언젠가 보면 되는” 릴리스 노트가 아니라 코드를 고쳐야 하는 브레이킹 체인지다.

파장은 이미 나타나고 있다. 8월 6일 Cloudflare는 Workers에서 MCP 서버를 만들 때 쓰던 McpAgentdeprecated·feature-frozen 으로 돌리고 스테이트리스 핸들러로 갈아탈 것을 안내했다. 세션이 없어지면 세션을 붙들어 두기 위한 Durable Object도 필요 없어지기 때문이다. 이 이야기는 12절에서 따로 다룬다.

이 글은 스펙 변경 목록을 그대로 옮기는 대신, 실제로 어느 코드를 고쳐야 하는지를 중심으로 정리한다. 각 항목에 SEP 번호를 달아 두었으니 근거가 필요하면 해당 PR을 바로 열어 보면 된다.

1. 세션이 사라졌다 (SEP-2567)

가장 큰 변화다. Streamable HTTP 트랜스포트에서 프로토콜 레벨 세션과 Mcp-Session-Id 헤더가 제거됐다.

그 결과로 따라오는 조건이 하나 더 있다. tools/list, resources/list, prompts/list더 이상 커넥션마다 다른 값을 돌려줄 수 없다. 예전에는 “이 세션은 인증된 사용자니까 관리자 도구까지 보여 준다” 같은 구현이 가능했지만, 이제 목록 응답은 커넥션에 종속되지 않는다.

그럼 호출 간에 상태를 유지해야 하는 서버는 어떻게 하나. 스펙이 제시하는 답은 명확하다 — 서버가 발급한 명시적 핸들을 평범한 도구 인자로 주고받으라는 것이다.

// Before — 세션 헤더에 기대던 구조
app.post('/mcp', async (c) => {
  const sessionId = c.req.header('Mcp-Session-Id');
  const state = await sessions.get(sessionId);   // 이제 이 헤더는 오지 않는다
  // ...
});

// After — 상태는 서버가 발급한 핸들로, 도구 인자에 실어 명시적으로 전달
server.tool('open_workspace', {}, async () => ({
  resultType: 'complete',
  content: [{ type: 'text', text: '워크스페이스를 열었습니다' }],
  structuredContent: { workspaceHandle: 'ws_01J8ZQ...' },   // 서버가 발급
}));

server.tool('write_file', {
  workspaceHandle: z.string(),   // 클라이언트가 다음 호출에 그대로 실어 보낸다
  path: z.string(),
  body: z.string(),
}, async ({ workspaceHandle, path, body }) => { /* ... */ });

암묵적인 커넥션 상태가 명시적인 데이터로 바뀐 것이다. 로드밸런서 뒤에 인스턴스를 여러 대 두거나 서버리스로 굴릴 때 훨씬 다루기 쉬워진다. 어느 인스턴스가 요청을 받든 상관없어지기 때문이다.

2. initialize 핸드셰이크가 사라졌다 (SEP-2575)

initializenotifications/initialized가 통째로 제거됐다. 대신 모든 요청이 자기 자신에게 필요한 정보를 _meta에 싣고 다닌다.

_meta 방향 필수 내용
io.modelcontextprotocol/protocolVersion 클라이언트 → 서버 프로토콜 버전 ("2026-07-28")
io.modelcontextprotocol/clientCapabilities 클라이언트 → 서버 이 요청에 관련된 클라이언트 능력
io.modelcontextprotocol/clientInfo 클라이언트 → 서버 아니오 (SHOULD) 클라이언트 이름·버전
io.modelcontextprotocol/logLevel 클라이언트 → 서버 아니오 이 요청에 대한 최소 로그 레벨
io.modelcontextprotocol/serverInfo 서버 → 클라이언트 (결과의 _meta) 아니오 (SHOULD) 서버 이름·버전
// 모든 요청이 이런 모양이 된다
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_file",
    "arguments": { "path": "a.txt", "body": "hi" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": { },
      "io.modelcontextprotocol/clientInfo": { "name": "my-client", "version": "1.0.0" }
    }
  }
}

필수 필드가 빠진 요청은 malformed다. 서버는 반드시(MUST) JSON-RPC -32602(Invalid params)로 거부해야 하고, HTTP라면 응답 상태는 400 Bad Request여야 한다. 버전이 맞지 않으면 UnsupportedProtocolVersionError(-32022)를 돌려준다.

능력 선언에도 규칙이 하나 붙었다. 서버는 클라이언트가 선언하지 않은 능력에 기대면 안 된다 (MUST NOT). 요청을 처리하는 데 선언되지 않은 능력이 필요하면 MissingRequiredClientCapabilityError(-32021)를 반환해야 하며, data.requiredCapabilities에 빠진 능력을 나열해야 한다.

스펙은 스테이트리스의 의미를 아주 못 박아 뒀다. 서버는 같은 커넥션의 이전 요청에 기대어 문맥을 세우면 안 된다(MUST NOT). 심지어 stdio 프로세스조차 대화나 세션이 아니라고 명시한다 — 클라이언트는 같은 트랜스포트에 서로 무관한 요청을 섞어 보낼 수 있고, 서버는 커넥션이나 프로세스 동일성을 세션 연속성의 대용으로 취급해서는 안 된다.

핸드셰이크 왕복 한 번이 통째로 없어졌으니 콜드 스타트가 잦은 환경 — 엣지 런타임이나 서버리스 — 에서는 체감되는 이득이 있다. 반대로 “초기화 때 한 번 받아 두고 계속 쓰던” 정보에 의존하던 코드는 전부 손봐야 한다.

3. server/discover: 이제 필수 구현이다 (SEP-2575)

핸드셰이크가 사라진 자리를 메우는 RPC다. 서버는 server/discover를 반드시(MUST) 구현해야 한다. 지원 프로토콜 버전, 능력, 신원을 알리는 용도다.

클라이언트 입장에서는 두 가지로 쓸 수 있다.

DiscoverResult의 모양은 이렇다. 필드 이름을 조심하자 — 지원 버전 목록은 supportedVersions 이고, 서버 신원은 결과 최상위가 아니라 _meta 안에 들어간다.

{
  "resultType": "complete",
  "supportedVersions": ["2026-07-28", "2025-11-25"],
  "capabilities": { "tools": {}, "resources": {} },
  "_meta": {
    "io.modelcontextprotocol/serverInfo": { "name": "my-mcp-server", "version": "2.0.0" }
  }
}

버전이 맞지 않을 때 서버가 돌려주는 에러도 정해져 있다. 지원 목록을 함께 실어 줘야 클라이언트가 다시 고를 수 있다.

{
  "jsonrpc": "2.0", "id": 1,
  "error": {
    "code": -32022,
    "message": "Unsupported protocol version",
    "data": { "supported": ["2026-07-28", "2025-11-25"], "requested": "1900-01-01" }
  }
}

서버를 만들고 있다면 이번 마이그레이션에서 가장 먼저 추가해야 할 코드가 이것이다. 없으면 스펙 위반이다.

구·신형 클라이언트를 같이 받으려면

스펙은 구현체를 세 부류로 나눠 부른다.

용어
Modern 버전·신원·능력을 요청마다 _meta로 실어 보내는 버전 (2026-07-28 이상)
Legacy initialize 핸드셰이크로 세션을 세우는 버전 (2025-11-25 이하)
Dual-era 둘 다 지원하는 구현

Dual-era 서버는 클라이언트가 어떻게 말을 거는지로 판단한다. 요청이 모던 _meta를 달고 오면 스테이트리스로 처리하고, initialize가 오면 레거시 방식으로 처리한다. 한 엔드포인트에서 둘을 동시에 서비스해도 된다(MAY).

클라이언트 쪽 탐지는 트랜스포트마다 다르다.

판정 결과는 개별 요청이 아니라 서버의 속성이다. stdio는 프로세스 수명 동안, HTTP는 오리진 단위로 캐시해 두는 게 맞다(SHOULD).

주의할 조합이 있다. 레거시 클라이언트 → 모던 서버는 실패한다. 레거시 클라이언트에는 상위 버전으로 올라갈 수단이 없기 때문이다. 그래서 모던 전용 서버라면 initialize 요청에 대한 에러 메시지에 지원 버전을 적어 두는 게 좋다(SHOULD) — 레거시 클라이언트 사용자가 볼 수 있는 유일한 단서가 그 메시지일 수 있다.

4. 구독 방식이 바뀌었다 (SEP-2575)

HTTP GET 엔드포인트와 resources/subscribe·resources/unsubscribe가 사라지고, subscriptions/listen 하나로 통합됐다. 단일 long-lived POST 응답 스트림이다.

클라이언트가 받고 싶은 알림 종류를 명시적으로 옵트인한다.

서버는 이를 확인해 주고, 보내는 알림에 io.modelcontextprotocol/subscriptionId 태그를 붙인다.

여기서 헷갈리기 쉬운 지점이 하나 있다. notifications/progressnotifications/message처럼 요청에 딸린 알림은 subscriptions/listen 스트림으로 가지 않는다. 그 알림들은 원래 요청의 응답 스트림으로 계속 흐른다. 진행률 표시가 갑자기 안 나온다면 여기를 의심하면 된다.

5. MRTR — 서버가 클라이언트에게 되묻는 방식 (SEP-2322)

기존에는 서버가 클라이언트에게 요청을 거는 방향이 따로 있었다. roots/list, sampling/createMessage, elicitation/create 같은 것들이다. 스펙의 표현을 그대로 옮기면, 서버는 이제 이런 요청을 반드시 MRTR 패턴으로 보내야 하고(MUST), 기존의 서버 주도 요청 패턴은 더 이상 지원되지 않는다. 브레이킹 체인지다.

새 흐름은 이렇다.

  1. 클라이언트가 요청을 보낸다 (id: 1)
  2. 서버가 정보가 더 필요하면 resultType: "input_required"InputRequiredResult를 돌려준다
  3. 클라이언트가 사용자에게 물어본 뒤, 원래 요청을 새 id로 다시 보내면서 답을 실어 준다

여기서 가장 많이 틀리는 지점이 있다. inputRequestsinputResponses는 배열이 아니라 맵이다. 키는 서버가 붙인 식별자고, 값은 ElicitRequest·CreateMessageRequest·ListRootsRequest 중 하나인 완전한 요청 객체(method + params)다.

// 2단계 — 서버 응답
{
  "jsonrpc": "2.0", "id": 1,
  "result": {
    "resultType": "input_required",
    "inputRequests": {
      "github_login": {
        "method": "elicitation/create",
        "params": {
          "mode": "form",
          "message": "GitHub 사용자명을 입력해 주세요",
          "requestedSchema": {
            "type": "object",
            "properties": { "name": { "type": "string" } },
            "required": ["name"]
          }
        }
      }
    },
    "requestState": "AEAD-protected blob"
  }
}

응답도 같은 키를 쓰는 맵이고, 값은 각 요청의 결과 객체다.

// 3단계 — 새 id로 재시도하며 답과 requestState를 그대로 실어 보낸다
{
  "jsonrpc": "2.0", "id": 2,
  "method": "tools/call",
  "params": {
    "name": "delete_file",
    "arguments": { "path": "a.txt" },
    "inputResponses": {
      "github_login": { "action": "accept", "content": { "name": "octocat" } }
    },
    "requestState": "AEAD-protected blob"
  }
}

requestState — 이게 MRTR을 스테이트리스로 만드는 장치다

requestState서버에게만 의미가 있는 불투명 문자열이다. 서버가 필요한 문맥을 여기에 인코딩해 내려보내면, 클라이언트가 그대로 되돌려 준다. 서버가 상태 저장소를 두지 않아도 되는 이유가 바로 이것이다.

규칙이 꽤 엄격하다.

보안 요구사항이 특히 중요하다. 이 값은 클라이언트를 거쳐 오므로 공격자가 조작할 수 있는 입력이다(MUST 로 그렇게 취급하라고 명시한다). 인가·리소스 접근·비즈니스 로직에 영향을 준다면 서버는 무결성을 반드시 보호해야 하고(HMAC이나 AEAD 등), 검증에 실패한 상태는 거부해야 한다. 변조돼 봐야 요청이 실패하는 것 외에 아무 일도 일어나지 않는 경우에만 생략할 수 있다.

리플레이 방지를 위해 무결성 보호된 페이로드 안에 다음을 넣고 수신할 때마다 검증하는 게 권장된다(SHOULD).

다만 이 조치들은 리플레이 창을 좁힐 뿐 단일 사용을 보장하지는 않는다. 일회성 사용이 꼭 필요하다면 서버 쪽에서 별도로 강제해야 한다(MUST).

MRTR을 쓸 수 있는 요청은 셋뿐이다

클라이언트 요청 InputRequiredResult 가능
prompts/get 가능
resources/read 가능
tools/call 가능

그 외 요청에는 보내면 안 된다(MUST NOT). 또한 클라이언트가 능력으로 선언하지 않은 종류의 요청을 inputRequests에 담아서도 안 된다 — 클라이언트가 elicitation을 선언하지 않았다면 elicitation/create를 넣을 수 없다.

양방향 요청이 단방향 재시도로 바뀌었다. 트랜스포트 입장에서는 훨씬 단순해졌지만, 클라이언트는 재시도 루프를 직접 구현해야 한다. 기존에 서버 주도 요청을 처리하던 콜백은 전부 이 구조로 옮겨야 한다.

6. resultType이 모든 결과에 필수가 됐다 (SEP-2322)

모든 결과에 resultType 필드가 필수로 붙는다.

하위 호환에 관한 규칙이 명시돼 있다. 이전 프로토콜 서버가 이 필드를 빠뜨린 경우, 클라이언트는 반드시(MUST) "complete"로 취급해야 한다. 클라이언트를 만든다면 이 분기를 꼭 넣어 두자.

7. 없어진 것들

ping
logging/setLevel
notifications/roots/list_changed
tasks/result          (→ tasks/get 폴링으로 대체)
tasks/list
notifications/elicitation/complete

로그 레벨은 이제 요청마다 _metaio.modelcontextprotocol/logLevel로 지정한다. 그리고 서버는 이 필드가 없는 요청에 대해 notifications/message를 보내면 안 된다 (MUST NOT). 무조건 로그를 흘려보내던 서버라면 조건을 추가해야 한다.

SSE 스트림 재개도 사라졌다. Last-Event-ID 헤더와 SSE 이벤트 ID가 Streamable HTTP에서 제거되면서, 응답 스트림이 끊기면 진행 중이던 요청은 그대로 유실된다. 클라이언트는 새 요청 ID로 다시 보내야 한다(MUST). 재연결하면 이어받던 동작을 기대하고 짠 코드가 있다면 여기서 조용히 깨진다.

8. Tasks가 코어에서 확장으로 빠졌다 (SEP-2663)

실험적 기능이던 tasks가 코어 프로토콜에서 빠져 공식 확장 io.modelcontextprotocol/tasks로 옮겨 갔다. 단순한 이사가 아니라 설계가 다시 짜였다.

변경 내용
tasks/result 제거 블로킹 방식이었다. tasks/get 폴링으로 대체
tasks/update 신설 클라이언트 → 서버 입력 전달용
tasks/list 제거
핸들 반환 서버가 요청별 옵트인 없이 태스크 핸들을 자발적으로 돌려줄 수 있다

확장은 능력(capabilities)의 extensions 맵으로 알린다. 식별자는 _meta 키 명명 규칙을 따르며 접두사가 필수다.

{
  "capabilities": {
    "tools": {},
    "extensions": { "io.modelcontextprotocol/tasks": {} }
  }
}

한쪽만 확장을 지원하는 경우의 규칙도 정해져 있다. 지원하는 쪽이 코어 동작으로 되돌아가거나 적절한 에러로 거부해야 한다(MUST).

9. Deprecated — Roots, Sampling, Logging (SEP-2577)

세 기능이 폐기 예정으로 지정됐다. 폐기 기간 동안에는 완전히 동작하지만, 새로 만드는 구현은 쓰지 말라는 뜻이다. 스펙이 권하는 대체 방법은 이렇다.

폐기 대상 대체
Roots 디렉터리·파일을 도구 파라미터, 리소스 URI, 서버 설정으로 전달
Sampling LLM 제공사 API와 직접 연동
Logging stdio는 stderr로, 그 외에는 OpenTelemetry

함께 폐기 재분류된 것도 있다.

여기서 중요한 건 이번에 함께 도입된 기능 수명주기 정책이다. Active / Deprecated / Removed 세 상태를 정의하고, 폐기된 기능은 제거 대상이 되기 전까지 최소 12개월 스펙에 남는다. 다만 무조건은 아니다 — 정책의 신속 제거(expedited-removal) 예외가 적용되면 최소 90일로 줄어든다. 활성 보안 위험이 있는 경우가 그렇다. 즉 위 기능들이 당장 다음 리비전에 사라지지는 않지만, “1년은 무조건 안전하다”고 읽으면 안 된다.

10. 캐싱과 라우팅 — 조용하지만 실무에 크게 걸리는 것들

메이저 변경 목록에는 없지만 실제 구현에는 바로 영향을 주는 항목들이다.

리스트 결과가 캐시 가능해졌다 (SEP-2549). tools/list, prompts/list, resources/list, resources/read, resources/templates/list의 결과에 ttlMscacheScope필수로 붙는다. ttlMs는 신선도 힌트(밀리초)고, cacheScope"public" / "private"으로 중간 캐시가 공유해도 되는지를 정한다. 폴링을 줄이는 용도다.

요청 헤더가 필수가 됐다 (SEP-2243). Streamable HTTP POST에 Mcp-MethodMcp-Name을 반드시 실어야 한다. 본문을 파싱하지 않고도 라우팅할 수 있게 하려는 것이다. 리버스 프록시나 WAF 앞단에서 MCP 트래픽을 구분해야 했다면 이제 헤더만 보면 된다.

tools/list는 결정적 순서로 반환해야 한다(SHOULD). 클라이언트 캐싱과 LLM 프롬프트 캐시 적중률 때문이다. 도구 목록을 맵에서 뽑아 그때그때 다른 순서로 내보내고 있었다면 정렬을 넣자. 프롬프트 캐시가 매번 깨지고 있었을 것이다.

OpenTelemetry 추적 컨텍스트가 규약화됐다 (SEP-414). _metatraceparent, tracestate, baggage를 실어 전파한다.

11. 에러 코드가 재번호됐다

에러 코드 할당 정책이 생겼다. JSON-RPC 서버 에러 범위를 이렇게 나눈다.

이에 맞춰 번호가 바뀐 것들이 있다.

에러 이전 이후
HeaderMismatch -32001 -32020
MissingRequiredClientCapability -32003 -32021
UnsupportedProtocolVersion -32004 -32022
리소스 없음 -32002 -32602 (Invalid Params)

여기서 오해하기 쉬운 지점이 있다. 위 세 개는 이번 리비전의 드래프트 단계에서 처음 생긴 코드라, 정식 릴리스된 이전 버전을 구현한 코드에는 애초에 존재하지 않는다. 실제로 기존 코드에 박혀 있을 수 있는 건 마지막 행 하나뿐이다.

리소스 없음이 -32002에서 -32602(Invalid Params)로 바뀐 것은 JSON-RPC 스펙에 맞추기 위한 변경이다. 이번 버전을 구현한 쪽은 -32002내보내면 안 되지만(MUST NOT), 클라이언트는 구 버전 서버가 보내는 -32002여전히 받아들이는 게 좋다(SHOULD).

12. Cloudflare Workers를 쓰고 있다면 — McpAgent가 폐기됐다

이번 스펙 변경이 실제 구현에 어떤 파장을 일으키는지 가장 잘 보여 주는 사례가 Cloudflare다. 2026년 8월 6일, Cloudflare는 “The next generation of MCP”를 발표하면서 McpAgent를 걷어냈다.

왜 이게 자연스러운 귀결인지는 앞의 1·2절을 읽었다면 짐작될 것이다. 지금까지 Workers에서 MCP 서버를 굴리려면 Durable Objects가 사실상 필수였다. Mcp-Session-Id로 식별되는 세션과 그 세션에 묶인 SSE 스트림을 유지해야 했으니, 요청을 같은 인스턴스로 고정해 줄 무언가가 필요했던 것이다. 세션이 사라지면서 그 전제 자체가 없어졌다.

Cloudflare의 표현은 이렇다.

This release of the MCP 2026-07-28 specification … removes the need for McpAgent. While Durable Objects remain the right primitive when an application itself needs state, MCP itself no longer requires a Durable Object to speak the protocol.

문서상 McpAgent의 현재 상태는 “deprecated and feature-frozen” 이다. 지금 당장 못 쓰게 된 건 아니지만 새 기능은 더 붙지 않는다. 대체재는 createMcpHandler로, 공식 설명은 “MCP SDK v2 서버 팩토리로부터 호출 가능한 스테이트리스 MCP 요청 핸들러를 만든다”이다.

export default {
  fetch(request, env, ctx) {
    return createMcpHandler(createServer)(request, env, ctx);
  },
} satisfies ExportedHandler;

Durable Object 클래스도, 세션 라우팅도 없다. 요청마다 서버를 새로 만들어 처리하고 끝난다.

여기서 오해하기 쉬운 지점이 하나 있다. Durable Objects가 필요 없어진 게 아니다. 없어진 건 “MCP 프로토콜을 말하기 위한” DO다. 앱 자체에 상태가 필요하다면 DO는 여전히 맞는 도구다. 공식 문서의 안내가 정확히 그 구분을 짚는다.

Store cross-request data behind an authenticated handle in a Durable Object, D1, KV, or R2 rather than an MCP session ID.

1절에서 본 “서버가 발급한 명시적 핸들”이 바로 이 이야기다. 상태를 두는 곳은 그대로 DO·D1·KV·R2 이고, 그 상태를 가리키는 열쇠를 MCP 세션 ID가 아니라 인증된 핸들로 바꾸라는 것이다.

마이그레이션 부담도 한 번에 몰리지 않는다. Cloudflare는 /mcp 엔드포인트가 “새 프로토콜과 2025년 Streamable HTTP 클라이언트의 스테이트리스 요청을 모두 받는다”고 밝혔다. 구형 클라이언트를 쓰는 사용자가 남아 있어도 서버를 먼저 옮길 수 있다.

비용에 대해서는 조심할 필요가 있다. Cloudflare는 “움직이는 부품이 줄어든 만큼의 비용 절감”이라는 정성적 표현만 썼고 구체적인 절감 수치는 제시하지 않았다. DO 인스턴스가 빠지니 요금이 줄어드는 방향인 건 분명하지만, 몇 퍼센트라는 숫자를 기대하고 접근할 일은 아니다.

13. 마이그레이션 체크리스트

서버를 운영 중이라면 순서대로 확인하자.

클라이언트라면 여기에 두 가지가 더 붙는다.

마무리

Tier 1 SDK 네 개 — TypeScript, Python, Go, C# — 는 릴리스 시점에 이미 2026-07-28을 말한다. Rust SDK는 베타로 지원한다. 공식 발표도 “세션 식별자에 의존하던 개발자에게는 어느 정도의 마이그레이션 비용이 있다”고 인정한다.

다만 방향 자체는 분명하다. 암묵적인 커넥션 상태를 걷어내고 모든 것을 요청 안에 명시적으로 담는 쪽이다. 엣지·서버리스처럼 인스턴스가 뜨고 지는 환경에서 MCP 서버를 굴린다면, 이번 변경은 손해가 아니라 이득이다. 세션 스토어를 붙들고 있을 이유가 없어졌기 때문이다.

폐기 기간이 최소 12개월이니 당장 오늘 전부 갈아엎을 필요는 없다. 하지만 server/discover는 예외다. 그건 폐기가 아니라 신규 필수 요구사항이라, 새 스펙을 지원한다고 말하려면 지금 넣어야 한다.