sumitasthaai commited on
Commit
8f3faab
·
unverified ·
1 Parent(s): ed7c1bd

Add Turso database integration and environment variable support

Browse files

- Add put_task_to_db and get_task_from_db tools for task management
- Integrate Turso (libSQL) database for persistent storage
- Add python-dotenv for automatic .env file loading
- Update README with database tools documentation
- Update .gitignore to exclude .env and database files
- Remove unused test files

Files changed (5) hide show
  1. .gitignore +14 -0
  2. README.md +31 -4
  3. pyproject.toml +2 -0
  4. server.py +51 -18
  5. uv.lock +17 -0
.gitignore CHANGED
@@ -8,3 +8,17 @@ wheels/
8
 
9
  # Virtual environments
10
  .venv
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  # Virtual environments
10
  .venv
11
+
12
+ # Environment variables
13
+ .env
14
+ .env.local
15
+
16
+ # Database files (using Turso, not local SQLite)
17
+ *.db
18
+ *.sqlite
19
+ *.sqlite3
20
+
21
+ # Python cache
22
+ __pycache__/
23
+ *.pyc
24
+ *.pyo
README.md CHANGED
@@ -36,10 +36,12 @@ A Model Context Protocol (MCP) server that provides intelligent access to conten
36
  - **Content Fetching**: Retrieve content from any page on the Tatva website
37
  - **Blog Post Management**: Access and search through all blog posts
38
  - **Smart Search**: Find posts by keywords or filter by year
 
39
  - **Resource Access**: Direct access to homepage, about page, and specific posts
40
  - **Analysis Tools**: Built-in prompts for post analysis and comparison
41
  - **Docker Support**: Easy deployment with containerization
42
  - **Hugging Face Spaces Ready**: Optimized for HF Spaces deployment
 
43
 
44
  ## 🛠️ Available Tools
45
 
@@ -54,6 +56,10 @@ A Model Context Protocol (MCP) server that provides intelligent access to conten
54
  - `search_posts_by_keyword(keyword)` - Search posts by keyword
55
  - `get_posts_by_year(year)` - Filter posts by publication year
56
 
 
 
 
 
57
  ### Resources
58
  - `tatva://homepage` - Homepage resource
59
  - `tatva://about` - About page resource
@@ -82,7 +88,18 @@ A Model Context Protocol (MCP) server that provides intelligent access to conten
82
  uv sync
83
  ```
84
 
85
- 3. **Run the server**
 
 
 
 
 
 
 
 
 
 
 
86
  ```bash
87
  uv run server.py
88
  ```
@@ -123,10 +140,11 @@ The server exposes MCP tools that can be used by compatible AI assistants and cl
123
  ```
124
  sumit-mcp-server/
125
  ├── server.py # Main MCP server implementation
126
- ├── main.py # Entry point
127
- ├── pyproject.toml # Project configuration
128
  ├── Dockerfile # Container configuration
129
  ├── README.md # This file
 
 
130
  └── uv.lock # Dependency lock file
131
  ```
132
 
@@ -147,7 +165,14 @@ This server is optimized for deployment on Hugging Face Spaces:
147
  - Supports SSE transport for real-time communication
148
 
149
  ### Environment Variables
150
- - `PORT`: Server port (default: 7860)
 
 
 
 
 
 
 
151
 
152
  ## 📝 API Reference
153
 
@@ -162,6 +187,8 @@ This server is optimized for deployment on Hugging Face Spaces:
162
  | `get_all_posts_summary` | List all posts | None |
163
  | `search_posts_by_keyword` | Search posts | `keyword: str` |
164
  | `get_posts_by_year` | Filter by year | `year: str` |
 
 
165
 
166
  ### Resources
167
 
 
36
  - **Content Fetching**: Retrieve content from any page on the Tatva website
37
  - **Blog Post Management**: Access and search through all blog posts
38
  - **Smart Search**: Find posts by keywords or filter by year
39
+ - **Task Management**: Store and retrieve tasks using Turso (libSQL) database
40
  - **Resource Access**: Direct access to homepage, about page, and specific posts
41
  - **Analysis Tools**: Built-in prompts for post analysis and comparison
42
  - **Docker Support**: Easy deployment with containerization
43
  - **Hugging Face Spaces Ready**: Optimized for HF Spaces deployment
44
+ - **Environment Configuration**: Automatic loading of environment variables from `.env` file
45
 
46
  ## 🛠️ Available Tools
47
 
 
56
  - `search_posts_by_keyword(keyword)` - Search posts by keyword
57
  - `get_posts_by_year(year)` - Filter posts by publication year
58
 
59
+ ### Task Management
60
+ - `put_task_to_db(task, time_date)` - Add a task to the database with date and time
61
+ - `get_task_from_db(today_date)` - Retrieve all tasks for a specific date
62
+
63
  ### Resources
64
  - `tatva://homepage` - Homepage resource
65
  - `tatva://about` - About page resource
 
88
  uv sync
89
  ```
90
 
91
+ 3. **Configure environment variables**
92
+
93
+ Create a `.env` file in the project root with your Turso credentials:
94
+ ```bash
95
+ TURSO_AUTH_TOKEN=your_turso_auth_token
96
+ TURSO_DATABASE_URL=your_turso_database_url
97
+ PORT=7860
98
+ ```
99
+
100
+ The server will automatically load these from the `.env` file.
101
+
102
+ 4. **Run the server**
103
  ```bash
104
  uv run server.py
105
  ```
 
140
  ```
141
  sumit-mcp-server/
142
  ├── server.py # Main MCP server implementation
143
+ ├── pyproject.toml # Project configuration and dependencies
 
144
  ├── Dockerfile # Container configuration
145
  ├── README.md # This file
146
+ ├── .env # Environment variables (create with your Turso credentials)
147
+ ├── .gitignore # Git ignore rules
148
  └── uv.lock # Dependency lock file
149
  ```
150
 
 
165
  - Supports SSE transport for real-time communication
166
 
167
  ### Environment Variables
168
+
169
+ The server automatically loads environment variables from a `.env` file in the project root. Create a `.env` file with:
170
+
171
+ - `TURSO_AUTH_TOKEN`: Authentication token for Turso database (required)
172
+ - `TURSO_DATABASE_URL`: Database URL for Turso (libSQL) connection (required)
173
+ - `PORT`: Server port (default: 7860, optional)
174
+
175
+ **Note**: The `.env` file is automatically ignored by git to keep your credentials secure. You can also set these as system environment variables if preferred.
176
 
177
  ## 📝 API Reference
178
 
 
187
  | `get_all_posts_summary` | List all posts | None |
188
  | `search_posts_by_keyword` | Search posts | `keyword: str` |
189
  | `get_posts_by_year` | Filter by year | `year: str` |
190
+ | `put_task_to_db` | Add task to database | `task: str`, `time_date: str` |
191
+ | `get_task_from_db` | Get tasks for date | `today_date: str` |
192
 
193
  ### Resources
194
 
pyproject.toml CHANGED
@@ -7,4 +7,6 @@ requires-python = ">=3.13"
7
  dependencies = [
8
  "bs4>=0.0.2",
9
  "fastmcp>=2.12.4",
 
 
10
  ]
 
7
  dependencies = [
8
  "bs4>=0.0.2",
9
  "fastmcp>=2.12.4",
10
+ "libsql>=0.1.0",
11
+ "python-dotenv>=1.0.0",
12
  ]
server.py CHANGED
@@ -6,29 +6,62 @@ from bs4 import BeautifulSoup
6
  from urllib.parse import urljoin, urlparse
7
  import json
8
  from typing import List, Dict, Optional, Any
9
- import sqlite3
 
 
 
 
10
 
11
  mcp = FastMCP("tatva-sumit")
12
 
13
  BASE_URL = "https://tatva.sumityadav.com.np"
14
 
15
- # SQLite database setup
16
- DB_PATH = "tasks.db"
 
17
 
18
- def init_db():
19
- """Initialize the SQLite database and create tasks table if it doesn't exist"""
20
- conn = sqlite3.connect(DB_PATH)
21
- cursor = conn.cursor()
22
- cursor.execute("""
23
- CREATE TABLE IF NOT EXISTS tasks (
24
- id INTEGER PRIMARY KEY AUTOINCREMENT,
25
- task TEXT NOT NULL,
26
- time_date TEXT NOT NULL,
27
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
28
  )
29
- """)
30
- conn.commit()
31
- conn.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  # Initialize database on module load
34
  init_db()
@@ -179,7 +212,7 @@ def put_task_to_db(task: str, time_date: str) -> Dict[str, Any]:
179
  A dictionary with status and the inserted task information
180
  """
181
  try:
182
- conn = sqlite3.connect(DB_PATH)
183
  cursor = conn.cursor()
184
  cursor.execute("""
185
  INSERT INTO tasks (task, time_date)
@@ -213,7 +246,7 @@ def get_task_from_db(today_date: str) -> List[Dict[str, Any]]:
213
  A list of dictionaries containing all tasks for the specified date
214
  """
215
  try:
216
- conn = sqlite3.connect(DB_PATH)
217
  cursor = conn.cursor()
218
  # Query tasks where time_date starts with the given date
219
  cursor.execute("""
 
6
  from urllib.parse import urljoin, urlparse
7
  import json
8
  from typing import List, Dict, Optional, Any
9
+ import libsql
10
+ from dotenv import load_dotenv
11
+
12
+ # Load environment variables from .env file
13
+ load_dotenv()
14
 
15
  mcp = FastMCP("tatva-sumit")
16
 
17
  BASE_URL = "https://tatva.sumityadav.com.np"
18
 
19
+ # Turso database setup
20
+ TURSO_AUTH_TOKEN = os.environ.get("TURSO_AUTH_TOKEN")
21
+ TURSO_DATABASE_URL = os.environ.get("TURSO_DATABASE_URL")
22
 
23
+ def get_db_connection():
24
+ """Get a Turso/libSQL database connection"""
25
+ if not TURSO_AUTH_TOKEN or not TURSO_DATABASE_URL:
26
+ raise ValueError("TURSO_AUTH_TOKEN and TURSO_DATABASE_URL must be set in environment variables")
27
+
28
+ try:
29
+ # Try the newer API first
30
+ return libsql.connect(
31
+ database=TURSO_DATABASE_URL,
32
+ auth_token=TURSO_AUTH_TOKEN
33
  )
34
+ except TypeError:
35
+ # Fallback to older API
36
+ try:
37
+ return libsql.connect(
38
+ TURSO_DATABASE_URL,
39
+ auth_token=TURSO_AUTH_TOKEN
40
+ )
41
+ except TypeError:
42
+ # Try with sync_url parameter
43
+ return libsql.connect(
44
+ sync_url=TURSO_DATABASE_URL,
45
+ auth_token=TURSO_AUTH_TOKEN
46
+ )
47
+
48
+ def init_db():
49
+ """Initialize the Turso database and create tasks table if it doesn't exist"""
50
+ try:
51
+ conn = get_db_connection()
52
+ cursor = conn.cursor()
53
+ cursor.execute("""
54
+ CREATE TABLE IF NOT EXISTS tasks (
55
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
56
+ task TEXT NOT NULL,
57
+ time_date TEXT NOT NULL,
58
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
59
+ )
60
+ """)
61
+ conn.commit()
62
+ conn.close()
63
+ except Exception as e:
64
+ print(f"Warning: Could not initialize database: {e}")
65
 
66
  # Initialize database on module load
67
  init_db()
 
212
  A dictionary with status and the inserted task information
213
  """
214
  try:
215
+ conn = get_db_connection()
216
  cursor = conn.cursor()
217
  cursor.execute("""
218
  INSERT INTO tasks (task, time_date)
 
246
  A list of dictionaries containing all tasks for the specified date
247
  """
248
  try:
249
+ conn = get_db_connection()
250
  cursor = conn.cursor()
251
  # Query tasks where time_date starts with the given date
252
  cursor.execute("""
uv.lock CHANGED
@@ -460,6 +460,19 @@ wheels = [
460
  { url = "https://files.pythonhosted.org/packages/59/97/9b410ed8fbc6e79c1ee8b13f8777a80137d4bc189caf2c6202358e66192c/lazy_object_proxy-1.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:7601ec171c7e8584f8ff3f4e440aa2eebf93e854f04639263875b8c2971f819f", size = 26988, upload-time = "2025-08-22T13:49:57.302Z" },
461
  ]
462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  [[package]]
464
  name = "markdown-it-py"
465
  version = "4.0.0"
@@ -1010,12 +1023,16 @@ source = { virtual = "." }
1010
  dependencies = [
1011
  { name = "bs4" },
1012
  { name = "fastmcp" },
 
 
1013
  ]
1014
 
1015
  [package.metadata]
1016
  requires-dist = [
1017
  { name = "bs4", specifier = ">=0.0.2" },
1018
  { name = "fastmcp", specifier = ">=2.12.4" },
 
 
1019
  ]
1020
 
1021
  [[package]]
 
460
  { url = "https://files.pythonhosted.org/packages/59/97/9b410ed8fbc6e79c1ee8b13f8777a80137d4bc189caf2c6202358e66192c/lazy_object_proxy-1.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:7601ec171c7e8584f8ff3f4e440aa2eebf93e854f04639263875b8c2971f819f", size = 26988, upload-time = "2025-08-22T13:49:57.302Z" },
461
  ]
462
 
463
+ [[package]]
464
+ name = "libsql"
465
+ version = "0.1.11"
466
+ source = { registry = "https://pypi.org/simple" }
467
+ sdist = { url = "https://files.pythonhosted.org/packages/ff/a2/804e533104102770b42aa0698fee944dd13654652ceb3d27e08a83404bbd/libsql-0.1.11.tar.gz", hash = "sha256:101b6e60f5333434b3e6107bfe2cf24cd5d1317286ad262cb6489941abde77d4", size = 33353, upload-time = "2025-09-02T10:13:38.63Z" }
468
+ wheels = [
469
+ { url = "https://files.pythonhosted.org/packages/7c/e3/254d777f73a6ef985db2b030592a7eda45b2a2ac5042d9325937c90df9af/libsql-0.1.11-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b41c9fa8fa7bfe44f4a80a99939c5c87d11d88fdb1bad8d6f0c0ac96b5f9432", size = 4768039, upload-time = "2025-09-02T10:13:22.674Z" },
470
+ { url = "https://files.pythonhosted.org/packages/64/a5/de5dd7950bdc199b142a82b55fbc0049da0c7eb1639bb81a79a774f1654c/libsql-0.1.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8682d519c62daafba13df521b117a08a43af516f6d3c81337299275c66fda051", size = 4527338, upload-time = "2025-09-02T10:13:24.211Z" },
471
+ { url = "https://files.pythonhosted.org/packages/76/09/a36482f773943c45a6659bcb58be11ec7c1157876b908ea9eccf16c7a553/libsql-0.1.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c9ac431078a4eb82257541c764befa84782d8c5fbd1d1147e77f2906c28c444", size = 5110482, upload-time = "2025-09-02T10:13:25.669Z" },
472
+ { url = "https://files.pythonhosted.org/packages/a6/7e/8496944f42f5b91a0e0938205297fc11896f6003f92caa5c53eaa2b8440f/libsql-0.1.11-cp313-cp313-win_amd64.whl", hash = "sha256:c61f6c4a73d799e4bedc49eb9b18bc8b6574267046195963684688f6a184632b", size = 4056117, upload-time = "2025-09-02T10:13:28.806Z" },
473
+ { url = "https://files.pythonhosted.org/packages/d8/ad/cb4e9ac36693a9f3f3f9b03f2b1f0d14cf5b1b449c66be6f9ce7845cbf02/libsql-0.1.11-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7b39b90228637a4b26293af44833633c36c091276fc8b58f216dea38742f23", size = 5110968, upload-time = "2025-09-02T10:13:30.228Z" },
474
+ ]
475
+
476
  [[package]]
477
  name = "markdown-it-py"
478
  version = "4.0.0"
 
1023
  dependencies = [
1024
  { name = "bs4" },
1025
  { name = "fastmcp" },
1026
+ { name = "libsql" },
1027
+ { name = "python-dotenv" },
1028
  ]
1029
 
1030
  [package.metadata]
1031
  requires-dist = [
1032
  { name = "bs4", specifier = ">=0.0.2" },
1033
  { name = "fastmcp", specifier = ">=2.12.4" },
1034
+ { name = "libsql", specifier = ">=0.1.0" },
1035
+ { name = "python-dotenv", specifier = ">=1.0.0" },
1036
  ]
1037
 
1038
  [[package]]