Pocket Notes MCP

Pocket Notes MCP

A small, readable MCP learning project implemented in TypeScript that uses a local JSON notebook to demonstrate core MCP features such as tools, resources, prompts, sampling, and notifications.

Category
访问服务器

README

Pocket Notes MCP

TypeScript로 만든 작고 읽기 쉬운 MCP 학습 프로젝트입니다. 로컬 JSON 메모장을 도메인으로 사용해 MCP의 핵심 기능과 주요 양방향 기능을 한 프로젝트에서 보여줍니다.

무엇을 배우나요?

MCP 개념 이 프로젝트의 예
Lifecycle / capability negotiation SDK가 연결 시 자동 처리하며 테스트 Client에서 확인
Tools list_notes, create_note, analyze_notes
Structured output Tool의 outputSchemastructuredContent
Tool annotations 읽기 전용, 멱등성, 파괴성 힌트
Resources notes://catalog
Resource templates notes://note/{id}
Resource links create_note 결과가 새 메모 URI를 반환
Prompts review_note
Completion Prompt의 noteId/style, Resource의 id 추천
Notifications 메모 생성 후 Resource 목록 변경 알림
Progress / cancellation analyze_notes
Sampling summarize_note가 Host의 모델에 요약 요청
Elicitation create_note_interactive가 사용자 입력 폼 요청
Roots list_workspace_roots가 Client의 작업 영역 요청
Logging 메모 생성 이벤트를 MCP Client에 전송

Tools, Resources, Prompts가 프로젝트의 본체입니다. Sampling, Elicitation, Roots는 MCP Client가 해당 capability를 선언했을 때만 작동하며, 지원하지 않는 Client에서는 이해하기 쉬운 오류 결과를 반환합니다.

요구사항

  • Node.js 24 LTS 권장 (.nvmrc 제공)
  • Node.js 22 LTS도 호환
  • npm 10 이상

프로덕션 지원 중인 @modelcontextprotocol/sdk v1.29.0을 고정해서 사용합니다. SDK v2는 이 프로젝트 작성 시점에 베타이므로 사용하지 않습니다.

시작하기

cd /Users/home/Projects/pocket-notes-mcp
npm install
npm run check

개발 모드:

npm run dev

아무 출력 없이 계속 실행되는 것이 정상입니다. stdio MCP 서버는 사람이 터미널에 입력하기를 기다리는 CLI가 아니라, MCP Host가 표준 입력으로 JSON-RPC 메시지를 보내기를 기다립니다. stdout은 MCP 메시지 전용이므로 디버그 출력은 stderr를 사용해야 합니다.

빌드된 서버 실행:

npm run build
npm start

MCP Host에 연결

Host 설정 형식은 제품마다 조금씩 다르지만 핵심 값은 같습니다.

{
  "mcpServers": {
    "pocket-notes": {
      "command": "node",
      "args": [
        "/Users/home/Projects/pocket-notes-mcp/dist/index.js"
      ],
      "env": {
        "POCKET_NOTES_FILE": "/Users/home/Projects/pocket-notes-mcp/data/notes.json"
      }
    }
  }
}

POCKET_NOTES_FILE을 생략하면 서버 프로세스의 현재 작업 디렉터리를 기준으로 data/notes.json을 사용합니다. Host 설정에서는 절대 경로를 지정하는 편이 명확합니다.

MCP Inspector로 확인

먼저 빌드합니다.

npm run build

그다음 공식 Inspector로 서버를 실행합니다.

npx @modelcontextprotocol/inspector \
  node /Users/home/Projects/pocket-notes-mcp/dist/index.js

Inspector에서 다음 순서로 살펴보면 좋습니다.

  1. tools/list에서 입력·출력 스키마와 annotations 확인
  2. list_notes 호출 후 structuredContent 확인
  3. resources/listresources/templates/list 확인
  4. notes://note/{id} Resource 읽기
  5. prompts/listreview_note Prompt 확인
  6. Completion 요청으로 noteId 추천 확인

Inspector나 Host가 Sampling, Elicitation, Roots를 지원하고 capability를 선언하면 해당 고급 Tool도 실행할 수 있습니다.

프로젝트 구조

pocket-notes-mcp/
├── src/
│   ├── index.ts                 stdio 전송 연결
│   ├── server.ts                MCP 서버 조립과 instructions
│   ├── register-tools.ts        일반 Tools
│   ├── register-client-tools.ts Sampling, Elicitation, Roots Tools
│   ├── register-resources.ts    Resources와 Resource Template
│   ├── register-prompts.ts      Prompt와 Completion
│   ├── note-store.ts            JSON 파일 저장소
│   └── note.ts                  도메인 타입과 출력 변환
├── data/
│   └── notes.json               예제 데이터
├── tests/
│   ├── note-store.test.ts
│   ├── server.test.ts
│   └── client-capabilities.test.ts
├── package.json
├── tsconfig.json
└── tsconfig.build.json

파일은 MCP 개념별로 나눴지만 별도의 프레임워크나 DI 컨테이너, 데이터베이스, 라우터 계층은 추가하지 않았습니다. 학습에 필요하지 않은 추상화를 피하기 위한 의도적인 선택입니다.

코드 읽는 순서

1. 서버 실행

src/index.ts

NoteStore 생성
→ McpServer 생성
→ StdioServerTransport 생성
→ server.connect()

2. Tool

src/register-tools.tslist_notes를 먼저 읽습니다.

Zod inputSchema
→ Tool handler
→ NoteStore
→ content + structuredContent

다음으로 상태를 변경하는 create_note를 읽으면 Tool annotations와 Resource link, list-changed notification의 관계를 볼 수 있습니다.

3. Resource

src/register-resources.ts에서 고정 URI와 템플릿 URI를 비교합니다.

notes://catalog
notes://note/{id}

4. Prompt와 Completion

src/register-prompts.tsreview_note는 사용자가 명시적으로 선택하는 재사용 워크플로입니다. completable()이 유효한 메모 ID와 복습 스타일을 추천합니다.

5. 양방향 MCP

summarize_note, create_note_interactive, list_workspace_roots는 서버가 다시 Client에 요청을 보내는 예제입니다.

Host/Client → Tool 호출 → MCP Server
                         ↓
                Sampling/Elicitation/Roots 요청
                         ↓
                    Host/Client 응답

테스트

npm test

테스트는 함수만 직접 호출하지 않습니다. SDK의 InMemoryTransport로 실제 MCP Client와 Server를 연결해 다음 프로토콜 동작을 검증합니다.

  • 초기화와 instructions 협상
  • Tool 목록과 호출
  • 구조화된 Tool 결과 검증
  • Resource 목록과 읽기
  • Prompt 목록과 조회
  • Completion
  • 미지원 capability의 안전한 실패
  • Sampling, Elicitation, Roots의 실제 양방향 요청

전체 검증:

npm run check

안전 경계

  • 서버는 POCKET_NOTES_FILE로 지정한 JSON 파일만 읽고 씁니다.
  • 메모 저장은 임시 파일을 만든 뒤 교체해 중간 상태의 JSON이 남지 않게 합니다.
  • create_note는 변경 Tool이지만 기존 메모를 삭제하지 않습니다.
  • Elicitation 폼에는 비밀번호, API 키 등 민감 정보를 입력하면 안 됩니다.
  • Tool annotations는 힌트일 뿐이며, 실제 승인과 권한 관리는 MCP Host가 담당합니다.
  • 원격 HTTP와 OAuth는 학습 범위를 흐리므로 포함하지 않았습니다. 다음 단계에서 Streamable HTTP 서버로 확장할 때 추가하는 것이 좋습니다.

공식 자료

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选