pocket-notes 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: pocket-notes
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local notes MCP server for Claude and Codex.
|
|
5
|
+
Author: Chen Ting
|
|
6
|
+
Author-email: Chen Ting <c.tingkuo216@gmail.com>
|
|
7
|
+
Requires-Dist: fastmcp>=4.1.3
|
|
8
|
+
Requires-Python: >=3.12
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# Pocket Notes
|
|
12
|
+
|
|
13
|
+
A simple local note-taking MCP server built with Python and FastMCP.
|
|
14
|
+
Save and search notes through an MCP-compatible client.
|
|
15
|
+
|
|
16
|
+
## Tools
|
|
17
|
+
|
|
18
|
+
- `save_note(content)`: Save a note to the local database.
|
|
19
|
+
- `search_notes(keyword)`: Search notes by keyword and return up to the 20 most recent matches.
|
|
20
|
+
- `greet(name)`: Return a greeting to test the connection.
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- Python 3.12 or later
|
|
25
|
+
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
26
|
+
- Codex CLI for the setup below
|
|
27
|
+
|
|
28
|
+
## Connect to Codex
|
|
29
|
+
|
|
30
|
+
Register the MCP server:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
codex mcp add pocket-notes -- uvx pocket-notes
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Start a new Codex session to use the tools.
|
|
37
|
+
|
|
38
|
+
## Data Storage
|
|
39
|
+
|
|
40
|
+
Notes are stored in a local SQLite database:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
~/.pocket-notes/notes.db
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Here, `~` refers to your home directory.
|
|
47
|
+
|
|
48
|
+
MCP clients running under the same user account on the same computer can share this database.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Pocket Notes
|
|
2
|
+
|
|
3
|
+
A simple local note-taking MCP server built with Python and FastMCP.
|
|
4
|
+
Save and search notes through an MCP-compatible client.
|
|
5
|
+
|
|
6
|
+
## Tools
|
|
7
|
+
|
|
8
|
+
- `save_note(content)`: Save a note to the local database.
|
|
9
|
+
- `search_notes(keyword)`: Search notes by keyword and return up to the 20 most recent matches.
|
|
10
|
+
- `greet(name)`: Return a greeting to test the connection.
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- Python 3.12 or later
|
|
15
|
+
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
16
|
+
- Codex CLI for the setup below
|
|
17
|
+
|
|
18
|
+
## Connect to Codex
|
|
19
|
+
|
|
20
|
+
Register the MCP server:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
codex mcp add pocket-notes -- uvx pocket-notes
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Start a new Codex session to use the tools.
|
|
27
|
+
|
|
28
|
+
## Data Storage
|
|
29
|
+
|
|
30
|
+
Notes are stored in a local SQLite database:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
~/.pocket-notes/notes.db
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Here, `~` refers to your home directory.
|
|
37
|
+
|
|
38
|
+
MCP clients running under the same user account on the same computer can share this database.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pocket-notes"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A local notes MCP server for Claude and Codex."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Chen Ting", email = "c.tingkuo216@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"fastmcp>=4.1.3",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[project.scripts]
|
|
15
|
+
pocket-notes = "pocket_notes.server:main"
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
19
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from contextlib import closing
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import sqlite3
|
|
4
|
+
|
|
5
|
+
from fastmcp import FastMCP
|
|
6
|
+
|
|
7
|
+
mcp = FastMCP("Pocket Notes")
|
|
8
|
+
DB_PATH = Path.home() / ".pocket-notes" / "notes.db"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@mcp.tool
|
|
12
|
+
def greet(name: str) -> str:
|
|
13
|
+
return f"Hello, {name}!"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@mcp.tool
|
|
17
|
+
def save_note(content: str) -> dict:
|
|
18
|
+
"""save this note to local for further use"""
|
|
19
|
+
content = content.strip()
|
|
20
|
+
if not content:
|
|
21
|
+
raise ValueError("Note can't be empty!")
|
|
22
|
+
|
|
23
|
+
DB_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
|
|
25
|
+
with closing(sqlite3.connect(DB_PATH)) as conn:
|
|
26
|
+
conn.execute(
|
|
27
|
+
"CREATE TABLE IF NOT EXISTS notes "
|
|
28
|
+
"(id INTEGER PRIMARY KEY, content TEXT NOT NULL)"
|
|
29
|
+
)
|
|
30
|
+
cursor = conn.execute(
|
|
31
|
+
"INSERT INTO notes (content) VALUES (?)", (content,)
|
|
32
|
+
)
|
|
33
|
+
conn.commit()
|
|
34
|
+
return {"id": cursor.lastrowid, "content": content}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@mcp.tool
|
|
38
|
+
def search_notes(keyword: str) -> list[dict]:
|
|
39
|
+
"""Use keywords to search local notes, return up to the most recent 20 notes"""
|
|
40
|
+
keyword = keyword.strip()
|
|
41
|
+
if not keyword:
|
|
42
|
+
raise ValueError("Search keyword can't be empty!")
|
|
43
|
+
|
|
44
|
+
if not DB_PATH.exists():
|
|
45
|
+
return []
|
|
46
|
+
|
|
47
|
+
with closing(sqlite3.connect(DB_PATH)) as conn:
|
|
48
|
+
conn.row_factory = sqlite3.Row
|
|
49
|
+
rows = conn.execute(
|
|
50
|
+
"SELECT id, content FROM notes "
|
|
51
|
+
"WHERE content LIKE ? "
|
|
52
|
+
"ORDER BY id DESC LIMIT 20",
|
|
53
|
+
(f"%{keyword}%",),
|
|
54
|
+
).fetchall()
|
|
55
|
+
return [dict(row) for row in rows]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> None:
|
|
59
|
+
mcp.run(transport="stdio")
|