personal-context-mcp
<div align="center">
# 🧠 personal-context-mcp
**把「你是谁」存一次,让每个 AI 都记得你。**
_Store who you are once — let every AI remember you._
[](https://modelcontextprotocol.io)
[](https://www.python.org)
[](https://github.com/astral-sh/uv)
[](LICENSE)
[中文](#-中文) · [English](#-english)
<br/>
<!--
⬇️ 放一张「AI 调用 who_am_i」的截图到 docs/who-am-i.png
推荐来源二选一:
1) MCP Inspector:uv run mcp dev server.py → 在 Tools 里点 who_am_i → 截图返回结果
2) Claude Code / Desktop:对 AI 说「调用 who_am_i 了解我」→ 截图那一轮对话
截好后覆盖到 docs/who-am-i.png 即可,下面这行会自动显示。
-->
<img src="docs/who-am-i.png" alt="AI 调用 who_am_i 一键读到完整个人上下文" width="720">
<sub>▲ 接入后对任意 AI 说「调用 who_am_i」,它一次就读到你完整的上下文</sub>
</div>
---
## 🇨🇳 中文
### ✨ 这是什么
换一个新 AI、新开一个聊天框,你是不是又得从头交代一遍「我是谁、我喜欢什么风格、我做过什么」?
`personal-context-mcp` 把这些**存成 markdown**,通过 **MCP(Model Context Protocol)** 暴露成一组工具。任何支持 MCP 的 AI(Claude Code、Claude Desktop、Cursor…)接上后,调用一次 `who_am_i` 就「认识你」,不用再自我介绍。
> 📦 数据一份,插头随时加 · ☁️ 放 GitHub 永久免费 · 🔌 本地 stdio 零托管 · 🔐 分层可见
### ⏱️ 30 秒看效果
同样一句「帮我改简历」,接入前后 AI 的反应完全不同:
**❌ 没有它(每次都从头认识你)**
```text
你 :帮我改简历
AI :好的,先了解一下你——你是做什么方向的?
常用哪些技术栈?想投什么岗位?偏好什么写作风格?
你 :(又要把背景、技术栈、风格偏好从头敲一遍……)
```
**✅ 有了它(一句话,AI 秒懂你是谁)**
```text
你 :先调用 who_am_i 了解我,然后帮我改简历
AI :〔调用 who_am_i〕
好的,已了解你的背景(LLM 预训练 / 长文本 / 分布式)、
偏好(中文、先定风格再动手)和写作习惯。
基于这些,我把「书籍数据 SFT」项目改写得更突出你的贡献……
```
> 差别就在于:上下文只需**存一次**,之后每个新 AI、每个新对话都直接读,不用再自我介绍。
### 💡 核心理念
| | 说明 |
|---|---|
| 📦 **数据与服务分离** | 你的资料是 `context/` 下的纯 markdown,放在你自己的 git 仓库里;server 只是薄薄一层,随时可换、可拔。 |
| ☁️ **永久留存、不吃算力** | 跟 GPU 无关。数据放 GitHub 永久免费,server 本地跑、断网可用。哪天没有任何服务器,光靠这个 git 仓库你依然拥有全部资料。 |
| 🔐 **分层可见(tier)** | `public ⊂ recruiter ⊂ friend ⊂ private`。同一份资料,陌生人 / 招聘方 / 朋友 / 自己看到的范围不同。 |
### 📁 目录结构
```
personal-context-mcp/
├── server.py # 🔌 MCP server(stdio)
├── context/ # ★ 数据层:你的资料,改这里
│ ├── style.md # 🎨 风格习惯
│ ├── preferences.md # ⚙️ 偏好设置
│ ├── skills.md # 🧰 用过的 skill
│ ├── background.md # 📖 人生背景(可公开)
│ └── private.md # 🔒 私密信息(gitignore,仅本地 tier=private 可见)
├── ingest/import_file.py # 📄 简历/文件 → 纯文本(供 AI 解析)
└── pyproject.toml
```
### 🚀 快速开始
```bash
# 1) 装依赖(mcp / pyyaml / pypdf / python-docx)
cd personal-context-mcp
uv sync
# 2) 本地可视化调试(打开 MCP Inspector,逐个点工具试)
uv run mcp dev server.py
# 3) 接入 Claude Code / Cursor
uv run mcp install server.py --name personal-context
```
或手动在 AI 的 MCP 配置里加一段(注意换成**绝对路径**):
```json
{
"mcpServers": {
"personal-context": {
"command": "uv",
"args": ["--directory", "/绝对路径/personal-context-mcp", "run", "python", "server.py"]
}
}
}
```
接入后,对 AI 说一句 **「调用 who_am_i 了解我」** 就行 ✅
### 🔄 它是怎么工作的
```mermaid
flowchart LR
A["📝 context/*.md<br/>你的资料"] --> B["🔌 MCP Server<br/>server.py (stdio)"]
B -->|"who_am_i / search…"| C["🤖 任意 AI<br/>Claude / Cursor…"]
C -->|"save_context 写回"| A
D["📄 简历 / 文件"] -->|"extract_file"| C
```
### 🧰 提供的工具
| 工具 | 作用 |
|---|---|
| 🙋 `who_am_i(viewer_tier)` | 一次性返回该 tier 下全部可见内容,换新 AI 时用它「一键认识你」 |
| 📋 `list_context(viewer_tier)` | 列出所有板块 |
| 📖 `get_context(slug, viewer_tier)` | 读某个板块全文 |
| 🔍 `search_context(query, viewer_tier)` | 关键词搜索 |
| 💾 `save_context(slug, title, body, tier, tags)` | 写入/更新板块(AI 整理完经历后存回来) |
| 📄 `extract_file(path)` | 抽取 pdf/docx/txt/md 文本,供 AI 解析简历 |
### 📄 上传简历 / 文件,自动整理进知识库
不用写死解析逻辑 —— 让 AI 来做:
1. 让 AI `extract_file("我的简历.pdf")` 拿到纯文本;
2. AI 解析、优化成结构化内容;
3. AI `save_context(slug="background", …)` 写回 `context/`。
> 命令行也能单独抽文本:`uv run python ingest/import_file.py 我的简历.pdf`
### 🧪 测试
核心逻辑(tier 权限过滤、搜索、写回、非法 slug 拦截)都有单测:
```bash
uv run pytest # 或 .venv/bin/python -m pytest
```
### 🔐 分层可见(tier)
每个 `.md` 头部的 `tier` 字段决定谁能看到:
```
public ⊂ recruiter ⊂ friend ⊂ private
陌生人 招聘方 朋友 只有自己
```
调用时传 `viewer_tier`,server 只返回该层级**及以下**的内容。私密信息(如内网路径、身份细节)建议单独放 `context/private.md` 并加进 `.gitignore`,这样它**永不进入 GitHub**,只在本地 `tier=private` 时可见。
### ☁️ 留存到 GitHub
```bash
cd personal-context-mcp
git add . && git commit -m "update my context"
git push
```
> 💡 `context/private.md` 已在 `.gitignore` 里;其余板块默认可公开。若想全部私有,直接用**私有仓库**即可。
<!-- EN_APPEND_MARK -->
---
## 🇬🇧 English
### ✨ What is this
Every time you switch to a new AI or open a fresh chat, you re-explain *who you are, what style you like, what you've built*. 😮💨
`personal-context-mcp` stores all of that as **markdown** and exposes it through the **Model Context Protocol (MCP)**. Any MCP-capable AI (Claude Code, Claude Desktop, Cursor…) plugs in, calls `who_am_i` once, and instantly *knows you* — no more re-onboarding.
> 📦 One data source, plug in anytime · ☁️ Free forever on GitHub · 🔌 Local stdio, zero hosting · 🔐 Tiered visibility
### ⏱️ See it in 30 seconds
Same prompt — "help me polish my resume" — a world of difference before vs. after:
**❌ Without it (re-onboarding every time)**
```text
You : Help me polish my resume.
AI : Sure — first, what field are you in? Which tech stack do you
use? What roles are you targeting? Any writing-style preferences?
You : (typing out my background, stack and style preferences… again.)
```
**✅ With it (one line, and the AI just knows you)**
```text
You : Call who_am_i to learn about me, then polish my resume.
AI : 〔calls who_am_i〕
Got it — I know your background (LLM pretraining / long-context /
distributed), your preferences and writing style. Based on that,
I've rewritten the "book-data SFT" project to highlight your impact…
```
> The point: store your context **once**, and every new AI and every new chat reads it directly — no more self-introductions.
### 💡 Core ideas
| | |
|---|---|
| 📦 **Data ≠ server** | Your data is plain markdown under `context/`, living in your own git repo. The server is a thin, swappable layer. |
| ☁️ **Permanent, compute-free** | No GPU involved. Data lives on GitHub for free; the server runs locally and works offline. Even with no server anywhere, the git repo alone keeps all your data. |
| 🔐 **Tiered visibility** | `public ⊂ recruiter ⊂ friend ⊂ private`. Strangers / recruiters / friends / you each see a different slice of the same data. |
### 📁 Layout
```
personal-context-mcp/
├── server.py # 🔌 MCP server (stdio)
├── context/ # ★ data layer — edit these
│ ├── style.md # 🎨 style & habits
│ ├── preferences.md # ⚙️ preferences
│ ├── skills.md # 🧰 skills used
│ ├── background.md # 📖 background (public-safe)
│ └── private.md # 🔒 private (gitignored, tier=private only)
├── ingest/import_file.py # 📄 resume/file → plain text (for the AI to parse)
└── pyproject.toml
```
### 🚀 Quick start
```bash
# 1) install deps
cd personal-context-mcp
uv sync
# 2) local visual debugging (MCP Inspector)
uv run mcp dev server.py
# 3) install into Claude Code / Cursor
uv run mcp install server.py --name personal-context
```
Or add this to your AI's MCP config (use an **absolute path**):
```json
{
"mcpServers": {
"personal-context": {
"command": "uv",
"args": ["--directory", "/abs/path/personal-context-mcp", "run", "python", "server.py"]
}
}
}
```
Then just tell the AI: **"Call who_am_i to learn about me."** ✅
### 🧰 Tools
| Tool | Purpose |
|---|---|
| 🙋 `who_am_i(viewer_tier)` | Return everything visible at that tier in one shot — "know me instantly" |
| 📋 `list_context(viewer_tier)` | List all sections |
| 📖 `get_context(slug, viewer_tier)` | Read one section |
| 🔍 `search_context(query, viewer_tier)` | Keyword search |
| 💾 `save_context(slug, title, body, tier, tags)` | Write/update a section |
| 📄 `extract_file(path)` | Extract text from pdf/docx/txt/md for the AI to parse |
### 📄 Import a resume, let the AI organize it
No hard-coded parsing — let the AI do it:
1. AI calls `extract_file("resume.pdf")` to get plain text;
2. AI parses and structures it;
3. AI calls `save_context(slug="background", …)` to write it back.
> CLI also works: `uv run python ingest/import_file.py resume.pdf`
### 🧪 Tests
The core logic (tier filtering, search, write-back, illegal-slug rejection) is covered by unit tests:
```bash
uv run pytest # or: .venv/bin/python -m pytest
```
### 🔐 Tiered visibility
The `tier` field in each `.md` front-matter controls who sees it. The server returns only content at or below the requested `viewer_tier`. Keep private data (internal paths, identity details) in `context/private.md` and gitignore it — it **never** reaches GitHub and shows only at local `tier=private`.
### ☁️ Persist to GitHub
```bash
git add . && git commit -m "update my context"
git push
```
<div align="center">
---
Made with 🧠 by [KrystalJin1](https://github.com/KrystalJin1) · MIT License
</div>
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: list_context shows board titles, get_context retrieves full content, search_context searches, who_am_i returns a compiled self-introduction, save_context writes/updates, and extract_file extracts text from files. No overlap.
All tools use snake_case and follow a verb_noun pattern (list_context, get_context, search_context, save_context, extract_file), with who_am_i being a minor but acceptable variant. Very consistent.
6 tools is well-scoped for a personal context server. It covers reading, writing, searching, file ingestion, and a summary tool without being too few or too many.
The tool set covers listing, reading, searching, creating/updating, and file extraction. A delete tool is missing, but the domain (personal context boards) may not require it. Minor gap, otherwise complete.