Spaces:
Running
Running
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
- .gitignore +14 -0
- README.md +31 -4
- pyproject.toml +2 -0
- server.py +51 -18
- 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. **
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
├──
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
mcp = FastMCP("tatva-sumit")
|
| 12 |
|
| 13 |
BASE_URL = "https://tatva.sumityadav.com.np"
|
| 14 |
|
| 15 |
-
#
|
| 16 |
-
|
|
|
|
| 17 |
|
| 18 |
-
def
|
| 19 |
-
"""
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
)
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 =
|
| 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 =
|
| 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]]
|