mcp-sqlite-memory-bank 0.1.1__py3-none-any.whl → 1.1.0__py3-none-any.whl
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.
- mcp_sqlite_memory_bank/__init__.py +19 -16
- mcp_sqlite_memory_bank/server.py +296 -197
- mcp_sqlite_memory_bank/types.py +6 -2
- mcp_sqlite_memory_bank/utils.py +21 -11
- {mcp_sqlite_memory_bank-0.1.1.dist-info → mcp_sqlite_memory_bank-1.1.0.dist-info}/METADATA +26 -2
- mcp_sqlite_memory_bank-1.1.0.dist-info/RECORD +10 -0
- mcp_sqlite_memory_bank-0.1.1.dist-info/RECORD +0 -10
- {mcp_sqlite_memory_bank-0.1.1.dist-info → mcp_sqlite_memory_bank-1.1.0.dist-info}/WHEEL +0 -0
- {mcp_sqlite_memory_bank-0.1.1.dist-info → mcp_sqlite_memory_bank-1.1.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_sqlite_memory_bank-0.1.1.dist-info → mcp_sqlite_memory_bank-1.1.0.dist-info}/top_level.txt +0 -0
mcp_sqlite_memory_bank/types.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
"""
|
2
2
|
Type definitions for SQLite Memory Bank.
|
3
3
|
|
4
|
-
This module contains type definitions and custom error classes used throughout
|
5
|
-
Designed for explicit, discoverable use by LLMs and FastMCP clients.
|
4
|
+
This module contains type definitions and custom error classes used throughout
|
5
|
+
the project. Designed for explicit, discoverable use by LLMs and FastMCP clients.
|
6
6
|
"""
|
7
7
|
|
8
8
|
from typing import TypedDict, Dict, Any, Literal, List, Union, Optional
|
@@ -49,24 +49,28 @@ class MemoryBankError(Exception):
|
|
49
49
|
|
50
50
|
class ValidationError(MemoryBankError):
|
51
51
|
"""Error for invalid inputs (table names, column names, data types, etc)."""
|
52
|
+
|
52
53
|
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
53
54
|
super().__init__(message, ErrorCategory.VALIDATION, details)
|
54
55
|
|
55
56
|
|
56
57
|
class DatabaseError(MemoryBankError):
|
57
58
|
"""Error for SQLite database operations."""
|
59
|
+
|
58
60
|
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
59
61
|
super().__init__(message, ErrorCategory.DATABASE, details)
|
60
62
|
|
61
63
|
|
62
64
|
class SchemaError(MemoryBankError):
|
63
65
|
"""Error for schema-related operations (create/alter table, etc)."""
|
66
|
+
|
64
67
|
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
65
68
|
super().__init__(message, ErrorCategory.SCHEMA, details)
|
66
69
|
|
67
70
|
|
68
71
|
class DataError(MemoryBankError):
|
69
72
|
"""Error for data operations (insert/update/delete)."""
|
73
|
+
|
70
74
|
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
71
75
|
super().__init__(message, ErrorCategory.DATA, details)
|
72
76
|
|
mcp_sqlite_memory_bank/utils.py
CHANGED
@@ -15,7 +15,6 @@ from .types import (
|
|
15
15
|
ValidationError,
|
16
16
|
DatabaseError,
|
17
17
|
SchemaError,
|
18
|
-
DataError,
|
19
18
|
MemoryBankError,
|
20
19
|
ToolResponse
|
21
20
|
)
|
@@ -60,7 +59,8 @@ def validate_identifier(name: str, context: str = "identifier") -> None:
|
|
60
59
|
"""
|
61
60
|
if not bool(re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', name)):
|
62
61
|
raise ValidationError(
|
63
|
-
f"Invalid {context}: {name}. Must start with letter/underscore and
|
62
|
+
f"Invalid {context}: {name}. Must start with letter/underscore and "
|
63
|
+
f"contain only letters, numbers, underscores.",
|
64
64
|
{"invalid_name": name}
|
65
65
|
)
|
66
66
|
|
@@ -110,7 +110,10 @@ def get_table_columns(conn: sqlite3.Connection, table_name: str) -> List[str]:
|
|
110
110
|
return columns
|
111
111
|
|
112
112
|
# Compatibility function for direct table_name usage
|
113
|
-
|
113
|
+
|
114
|
+
|
115
|
+
def get_table_columns_by_name(
|
116
|
+
table_name: str) -> Union[List[str], Dict[str, Any]]:
|
114
117
|
"""
|
115
118
|
Get list of column names for a table by name.
|
116
119
|
Compatibility function for the old implementation.
|
@@ -130,8 +133,10 @@ def get_table_columns_by_name(table_name: str) -> Union[List[str], Dict[str, Any
|
|
130
133
|
(table_name,)
|
131
134
|
)
|
132
135
|
if not cur.fetchone():
|
133
|
-
return {
|
134
|
-
|
136
|
+
return {
|
137
|
+
"success": False,
|
138
|
+
"error": f"Table '{table_name}' does not exist"}
|
139
|
+
|
135
140
|
# Get column information
|
136
141
|
cur.execute(f"PRAGMA table_info({table_name})")
|
137
142
|
columns = [col[1] for col in cur.fetchall()]
|
@@ -139,7 +144,9 @@ def get_table_columns_by_name(table_name: str) -> Union[List[str], Dict[str, Any
|
|
139
144
|
except MemoryBankError as e:
|
140
145
|
return e.to_dict()
|
141
146
|
except Exception as e:
|
142
|
-
return {
|
147
|
+
return {
|
148
|
+
"success": False,
|
149
|
+
"error": f"Exception in get_table_columns: {e}"}
|
143
150
|
|
144
151
|
|
145
152
|
def validate_table_exists(conn: sqlite3.Connection, table_name: str) -> None:
|
@@ -163,10 +170,11 @@ def validate_table_exists(conn: sqlite3.Connection, table_name: str) -> None:
|
|
163
170
|
)
|
164
171
|
|
165
172
|
|
166
|
-
def build_where_clause(
|
173
|
+
def build_where_clause(
|
174
|
+
where: Dict[str, Any], valid_columns: List[str]) -> Union[Tuple[str, list], Dict[str, Any]]:
|
167
175
|
"""
|
168
176
|
Build a WHERE clause from a dictionary of column-value pairs.
|
169
|
-
|
177
|
+
|
170
178
|
Args:
|
171
179
|
where: Dictionary of {column: value} pairs
|
172
180
|
valid_columns: List of valid column names for validation
|
@@ -181,13 +189,15 @@ def build_where_clause(where: Dict[str, Any], valid_columns: List[str]) -> Union
|
|
181
189
|
# Validate column names
|
182
190
|
conditions = []
|
183
191
|
values = []
|
184
|
-
|
192
|
+
|
185
193
|
for col, val in where.items():
|
186
194
|
if col not in valid_columns:
|
187
|
-
return {
|
195
|
+
return {
|
196
|
+
"success": False,
|
197
|
+
"error": f"Invalid column in where clause: {col}"}
|
188
198
|
conditions.append(f"{col}=?")
|
189
199
|
values.append(val)
|
190
|
-
|
200
|
+
|
191
201
|
clause = ' AND '.join(conditions)
|
192
202
|
return clause, values
|
193
203
|
except Exception as e:
|
@@ -1,8 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp_sqlite_memory_bank
|
3
|
-
Version:
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: A dynamic, agent/LLM-friendly SQLite memory bank for MCP servers.
|
5
|
-
Author-email: Robert Meisner <
|
5
|
+
Author-email: Robert Meisner <robert@catchit.pl>
|
6
6
|
License-Expression: MIT
|
7
7
|
Project-URL: Homepage, https://github.com/robertmeisner/mcp_sqlite_memory_bank
|
8
8
|
Project-URL: Source, https://github.com/robertmeisner/mcp_sqlite_memory_bank
|
@@ -19,6 +19,30 @@ Provides-Extra: test
|
|
19
19
|
Requires-Dist: pytest; extra == "test"
|
20
20
|
Dynamic: license-file
|
21
21
|
|
22
|
+
## Development Setup
|
23
|
+
|
24
|
+
To ensure code quality and consistent style, this project uses `flake8` and `pre-commit` hooks.
|
25
|
+
|
26
|
+
**Install development dependencies:**
|
27
|
+
|
28
|
+
```sh
|
29
|
+
pip install -r requirements.txt
|
30
|
+
```
|
31
|
+
|
32
|
+
**Enable pre-commit hooks (recommended):**
|
33
|
+
|
34
|
+
```sh
|
35
|
+
pre-commit install
|
36
|
+
```
|
37
|
+
|
38
|
+
This will automatically run `flake8` on staged files before every commit. To manually check all files:
|
39
|
+
|
40
|
+
```sh
|
41
|
+
pre-commit run --all-files
|
42
|
+
```
|
43
|
+
|
44
|
+
If you see lint errors, fix them before committing. You can configure linting rules in the `.flake8` file.
|
45
|
+
|
22
46
|
# mcp_sqlite_memory_bank
|
23
47
|
|
24
48
|

|
@@ -0,0 +1,10 @@
|
|
1
|
+
mcp_sqlite_memory_bank/__init__.py,sha256=l2045g6NL0NYoX0zMUjL5gDJHb4rI3l3gNUOYeACyBU,2293
|
2
|
+
mcp_sqlite_memory_bank/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
mcp_sqlite_memory_bank/server.py,sha256=zC8hrDwmBKJdVG4YFD2fzddQuTgIcQorFB4W5YyqICk,38325
|
4
|
+
mcp_sqlite_memory_bank/types.py,sha256=86xN1bv-WaIu_Oz1_RFjRP7wsZdc6CHL_ntCGqn0eDI,4439
|
5
|
+
mcp_sqlite_memory_bank/utils.py,sha256=YHUFbZL0AJ0jjQnlQSVYJpBi4Bmeu7M-7tcyS82gxts,6574
|
6
|
+
mcp_sqlite_memory_bank-1.1.0.dist-info/licenses/LICENSE,sha256=KPr7eFgCJqQIjeSAcwRafbjcgm-10zkrJ7MFoTOGJQg,1092
|
7
|
+
mcp_sqlite_memory_bank-1.1.0.dist-info/METADATA,sha256=jnnHoRb-7aM562XCtA7LVpqSnr3urlp1OGsW60n9Kg0,23617
|
8
|
+
mcp_sqlite_memory_bank-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
+
mcp_sqlite_memory_bank-1.1.0.dist-info/top_level.txt,sha256=xQ8MTGECpWMR-9DV4H8mMqaSoZqE-C8EvpOg9E2U1wM,23
|
10
|
+
mcp_sqlite_memory_bank-1.1.0.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
mcp_sqlite_memory_bank/__init__.py,sha256=HnroBjHNJqCQ3kqaHgfYrZhHipSmNFWpAIYH2or0fi0,2322
|
2
|
-
mcp_sqlite_memory_bank/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
mcp_sqlite_memory_bank/server.py,sha256=kbdpF8axXj7X2Rj7NwDiGIAjOluZ-1d5uJHcuyoxksU,37839
|
4
|
-
mcp_sqlite_memory_bank/types.py,sha256=gGteXWPKMKkOLlSe3CEpqEm-X-rEePCwfbXUaoY4YYU,4431
|
5
|
-
mcp_sqlite_memory_bank/utils.py,sha256=dkgx7-GHruZhzWemOWXgUpZwD_UZo_a7a7zP9bB5YXU,6476
|
6
|
-
mcp_sqlite_memory_bank-0.1.1.dist-info/licenses/LICENSE,sha256=KPr7eFgCJqQIjeSAcwRafbjcgm-10zkrJ7MFoTOGJQg,1092
|
7
|
-
mcp_sqlite_memory_bank-0.1.1.dist-info/METADATA,sha256=3ApIfPLvwaCrgFIy8ENr0cwCPzgSNvcsQ8BxlvZYE5o,23073
|
8
|
-
mcp_sqlite_memory_bank-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
-
mcp_sqlite_memory_bank-0.1.1.dist-info/top_level.txt,sha256=xQ8MTGECpWMR-9DV4H8mMqaSoZqE-C8EvpOg9E2U1wM,23
|
10
|
-
mcp_sqlite_memory_bank-0.1.1.dist-info/RECORD,,
|
File without changes
|
{mcp_sqlite_memory_bank-0.1.1.dist-info → mcp_sqlite_memory_bank-1.1.0.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{mcp_sqlite_memory_bank-0.1.1.dist-info → mcp_sqlite_memory_bank-1.1.0.dist-info}/top_level.txt
RENAMED
File without changes
|