<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Markpin 블로그</title>
  <link>https://markpin.dev/ko/blog/</link>
  <description>웹에서 읽는 일과 Markpin을 만드는 일에 대해 적습니다.</description>
  <language>ko</language>
  <atom:link href="https://markpin.dev/ko/blog/feed.xml" rel="self" type="application/rss+xml"/>
  <item>
    <title>왜 표시했는지 묻는 웹 형광펜을 만들며 정한 일곱 가지 (Markpin 개발기)</title>
    <link>https://markpin.dev/ko/blog/why-did-you-mark-this/</link>
    <guid isPermaLink="true">https://markpin.dev/ko/blog/why-did-you-mark-this/</guid>
    <pubDate>Wed, 14 Oct 2026 00:00:00 GMT</pubDate>
    <description>로컬 퍼스트 Chrome 확장 Markpin을 만들며 내린 결정 일곱 가지. IndexedDB, 페이지마다 Markdown 파일 하나, 서버 없는 동기화, 형광펜 복원, MCP 서버, 그리고 1.2.0의 기호와 한 줄.</description>
    <content:encoded><![CDATA[<p>8년차 개발자로 지내면서 기술 아티클을 꽤 많이 읽어 왔는데, 바로 읽지 못하고 일단 어딘가에 저장해 두는 경우가 많았다. 그게 Notion이었다가 Chrome 북마크였다가 하면서 링크는 여기저기 쌓였는데(그래서 파편화됐지만…), 정작 읽은 내용은 어디에도 남지 않았다. 읽다가 멈춘 글은 어디까지 읽었는지 다시 찾기 어려웠고, 형광펜 친 문장은 어디에 뒀는지 잊어버렸고, 읽으면서 든 생각은 따로 적는 게 귀찮아서 그냥 흘려보내는 일이 반복됐다. 그래서 종이책 읽을 때 하던 것(밑줄 긋고, 여백에 메모하고, 책갈피 꽂고, 다음에 다시 펼치는 것)을 웹에서 그대로 하게 해 주는 Chrome 확장을 만들게 됐다. 이름은 Markpin이고, 무료이며 계정이 없다.</p>
<p>이번에 올린 1.2.0에서는 형광펜을 그은 다음에 일어나는 일을 바꿨다. 문장을 드래그해 색이나 기호를 고르면 메모 칸이 열리는데, 빈칸이 아니라 「왜 표시했나요?」 같은 질문이 먼저 적혀 있다. 이렇게 바꾼 데는 나름 근거가 있다. 여러 학습 방법을 비교한 정리(Dunlosky 외, 2013)에서 형광펜만 긋는 건 효과가 낮은 쪽으로 평가됐고, 스스로 &quot;왜?&quot;를 묻거나 자기 말로 설명해 보는 쪽이 더 높게 평가됐다. 또 Roediger와 Karpicke의 2006년 실험에서는 글을 기억나는 대로 떠올려 본 사람들이 다시 읽기만 한 사람들보다 일주일 뒤에 더 많이 기억했다(61% 대 40%). 메모 칸이 무엇을 묻는지, 그리고 「다 읽음」을 누르면 무슨 일이 일어나는지는 이 두 결과를 보고 정했다.</p>
<p>이 글은 &quot;무엇을 만들었나&quot;보다 &quot;어떻게 만들었나&quot;에 가깝다. 로컬 퍼스트 Chrome 확장을 만들면서 내린 결정 일곱 개를 순서대로 적어 보고자 한다(앞의 여섯 개는 velog에 먼저 썼던 개발기를 지금 코드에 맞게 고친 것이다).</p>
<figure><img src="https://markpin.dev/img/blog/note-box-question.jpg" alt="형광펜을 남기자마자 열린 메모 칸. 붙인 기호에 따라 질문이 달라진다(화면은 영어 UI)" loading="lazy"></figure>
<h2>1. 데이터 정본은 IndexedDB에, 설정만 chrome.storage에</h2>
<p>우선 저장한 페이지와 클립(형광펜, 메모, 영역 클립)은 전부 확장의 IndexedDB에 둔다. <code>chrome.storage</code>에는 저장 위치, 플로팅 버튼 표시, 온디바이스 AI 켜기 같은 설정만 담는다. 이렇게 나눈 이유는 두 가지인데, 하나는 용량이다. 페이지 본문과 클립 이미지가 쌓이면 <code>chrome.storage.local</code> 기본 한도를 금방 넘어 버린다(<code>unlimitedStorage</code> 권한이 여기서 나온다). 다른 하나는 트랜잭션이다. 페이지와 그 클립들이 레코드 하나라서, 클립 하나를 더할 때도 읽고 고치고 다시 쓰는 과정 전체가 원자적이어야 했다. 사이드패널의 Zustand 스토어는 UI 상태만 들고 있고 데이터는 항상 IndexedDB에서 다시 읽는다. 백그라운드가 쓰고 나면 <code>STORE_CHANGED</code>를 브로드캐스트하고, 사이드패널은 자기가 쓴 뒤엔 스스로 다시 읽는다(<code>sendMessage</code>는 보낸 쪽에는 돌아오지 않기 때문이다).</p>
<h2>2. 파일은 페이지당 Markdown 하나, 기계 데이터는 파일 끝 주석 블록에</h2>
<p>파일 포맷에서 지키고 싶었던 건 두 가지였다. 사람이 Obsidian에서 열었을 때 깨끗해야 하고, 확장이 다시 읽을 때 손실이 없어야 한다는 것. 처음(v1)엔 별 고민 없이 frontmatter에 키를 전부 넣었는데, 막상 Obsidian에서 열어 보니 Properties 패널에 전부 노출되고 중첩 키(<code>clips</code>)는 JSON 한 줄로 보였다(이건 좀 보기 싫었다). 그래서 v2에서는 이렇게 나눴다.</p>
<pre><code>---
title: 예시 글 제목
url: https://example.com/article
savedAt: 2026-09-16T10:00:00.000Z
tags:
  - react
  - state
summary: 한 줄 요약
---

## Clips

&gt; 인용된 문장

내 메모

## Content

(본문)
&lt;!-- markpin
{&quot;v&quot;:2,&quot;id&quot;:&quot;…&quot;,&quot;rev&quot;:3,&quot;updatedAt&quot;:&quot;…&quot;,&quot;domain&quot;:&quot;example.com&quot;,&quot;clips&quot;:[{&quot;id&quot;:&quot;…&quot;,&quot;type&quot;:&quot;text&quot;,&quot;createdAt&quot;:&quot;…&quot;,&quot;updatedAt&quot;:&quot;…&quot;,&quot;text&quot;:&quot;인용된 문장&quot;,&quot;note&quot;:&quot;내 메모&quot;,&quot;selectors&quot;:[{&quot;type&quot;:&quot;TextQuoteSelector&quot;,&quot;exact&quot;:&quot;…&quot;,&quot;prefix&quot;:&quot;…&quot;,&quot;suffix&quot;:&quot;…&quot;},…],&quot;color&quot;:&quot;amber&quot;}]}
--&gt;</code></pre>
<p>frontmatter에는 사람이 읽는 키만 남겼다. <code>title</code>, <code>url</code>, <code>savedAt</code>, <code>tags</code>는 늘 있고, 값이 있을 때만 <code>summary</code>, <code>note</code>, <code>readAt</code>, <code>skimmedAt</code>, <code>deletedAt</code>이 붙는다(<code>summary</code>는 Chrome 내장 모델이 요약을 만들었을 때만 생긴다). <code>id rev updatedAt domain clips bookmark</code> 같은 기계용 데이터는 파일 끝 <code>&lt;!-- markpin … --&gt;</code> 안에 JSON 한 줄로 넣었다(위 예시는 줄인 것이다). 블록을 끝에 둔 이유는 Obsidian Live Preview가 HTML 주석을 숨기지 않고 회색 글자로 보여 주기 때문인데(Reading view에서는 숨긴다), 끝에 있으면 적어도 본문을 읽는 데는 방해가 안 된다. 문자열 안에 <code>--&gt;</code>가 들어가면 주석이 일찍 닫히지 않도록 그 JSON 줄에서는 <code>--\u003e</code>로 쓰고, <code>JSON.parse</code>가 원래대로 되돌린다.</p>
<p>모르는 frontmatter 키와 모르는 블록 키는 둘 다 보존하고, 키를 더하기만 하는 변경은 <code>v</code>를 올리지 않기로 했다. 파일 한 개 상한은 512KB로, 본문이 넘치면 잘라내고 <code>contentTruncated</code>를 남긴다. 파서는 v1(frontmatter <code>markpin: 1</code>)도 계속 읽는다. 옵션의 「기존 파일 다시 쓰기」는 전부 v2로 다시 쓰면서 <code>rev</code>만 올리고 <code>updatedAt</code>은 건드리지 않는데, 그래서 다른 기기에서 충돌 사본이 생기지 않는다.</p>
<h2>3. 동기화는 서버 없이, 폴더나 Google Drive로</h2>
<p>저장 위치는 셋 중 하나를 고른다. 브라우저만(기본), 내 컴퓨터의 폴더(File System Access API, <code>showDirectoryPicker</code>), 그리고 Google Drive(<code>drive.file</code> 스코프라 확장이 만든 파일만 볼 수 있다). 폴더와 Drive는 같은 인터페이스(<code>list</code>, <code>read</code>, <code>write</code>, <code>remove</code>) 뒤에 있는 어댑터 두 개이고, 엔진 하나가 둘 다 돌린다.</p>
<p>엔진은 마지막 쓰기 3초 뒤에, 그리고 <code>chrome.alarms</code>로 5분마다 동기화한다. 실패하면 재시도 간격을 1분부터 두 배씩 늘려 최대 30분까지 기다렸다가 다시 시도한다. 충돌 처리는 단순하게 했다. 동기화 이력이 없는 페이지는 <code>updatedAt</code>이 더 늦은 쪽을 고르고, 이력이 있는 페이지가 양쪽에서 바뀌었으면 이미 올라가 있는 쪽을 받되 이 기기에서 고친 쪽은 지우지 않고 <code>.conflict-</code> 사본으로 남긴다. 가장 똑똑한 방법은 아니겠지만 서버 없이 쓰는 개인 도구에서는 이 정도면 충분하다고 생각했다. 폴더 저장소에서는 삭제한 페이지를 Obsidian 휴지통 관례를 따라 <code>.trash/</code>로 옮기는 옵션도 있다(고른 폴더 안의 <code>.trash/</code>이고 기본은 꺼져 있다).</p>
<p>MV3 서비스 워커는 언제든 죽을 수 있어서, 주기 동기화와 재시도는 둘 다 알람으로 걸고 아직 올려야 할 것은 IndexedDB에 적어 둔다. 동기화가 도는 중에 또 요청이 들어오면 <code>again</code> 플래그를 세워 끝난 뒤 한 번 더 돌리고, 어댑터를 바꾸는 중에는 옛 어댑터가 끼어들지 못하게 막아 뒀다. 사실 이 서비스 워커 수명 문제가 MV3에서 제일 신경 쓰이는 부분인 것 같다.</p>
<h2>4. 형광펜을 다시 그 자리에 그리기</h2>
<p>페이지를 다시 열었을 때 형광펜이 같은 문장 위에 있어야 하는데, 이게 생각보다 까다로운 문제다. 텍스트 클립에는 W3C Web Annotation 셀렉터 세 가지를 같이 저장한다. 문장 그대로에 앞뒤로 최대 32자씩을 붙인 <code>TextQuoteSelector</code>, 그리고 <code>TextPositionSelector</code>와 <code>CssSelector</code>다. 영역 클립은 요소마다 <code>CssSelector</code>와 <code>XPathSelector</code>를 저장한다. 복원할 땐 먼저 quote를 페이지 전체에서 그대로 찾고, 없으면 CSS나 XPath로 요소를 찾아 그 안에서 공백을 정규화해 다시 찾고, 그래도 없으면 페이지 전체를 정규화해서 한 번 더 찾는다(<code>TextPositionSelector</code>는 다른 도구와의 호환용으로 저장만 하고 복원엔 쓰지 않는다). 전부 실패한 클립은 orphan으로 표시해서 목록에는 남기고 페이지에는 안 그린다. DOM이 조금 바뀌어도 quote 셀렉터가 대부분 잡아 주는 것 같다.</p>
<p>형광펜은 CSS Custom Highlight API로 칠해서 페이지 DOM을 건드리지 않는다. 나머지 페이지 안 UI(플로팅 버튼, 선택 툴바, 메모 팝오버, 레일)는 전부 <code>#markpin-host</code> 아래 Shadow DOM에 그리고, <code>!important</code>는 한 군데도 쓰지 않는다. 페이지 본문은 저장하거나 형광펜, 클립, 책갈피를 남길 때만 담고, 저장하지 않은 페이지에서는 아무것도 기록하지 않는다.</p>
<h2>5. 요약과 태그는 Chrome 내장 모델로</h2>
<p>요약과 태그 제안은 Chrome 내장 Prompt API(<code>LanguageModel</code>)를 쓴다. 모델이 기기 안에서 돌아서 본문이 밖으로 나가지 않고 API 키도 필요 없는데, 로컬 퍼스트라는 방향과 잘 맞는다고 생각했다. UI 언어가 en·ja·es·de·fr이면 <code>expectedOutputs</code>로 출력 언어를 선언하고, 아직 받아 주지 않는 ko·pt-BR은 프롬프트로만 언어를 정한다(한국어가 아직 이 목록에 없는 건 좀 아쉽다). 모델이 없는 기기에선 그냥 꺼지고, 옵션에서 끌 수도 있다.</p>
<h2>6. MCP로 내 폴더를 Claude가 읽게 하고, 쓰기는 확인 뒤에</h2>
<p><code>@markpin/mcp</code>는 그 폴더 위에서 도는 stdio MCP 서버다(Node 20.1 이상). 기본은 읽기 전용 도구 4개(<code>search get_page list_recent list_tags</code>)만 있고, <code>--allow-write</code>를 주면 쓰기 도구 12개가 더 등록된다(<code>add_clip set_clip_note set_bookmark update_tags …</code>). 클라이언트가 elicitation을 지원하면 쓰기마다 확인을 먼저 받는데, 내 파일을 AI가 조용히 고쳐 놓는 건 원치 않았기 때문이다. 모든 도구에 <code>readOnlyHint</code>를, 쓰기 도구에는 <code>destructiveHint</code>도 달아 뒀다(<code>true</code>인 건 <code>delete_pages</code> 하나다). 폴더를 watch하고 있어서 브라우저에서 방금 저장한 페이지가 다음 질문에 바로 잡히는데, 이게 써 보면 꽤 재밌다. 서버 소스는 MIT로 공개했다.</p>
<pre><code>claude mcp add markpin -- npx -y @markpin/mcp@latest --dir ~/Markpin --allow-write</code></pre>
<h2>7. 1.2.0에서 더한 기호와 한 줄, 그리고 파일에 쓰지 않는 읽던 자리</h2>
<p>선택 툴바가 두 줄이 됐다. 윗줄은 <code>[클립] ? ! × ★</code>이고, 아랫줄은 나머지 형광펜 색 세 개의 점(클립 버튼은 지금 고른 색을 쓴다)과 오른쪽 끝의 책갈피다. 색이나 기호를 한 번 누르면 바로 클립이 만들어진다. 기호 네 개는 의문, 새로 안 것, 반박, 핵심인데, 클립 하나에는 색 하나와 기호 하나까지만 붙는다. 색은 분류용이고 기호는 반응용이라고 생각하면 편하다.</p>
<p>클립이 저장되면 열리는 메모 칸의 안내 문구도 기호에 따라 달라진다. 기호가 없으면 「왜 표시했나요?」, <code>?</code>면 「무엇이 궁금한가요?」, <code>!</code>면 「무엇이 새로운가요?」, <code>×</code>면 「왜 아닌가요?」, <code>★</code>면 「왜 핵심인가요?」다. 막아서는 창이 아니라 안내 문구라서 비워 둬도 된다(적기 귀찮은 날도 있으니까).</p>
<p>다 읽은 글에서 책갈피를 눌러 「다 읽음」을 고르면 「이 글을 한 줄로」 칸이 하나 더 열린다. 안내 문구는 「기억나는 대로 한 줄」이고 500자까지 쓸 수 있다. 이 한 줄은 사이드패널 목록에서 제목 아래에 보이고 검색에도 걸린다. 책갈피와 읽음 옆에는 세 번째 상태인 「훑어봄」도 생겼다. 셋은 겹치지 않아서 한 글에는 하나만 붙고, 훑어봄은 한 줄을 묻지 않는다.</p>
<p>전부 키를 더하기만 한 변경이라 포맷은 여전히 v2다. 1.2.0 이후 같은 파일의 윗부분은 이렇게 생겼다.</p>
<pre><code>---
title: 예시 글 제목
url: https://example.com/article
savedAt: 2026-09-16T10:00:00.000Z
tags:
  - react
  - state
summary: 한 줄 요약
note: 전역 상태에 넣어 둔 것 대부분은 사실 서버 캐시였다
readAt: 2026-10-12T08:30:00.000Z
---

## Clips

&gt; 인용된 문장

× 모든 컴포넌트가 읽는 값일 때만 그렇다</code></pre>
<p>기호는 형광펜 아래 메모 줄 앞에 붙고, 파일 끝 블록에는 클립마다 <code>&quot;kind&quot;:&quot;disagree&quot;</code>처럼 들어간다(값은 <code>question</code>, <code>insight</code>, <code>disagree</code>, <code>star</code>). 한 줄은 frontmatter의 <code>note</code> 속성이 되고, 훑어본 글에는 <code>readAt</code> 자리에 <code>skimmedAt</code>이 ISO 시간으로 들어간다. 빈 값은 쓰지 않는다(<code>tags</code>만은 비어 있어도 <code>tags: []</code>로 쓴다).</p>
<p>저장한 페이지에서는 왼쪽 가장자리에 12px짜리 레일이 생긴다(마우스를 올리면 넓어지고, 보여 줄 게 없으면 숨는다). 클립은 그 색의 점으로, 책갈피는 리본으로, 읽던 자리는 회색 줄로 보이고, 점을 누르면 그 자리로 스크롤된다. 레일은 처음에 오른쪽 가장자리에 뒀는데, macOS 오버레이 스크롤바와 겹쳐서 거의 안 보이는 바람에 왼쪽으로 옮겼다(만든 나도 잘 못 찾았다…). 읽던 자리는 스크롤이 멈추고 1.5초 뒤에 기록되는데, 그 기기의 IndexedDB에만 두고 Markdown 파일에는 쓰지 않는다. 다시 돌아와도 토스트나 자동 스크롤은 없고, 읽던 자리는 레일에만 보인다.</p>
<p>사이드패널에서는 35일이 넘은 책갈피를 카드 하나로 묶어 「35일 넘은 책갈피 N개 · 아직 읽고 싶나요?」라고 한 번 묻는다. 글마다 「두기」, 「훑어봄」, 「책갈피 빼기」 중 하나를 고르면 되고, 아무것도 지워지지 않는다.</p>
<p><code>@markpin/mcp</code> 0.9.0에서는 <code>add_clip</code>이 <code>kind</code>를 받고, 쓰기 도구가 두 개 늘었다. 한 줄을 쓰는 <code>set_note</code>(빈 문자열이면 지우고, 바뀌기 전과 후를 돌려준다)와 <code>mark_skimmed</code>다. 읽기 도구 중에서는 <code>get_page</code>만 <code>kind</code>, <code>note</code>, <code>skimmedAt</code>을 돌려주고, <code>search</code>와 <code>list_recent</code>는 그것들을 뺀 요약을 돌려준다.</p>
<h2>권한과 외부 요청</h2>
<p>권한은 <code>storage unlimitedStorage sidePanel activeTab alarms identity</code>에 호스트 권한 <code>&lt;all_urls&gt;</code>이고, 콘텐츠 스크립트는 http와 https 페이지에서 돈다. <code>identity</code>와 <code>googleapis.com</code>은 Drive를 연결할 때만 쓰고, 확장은 그 밖의 외부 요청을 하지 않는다. 분석 도구도 넣지 않았다.</p>
<h2>묻고 싶은 것</h2>
<p>여기까지가 지금 시점에서 내린 결정들이다. 다 만들고 보니 아직 부족한 부분도 보이고, 특히 아래 두 가지는 혼자 판단하기보다 써 본 분들의 이야기를 듣고 싶다. 이 페이지에는 댓글이 없어서 support@markpin.dev로 알려 주면 정말 고마울 것 같다.</p>
<ol><li>파일 포맷 v2. 사람이 읽는 키는 frontmatter에, 기계 데이터는 파일 끝 주석 블록에 두는 이 분리를 Obsidian이나 다른 Markdown 도구에서 써 보면 불편한 지점이 있을지 궁금하다.</li><li>다음으로 보고 있는 건 읽은 것을 다시 보는 쪽이다. 하이라이트 복습, 내 메모 모아 보기, 로컬 읽기 통계 중 무엇이 먼저면 좋을지 듣고 싶다.</li></ol>
<p>로컬 퍼스트 확장을 만들어 보려는 누군가에게 약간의 도움은 됐으면 좋겠다.</p>
<ul><li>확장: <a href="https://chromewebstore.google.com/detail/gapplocbnakkofbdbllljohlfceghgmb">https://chromewebstore.google.com/detail/gapplocbnakkofbdbllljohlfceghgmb</a></li><li>MCP 서버: <a href="https://github.com/mud-studio/markpin-mcp">https://github.com/mud-studio/markpin-mcp</a></li></ul>]]></content:encoded>
  </item>
  <item>
    <title>옵시디언에 웹 글 하이라이트와 메모 쌓기: 밑줄 긋고, 왜 그었는지 적고, 볼트에 파일로</title>
    <link>https://markpin.dev/ko/blog/web-highlights-in-obsidian/</link>
    <guid isPermaLink="true">https://markpin.dev/ko/blog/web-highlights-in-obsidian/</guid>
    <pubDate>Tue, 13 Oct 2026 00:00:00 GMT</pubDate>
    <description>Chrome에서 웹 글에 형광펜을 긋고 기호와 메모를 남기면, 글마다 Markdown 파일 하나가 옵시디언 볼트에 쌓입니다. 설정 방법과 실제 파일 모양을 정리했습니다.</description>
    <content:encoded><![CDATA[<p>웹 글 하나를 통째로 볼트에 가져오는 일은 옵시디언 공식 웹 클리퍼가 제일 잘한다고 생각합니다. 다만 제가 계속 아쉬웠던 건 가져오는 쪽이 아니라 읽는 동안의 일이었습니다. 읽다가 한 줄에 표시해 두고, 왜 표시했는지 그 자리에서 적어 두고, 다음 날 읽다 멈춘 자리부터 다시 이어 읽는 것들인데(종이책에서는 펜 하나로 다 되던 일입니다), 웹에서는 이게 은근히 번거로워서 저장만 해 둔 글이 Notion이랑 북마크에 쌓여 갔습니다. 그래서 그 부분만 해 주는 Chrome 확장(Markpin)을 사이드 프로젝트로 만들었고, 저장 결과가 평범한 Markdown 파일이라 옵시디언 볼트 안에 그대로 둘 수 있습니다. 이 글에서는 설정하는 방법과 실제로 볼트에 어떤 파일이 쌓이는지를 정리해 보고자 합니다.</p>
<h2>결과부터</h2>
<p>우선 결과부터 보면, 글 하나가 파일 하나가 됩니다. 형광펜으로 그은 문장은 <code>==하이라이트==</code>로 들어가고 그 아래에 제가 적은 메모가 붙으며, 글 제목과 URL, 태그, 그리고 다 읽고 적은 한 줄은 속성(Properties)으로 들어갑니다.</p>
<figure><img src="https://markpin.dev/img/blog/obsidian-file.jpg" alt="옵시디언에서 연 저장 파일. 위에는 속성, Clips 아래에는 하이라이트와 메모가 보인다" loading="lazy"></figure>
<h2>설정하는 방법</h2>
<ol><li><a href="https://chromewebstore.google.com/detail/gapplocbnakkofbdbllljohlfceghgmb">Chrome 웹 스토어에서 Markpin</a>을 설치합니다. 무료이고 계정을 만들 필요가 없습니다.</li><li>확장 옵션을 열고 <strong>저장소</strong>에서 <strong>로컬 폴더</strong>를 고른 뒤 볼트 안의 폴더를 하나 지정합니다(예를 들면 <code>내볼트/Markpin</code>). Chrome이 폴더 접근을 한 번 확인합니다. Chrome을 다시 시작한 뒤 옵션에 폴더 권한이 필요하다는 안내가 뜨면 「권한 다시 허용」을 누르고 &quot;방문할 때마다 허용&quot;을 고르면 되고, 그 뒤로는 다시 묻지 않습니다.</li><li>같은 옵션의 <strong>Markdown</strong>에서 <strong>Obsidian</strong> 템플릿을 고릅니다. 클립을 <code>==하이라이트==</code>와 <code>[!quote]</code> 콜아웃으로 써 줍니다(기본 템플릿은 <code>&gt;</code> 인용문으로 씁니다).</li></ol>
<p>템플릿은 그 뒤에 Markpin이 쓰는 파일부터 적용됩니다. 이미 저장한 글은 다음에 형광펜이나 메모, 태그를 더해서 내용이 바뀔 때 새 모양으로 다시 쓰이고, 한꺼번에 바꾸고 싶으면 옵션의 「기존 파일 다시 쓰기」를 누르면 됩니다. 다만 이때 Markpin이 쓰는 속성이나 본문을 Markpin 밖에서 고쳤다면 그 내용은 사라지니 주의가 필요합니다. 직접 추가한 속성은 남습니다.</p>
<h2>읽으면서 표시하기</h2>
<p>문장을 드래그하면 두 줄짜리 작은 툴바가 뜨는데, 윗줄은 <code>클립 ? ! × ★</code>이고 아랫줄은 다른 형광펜 색과 책갈피입니다. 색이나 기호를 한 번 누르면 바로 저장되고, 아직 저장하지 않은 글이었다면 글도 같이 저장됩니다.</p>
<p>기호 네 개는 읽으면서 든 반응을 남기는 용도인데, <code>?</code>는 의문, <code>!</code>는 새로 안 것, <code>×</code>는 반박, <code>★</code>는 핵심입니다(색은 분류용, 기호는 반응용이라고 생각하면 편합니다).</p>
<p>저장되자마자 메모 칸이 열리는데, 빈칸이 아니라 질문이 하나 적혀 있습니다. 기호 없이 형광펜만 그었으면 「왜 표시했나요?」, <code>?</code>면 「무엇이 궁금한가요?」, <code>!</code>면 「무엇이 새로운가요?」, <code>×</code>면 「왜 아닌가요?」, <code>★</code>면 「왜 핵심인가요?」입니다. 형광펜만 긋고 지나가면 나중에 왜 그었는지 기억이 안 나는 경우가 많아서 넣은 장치인데, 적기 귀찮을 땐 비워 둬도 됩니다.</p>
<figure><img src="https://markpin.dev/img/blog/note-box-question.jpg" alt="하이라이트 직후 열린 메모 칸. 붙인 기호에 따라 질문이 달라진다(화면은 영어 UI)" loading="lazy"></figure>
<p>읽다가 멈출 때는 책갈피를 꽂아 둡니다. 페이지 왼쪽 가장자리에 얇은 레일이 생겨서 내 표시는 점으로, 책갈피는 리본으로, 읽던 자리는 줄로 보이고, 점을 누르면 그 자리로 이동합니다. 다 읽으면 꽂아 둔 책갈피를 눌러 「다 읽음」을 고릅니다. 그러면 이 글을 기억나는 대로 한 줄로 적는 칸이 열리고, 끝까지 읽지 않았다면 같은 자리에서 「훑어봄」으로 남기면 됩니다.</p>
<h2>볼트에 쌓이는 파일</h2>
<p>파일은 지정한 폴더 아래 <code>pages/연도/</code>에 글마다 하나씩 생깁니다. 예시로 줄이고 다듬으면 이런 모양입니다.</p>
<pre><code>---
title: Pin
url: https://en.wikipedia.org/wiki/Pin
savedAt: 2026-10-01T14:46:40.646Z
tags:
  - pins
  - history
summary: Pins are fastening devices made from various materials.
note: 바늘보다 오래됐다. 처음엔 뼈와 가시, 청동기부터 황동.
readAt: 2026-10-13T02:10:00.000Z
---

## Clips

==A pin is a device, typically pointed, used for fastening objects or fabrics together.==

안전핀 글이랑 비교해 볼 것

==Many later pins were made of brass==

? 왜 철이 아니라 황동이었을까

&gt; [!quote]
&gt; Different types of pins

## Content

(글 본문)
&lt;!-- markpin
{&quot;v&quot;:2,&quot;id&quot;:&quot;…&quot;,&quot;clips&quot;:[…]}
--&gt;</code></pre>
<p>속성에는 <code>title</code>, <code>url</code>, <code>savedAt</code>, <code>tags</code>가 항상 들어가고, Chrome 내장 AI가 만든 요약이 있으면 <code>summary</code>도 들어갑니다. <code>note</code>가 다 읽고 적은 한 줄입니다. 다 읽음이나 훑어봄으로 표시하면 <code>readAt</code>이나 <code>skimmedAt</code>이 생깁니다. 하이라이트는 <code>==…==</code>라서 옵시디언에서 형광펜으로 보이고, 메모는 바로 아래 줄에 오는데 기호를 붙였다면 <code>? 왜 철이 아니라 황동이었을까</code>처럼 줄 맨 앞에 기호가 붙습니다. 문단이나 이미지를 네모로 감싼 영역 클립은 <code>[!quote]</code> 콜아웃이 됩니다.</p>
<p>파일 맨 끝의 주석 블록은 Markpin이 웹 페이지에 형광펜을 다시 그릴 때 쓰는 데이터입니다. Reading view에서는 안 보이고, Live Preview에서는 노트 맨 아래에 회색 글자로 된 긴 JSON 한 줄이 보입니다(이 부분은 좀 아쉽지만 지우면 안 됩니다).</p>
<h2>옵시디언에서 쓸 때 알아 둘 것</h2>
<p>평범한 노트라서 검색하면 본문뿐 아니라 적어 둔 메모와 한 줄까지 같이 걸리고, 다른 노트에서 링크도 그대로 걸 수 있습니다.</p>
<p>다만 두 가지는 미리 알아 두면 좋습니다. 속성은 자유롭게 추가해도 됩니다(Markpin이 모르는 속성은 그대로 둡니다). 반대로 Markpin이 쓰는 속성이나 본문을 옵시디언에서 직접 고치면, 다음에 Markpin이 그 파일을 다시 쓸 때 덮어써집니다. 그래서 길게 정리하고 싶은 생각은 내 노트에 따로 쓰고 이 파일로 링크를 거는 편이 안전합니다.</p>
<p>추가로, 옵션에서 「삭제한 페이지를 .trash/ 폴더로 옮기기」를 켜면 삭제한 글의 파일이 지정한 폴더 안의 <code>.trash/</code>(예를 들면 <code>내볼트/Markpin/.trash/</code>)로 옮겨집니다. 볼트 최상위에 있는 옵시디언 휴지통과는 다른 폴더이고, 기본은 꺼져 있으며 폴더 저장소에서만 동작합니다.</p>
<h2>쓰기 전에 알아 둘 것</h2>
<ul><li>데스크톱 Chrome(122 이상)에서만 동작합니다. 모바일에서는 형광펜을 그을 수 없습니다.</li><li>볼트에 넣으려면 <strong>로컬 폴더</strong>를 써야 합니다. Google Drive 저장소는 내 드라이브에 Markpin 폴더를 따로 만들어 쓰기 때문에 볼트 안으로 들어오지 않습니다.</li><li>Obsidian 템플릿에서는 형광펜 색이 본문에 표현되지 않습니다. 색 정보는 파일 끝 블록과 웹 페이지에만 남습니다.</li><li>읽던 자리는 그 컴퓨터에만 기억되고 파일에는 쓰지 않습니다.</li></ul>
<h2>Claude가 같은 폴더를 읽게 하기(선택)</h2>
<p>Markpin에는 이 폴더를 읽는 작은 MCP 서버가 있어서, Claude Code나 Cursor 같은 AI 도구가 제가 저장해 둔 글에서 답을 찾게 할 수 있습니다. 서버는 내 컴퓨터에서 돌고 API 키가 필요 없으며, <code>--allow-write</code>를 붙이지 않으면 읽기만 합니다. Node.js 20.1 이상이 필요합니다.</p>
<pre><code>claude mcp add markpin -- npx -y @markpin/mcp@latest --dir ~/내볼트/Markpin</code></pre>
<p>연결해 두고 &quot;황동 핀에 대해 내가 뭐 표시해 뒀더라?&quot; 하고 물으면 저장한 글에서 찾아 줍니다.</p>
<p>아직 혼자 만들고 있는 도구라 부족한 부분이 많을 텐데, 옵시디언에서 써 보시고 불편한 점이나 파일 모양에서 걸리는 부분을 support@markpin.dev로 알려 주시면 큰 도움이 될 것 같습니다.</p>]]></content:encoded>
  </item>
</channel>
</rss>
