wtinydb-mcp 0.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.
@@ -0,0 +1,3 @@
1
+ """wtinydb-mcp package initialization."""
2
+
3
+ __version__ = "0.1.0"
wtinydb_mcp/catalog.py ADDED
@@ -0,0 +1,59 @@
1
+ """WTinyDB Architectural Patterns Catalog."""
2
+
3
+ from typing import Dict, List, Optional
4
+
5
+
6
+ class PatternsCatalog:
7
+ """Catalog of production-ready patterns for WTinyDB document database architectures."""
8
+
9
+ PATTERNS = [
10
+ {
11
+ "id": "pydantic-crud",
12
+ "name": "Pydantic Document Repository",
13
+ "feature": "CRUD & Models",
14
+ "module": "wtinydb.core.database",
15
+ "description": "Standard repository pattern wrapping WTinyDB with Pydantic model validation.",
16
+ "origin": "wisrovi SUITE",
17
+ },
18
+ {
19
+ "id": "async-wtinydb",
20
+ "name": "Async Document Operations",
21
+ "feature": "Async / FastAPI Integration",
22
+ "module": "wtinydb.core.async_db",
23
+ "description": "Non-blocking ThreadPoolExecutor wrapper for high-throughput async APIs.",
24
+ "origin": "wisrovi SUITE",
25
+ },
26
+ {
27
+ "id": "fluent-query",
28
+ "name": "Fluent Query Builder",
29
+ "feature": "Queries & Filtering",
30
+ "module": "wtinydb.core.query",
31
+ "description": "Chainable query builder (Q) for NoSQL field matching, regex search, and list filters.",
32
+ "origin": "wisrovi SUITE",
33
+ },
34
+ {
35
+ "id": "soft-delete-audit",
36
+ "name": "Soft Delete & Audit Trailing",
37
+ "feature": "Audit & Lifecycle",
38
+ "module": "wtinydb.models",
39
+ "description": "Mixins for automatic created_at, updated_at timestamps and logical deletion.",
40
+ "origin": "wisrovi SUITE",
41
+ },
42
+ {
43
+ "id": "n-level-nested-crud",
44
+ "name": "N-Level Nested JSON CRUD",
45
+ "feature": "Nested Documents & Path Querying",
46
+ "module": "wtinydb.core.database",
47
+ "description": "Single-responsibility modular CRUD for N-level deep nested JSON objects with dotted path matching.",
48
+ "origin": "wisrovi SUITE",
49
+ },
50
+ ]
51
+
52
+ def search(self, query: str) -> List[Dict[str, str]]:
53
+ """Search patterns matching query string across name, feature, or description."""
54
+ q = query.lower()
55
+ results = []
56
+ for p in self.PATTERNS:
57
+ if q in p["name"].lower() or q in p["feature"].lower() or q in p["description"].lower():
58
+ results.append(p)
59
+ return results
wtinydb_mcp/server.py ADDED
@@ -0,0 +1,245 @@
1
+ """wtinydb-mcp: Model Context Protocol server for WTinyDB architecting and code generation."""
2
+
3
+ import argparse
4
+ import ast
5
+ import json
6
+ import logging
7
+ import os
8
+ import signal
9
+ import subprocess
10
+ import sys
11
+ from functools import lru_cache
12
+
13
+ from mcp.server.fastmcp import FastMCP
14
+
15
+ from wtinydb_mcp.catalog import PatternsCatalog
16
+ from wtinydb_mcp.templates import TemplateGenerator
17
+
18
+ # Setup logging strictly to stderr to avoid breaking MCP protocol
19
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s", stream=sys.stderr)
20
+ logger = logging.getLogger(__name__)
21
+
22
+ PID_FILE = os.path.expanduser("~/.wtinydb_mcp.pid")
23
+
24
+ # Create primary FastMCP Server instance
25
+ mcp = FastMCP("wtinydb-mcp-server")
26
+
27
+
28
+ @lru_cache(maxsize=1)
29
+ def get_catalog() -> PatternsCatalog:
30
+ """Return shared patterns catalog instance."""
31
+ return PatternsCatalog()
32
+
33
+
34
+ def _is_pydantic_model(cls: ast.ClassDef) -> bool:
35
+ """Return True if class inherits from BaseModel or Mixins."""
36
+ return any(
37
+ isinstance(b, ast.Name) and b.id in ("BaseModel", "TimestampMixin", "SoftDeleteMixin", "AuditMixin")
38
+ for b in cls.bases
39
+ )
40
+
41
+
42
+ @mcp.tool()
43
+ def validate_model_schema(model_code: str) -> str:
44
+ """Validate a Pydantic model definition for WTinyDB compatibility."""
45
+ try:
46
+ tree = ast.parse(model_code)
47
+ issues = []
48
+ warnings = []
49
+
50
+ classes = [n for n in ast.walk(tree) if isinstance(n, ast.ClassDef)]
51
+ model_classes = [c for c in classes if _is_pydantic_model(c)]
52
+
53
+ if not model_classes:
54
+ issues.append("No Pydantic BaseModel or WTinyDB Mixin subclass found.")
55
+
56
+ result = "Valid Model Validation Result:\n"
57
+ if issues:
58
+ result += "Issues:\n" + "\n".join(f" ❌ {i}" for i in issues) + "\n"
59
+ if warnings:
60
+ result += "Warnings:\n" + "\n".join(f" ⚠️ {w}" for w in warnings) + "\n"
61
+ if not issues and not warnings:
62
+ result += "✅ Model looks good for WTinyDB document storage!"
63
+ return result
64
+
65
+ except SyntaxError as e:
66
+ return f"❌ Syntax Error in model code: {e}"
67
+ except Exception as e:
68
+ return f"❌ Validation Error: {type(e).__name__}: {e}"
69
+
70
+
71
+ @mcp.tool()
72
+ def search_wtinydb_pattern(query: str) -> str:
73
+ """Search for production-ready WTinyDB architectural patterns."""
74
+ results = get_catalog().search(query)
75
+ if not results:
76
+ return f"No pattern matching '{query}' was found in WTinyDB catalog."
77
+
78
+ response = "Found production-ready architectural patterns in wisrovi SUITE:\n\n"
79
+ for p in results:
80
+ response += f"🚀 [{p['origin']}] {p['name']}\n"
81
+ response += f" - Feature: {p['feature']}\n"
82
+ response += f" - Module: {p['module']}\n"
83
+ response += f" - Description: {p['description']}\n\n"
84
+ return response
85
+
86
+
87
+ @mcp.tool()
88
+ def deploy_wtinydb_scaffolding(
89
+ target_dir: str,
90
+ project_name: str = "wtinydb_project",
91
+ scaffold_type: str = "standard",
92
+ ) -> str:
93
+ """Deploys a professional WTinyDB project structure following wisrovi standards."""
94
+ try:
95
+ if not os.path.isabs(target_dir):
96
+ return "Error: target_dir must be an absolute path."
97
+
98
+ for folder in TemplateGenerator.get_folders(scaffold_type):
99
+ os.makedirs(os.path.join(target_dir, folder), exist_ok=True)
100
+
101
+ blueprints = TemplateGenerator.get_files_blueprint(scaffold_type, project_name)
102
+ for rel_path, content in blueprints.items():
103
+ full_path = os.path.join(target_dir, rel_path)
104
+ os.makedirs(os.path.dirname(full_path), exist_ok=True)
105
+ with open(full_path, "w", encoding="utf-8") as f:
106
+ f.write(content)
107
+
108
+ return f"Success: WTinyDB architecture '{project_name}' deployed at {target_dir}"
109
+ except Exception as e:
110
+ return f"Error deploying scaffolding: {str(e)}"
111
+
112
+
113
+ @mcp.tool()
114
+ def get_wtinydb_architect_blueprints() -> str:
115
+ """Complete reference with read/write/update examples for every WTinyDB feature."""
116
+ crud_code = (
117
+ "from pydantic import BaseModel, Field\n"
118
+ "from wtinydb import WTinyDB, SoftDeleteMixin\n\n"
119
+ "class Article(SoftDeleteMixin, BaseModel):\n"
120
+ " title: str\n"
121
+ " content: str\n"
122
+ " tags: list[str] = []\n\n"
123
+ "db = WTinyDB(Article, db_path='articles.json')\n"
124
+ "# WRITE\n"
125
+ "art = db.insert(Article(title='Intro', content='Hello World'))\n"
126
+ "# READ\n"
127
+ "all_articles = db.get_all()\n"
128
+ "art1 = db.get(1)\n"
129
+ "# UPDATE\n"
130
+ "db.update(1, {'title': 'Updated Title'})\n"
131
+ "# DELETE\n"
132
+ "db.delete(1, hard=False)\n"
133
+ )
134
+
135
+ async_code = (
136
+ "import asyncio\n"
137
+ "from wtinydb import WTinyDB, AsyncWTinyDB\n\n"
138
+ "async def main():\n"
139
+ " sync_db = WTinyDB(Article, db_path='articles.json')\n"
140
+ " db = AsyncWTinyDB(sync_db)\n"
141
+ " art = await db.insert(Article(title='Async Title', content='Text'))\n"
142
+ " rows = await db.get_all()\n"
143
+ " await db.close()\n"
144
+ )
145
+
146
+ query_code = (
147
+ "from wtinydb import WTinyDB, Q\n\n"
148
+ "db = WTinyDB(Article, in_memory=True)\n"
149
+ "# Query with operators\n"
150
+ "tech_articles = db.find(Q('tags').in_list('tags', ['tech', 'python']))\n"
151
+ "regex_matches = db.find(Q('title').matches('title', r'^Intro'))\n"
152
+ )
153
+
154
+ nested_code = (
155
+ "from wtinydb import WTinyDB, Q\n\n"
156
+ "db = WTinyDB(Company, db_path='companies.json')\n"
157
+ "# N-Level Dotted Path Querying\n"
158
+ "results = db.find(Q('department.manager.contact.address.city').eq('San Francisco'))\n"
159
+ "# N-Level Deep Field Updating\n"
160
+ "db.update(target_company, {'department.budget': 7500000.00})\n"
161
+ )
162
+
163
+ return (
164
+ "WTINYDB EXPERT BLUEPRINTS (COMPLETE REFERENCE)\n\n"
165
+ "=== 1. MODEL & CRUD ===\n" + crud_code + "\n"
166
+ "=== 2. ASYNC OPERATIONS ===\n" + async_code + "\n"
167
+ "=== 3. FLUENT QUERY BUILDER ===\n" + query_code + "\n"
168
+ "=== 4. N-LEVEL NESTED JSON CRUD ===\n" + nested_code
169
+ )
170
+
171
+
172
+ @mcp.tool()
173
+ def get_wtinydb_architect_manual() -> str:
174
+ """Expert manual for building high-performance document database systems with WTinyDB."""
175
+ manual_text = (
176
+ "WTINYDB ARCHITECT MANUAL (ADVANCED)\n"
177
+ "--- PROJECT STRUCTURE RULES (MANDATORY) ---\n"
178
+ "1. CONFIG: All database settings MUST be centralized in `config/settings.py` as a `DatabaseSettings` dataclass.\n"
179
+ "2. MODELS: All Pydantic models MUST be placed inside `models/` directory.\n"
180
+ "3. REPOSITORIES: All data-access logic MUST live in `repositories/` wrapping `WTinyDB` or `AsyncWTinyDB`.\n"
181
+ "4. ORCHESTRATOR: Service entrypoint MUST be `main.py` at root level.\n\n"
182
+ "--- CORE RULES ---\n"
183
+ "1. Always use Pydantic models for schema definitions.\n"
184
+ "2. Use `SoftDeleteMixin` or `AuditMixin` for soft-deletion and automatic creation/update timestamps.\n"
185
+ "3. Use `Q` fluent query builder for complex filtering.\n"
186
+ "4. For FastAPI/async apps, wrap WTinyDB with `AsyncWTinyDB`.\n\n"
187
+ "Generated by WTinyDB MCP by wisrovi"
188
+ )
189
+ return manual_text
190
+
191
+
192
+ @mcp.tool()
193
+ def generate_wtinydb_crud(model_code: str) -> str:
194
+ """Generate repository CRUD wrapper code for a Pydantic model definition."""
195
+ try:
196
+ tree = ast.parse(model_code)
197
+ classes = [n.name for n in ast.walk(tree) if isinstance(n, ast.ClassDef) and _is_pydantic_model(n)]
198
+ if not classes:
199
+ return "# Error: No Pydantic model found in provided code."
200
+
201
+ model_name = classes[0]
202
+ repo_name = f"{model_name}Repository"
203
+
204
+ code = (
205
+ f"from typing import List, Optional\n"
206
+ f"from wtinydb import WTinyDB, Q\n"
207
+ f"# Import {model_name} from models module\n\n"
208
+ f"class {repo_name}:\n"
209
+ f" def __init__(self, db_path: str = '{model_name.lower()}.json', in_memory: bool = False):\n"
210
+ f" self.db = WTinyDB({model_name}, db_path=db_path, in_memory=in_memory)\n\n"
211
+ f" def create(self, item: {model_name}) -> {model_name}:\n"
212
+ f" return self.db.insert(item)\n\n"
213
+ f" def get_by_id(self, doc_id: int) -> {model_name}:\n"
214
+ f" return self.db.get(doc_id)\n\n"
215
+ f" def get_all(self) -> List[{model_name}]:\n"
216
+ f" return self.db.get_all()\n\n"
217
+ f" def update(self, doc_id: int, data: dict) -> {model_name}:\n"
218
+ f" return self.db.update(doc_id, data)\n\n"
219
+ f" def delete(self, doc_id: int, hard: bool = False) -> bool:\n"
220
+ f" return self.db.delete(doc_id, hard=hard)\n"
221
+ )
222
+ return code
223
+ except Exception as e:
224
+ return f"# Generation error: {e}"
225
+
226
+
227
+ def run_stdio():
228
+ """Run MCP server in stdio mode."""
229
+ mcp.run(transport="stdio")
230
+
231
+
232
+ def main():
233
+ """Main CLI entrypoint for wtinydb-mcp server."""
234
+ parser = argparse.ArgumentParser(description="wtinydb-mcp: WTinyDB Architect MCP Server")
235
+ parser.add_argument("command", nargs="?", default="run", choices=["run", "help"])
236
+ args = parser.parse_args()
237
+
238
+ if args.command == "run":
239
+ run_stdio()
240
+ else:
241
+ parser.print_help()
242
+
243
+
244
+ if __name__ == "__main__":
245
+ main()
@@ -0,0 +1,86 @@
1
+ """WTinyDB Scaffolding Code and Folder Generator."""
2
+
3
+ from typing import Dict, List
4
+
5
+
6
+ class TemplateGenerator:
7
+ """Generates standard directory structures and starter files for WTinyDB projects."""
8
+
9
+ @staticmethod
10
+ def get_folders(scaffold_type: str = "standard") -> List[str]:
11
+ """Return list of directory relative paths to create."""
12
+ return [
13
+ "config",
14
+ "models",
15
+ "repositories",
16
+ "services",
17
+ "tests",
18
+ ]
19
+
20
+ @staticmethod
21
+ def get_files_blueprint(scaffold_type: str = "standard", project_name: str = "wtinydb_project") -> Dict[str, str]:
22
+ """Return dictionary of relative file paths and their starter contents."""
23
+ settings_py = (
24
+ "from dataclasses import dataclass\n"
25
+ "import os\n\n"
26
+ "@dataclass\n"
27
+ "class DatabaseSettings:\n"
28
+ " db_path: str = os.getenv('TINYDB_PATH', 'app_data.json')\n"
29
+ " in_memory: bool = os.getenv('TINYDB_IN_MEMORY', 'False').lower() == 'true'\n"
30
+ )
31
+
32
+ user_model_py = (
33
+ "from pydantic import BaseModel, Field\n"
34
+ "from wtinydb import AuditMixin\n\n"
35
+ "class User(AuditMixin, BaseModel):\n"
36
+ " name: str = Field(description='User name')\n"
37
+ " email: str = Field(description='User email')\n"
38
+ " role: str = Field(default='user', description='Role')\n"
39
+ )
40
+
41
+ user_repo_py = (
42
+ "from wtinydb import WTinyDB, Q\n"
43
+ "from config.settings import DatabaseSettings\n"
44
+ "from models.user import User\n\n"
45
+ "class UserRepository:\n"
46
+ " def __init__(self, settings: DatabaseSettings = None):\n"
47
+ " settings = settings or DatabaseSettings()\n"
48
+ " self.db = WTinyDB(User, db_path=settings.db_path, in_memory=settings.in_memory)\n\n"
49
+ " def create_user(self, user: User) -> User:\n"
50
+ " return self.db.insert(user)\n\n"
51
+ " def get_by_email(self, email: str):\n"
52
+ " return self.db.get_by_field('email', email)\n"
53
+ )
54
+
55
+ main_py = (
56
+ f"'''{project_name} Entrypoint'''\n"
57
+ "from models.user import User\n"
58
+ "from repositories.user_repo import UserRepository\n\n"
59
+ "def main():\n"
60
+ " repo = UserRepository()\n"
61
+ " user = repo.create_user(User(name='Alice', email='alice@example.com'))\n"
62
+ " print(f'User created: {user.name} (email: {user.email})')\n\n"
63
+ "if __name__ == '__main__':\n"
64
+ " main()\n"
65
+ )
66
+
67
+ readme_md = (
68
+ f"# {project_name}\n\n"
69
+ "WTinyDB Document Store Application.\n\n"
70
+ "## Architecture\n"
71
+ "```mermaid\n"
72
+ "flowchart TD\n"
73
+ " Main[main.py] --> Repo[UserRepository]\n"
74
+ " Repo --> WTinyDB[WTinyDB Engine]\n"
75
+ " WTinyDB --> JSON[(TinyDB JSON Storage)]\n"
76
+ "```\n\n"
77
+ "*Generated by WTinyDB MCP by wisrovi*\n"
78
+ )
79
+
80
+ return {
81
+ "config/settings.py": settings_py,
82
+ "models/user.py": user_model_py,
83
+ "repositories/user_repo.py": user_repo_py,
84
+ "main.py": main_py,
85
+ "README.md": readme_md,
86
+ }
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: wtinydb-mcp
3
+ Version: 0.1.0
4
+ Summary: Model Context Protocol (MCP) server for WTinyDB architecture and code generation
5
+ Author-email: "WILLIAM R." <william@ecapturedtech.com>
6
+ License: MIT
7
+ Keywords: mcp,wtinydb,tinydb,ai-agent,fastmcp,architecture
8
+ Requires-Python: >=3.9
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: mcp>=1.0.0
12
+ Requires-Dist: pydantic>=2.0.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
15
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
16
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
17
+ Dynamic: license-file
18
+
19
+ # wtinydb-mcp: Model Context Protocol Server for WTinyDB
20
+
21
+ `wtinydb-mcp` is an official **Model Context Protocol (MCP)** server built on top of **FastMCP** that equips AI agents with tools to architect, validate, scaffold, and generate code for **WTinyDB** (TinyDB + Pydantic document database engine).
22
+
23
+ ## Key Technologies & Libraries
24
+
25
+ - **[MCP Protocol](https://modelcontextprotocol.io/)**: Open standard connecting AI models to external tools and context.
26
+ - **[FastMCP](https://github.com/jlowin/fastmcp)**: Python framework for fast MCP server implementation.
27
+ - **[WTinyDB](file:///home/william.rodriguez/Documents/w_libraries/w_libraries/wtinydb_os/wtinydb)**: Pydantic-powered document database engine on top of TinyDB.
28
+ - **[Pydantic v2](https://docs.pydantic.dev/)**: Data schema validation and Python AST inspection.
29
+ - **[Pytest](https://docs.pytest.org/)**: Modern Python testing framework.
30
+ - **[Pytest-Cov](https://pytest-cov.readthedocs.io/)**: Code coverage measurement for pytest.
31
+ - **[Docker](https://www.docker.com/)**: Containerized test execution environment.
32
+
33
+ ---
34
+
35
+ ## MCP Tools Exposed
36
+
37
+ 1. **`validate_model_schema(model_code: str)`**: Validates Pydantic document models for WTinyDB compatibility.
38
+ 2. **`search_wtinydb_pattern(query: str)`**: Searches the official wisrovi SUITE catalog for WTinyDB architectural patterns.
39
+ 3. **`deploy_wtinydb_scaffolding(target_dir: str, project_name: str, scaffold_type: str)`**: Deploys project scaffolding with repository, config, models, and tests.
40
+ 4. **`get_wtinydb_architect_blueprints()`**: Returns code reference and blueprints for WTinyDB features.
41
+ 5. **`get_wtinydb_architect_manual()`**: Returns the comprehensive WTinyDB architecting manual.
42
+ 6. **`generate_wtinydb_crud(model_code: str)`**: Automatically generates repository CRUD class for Pydantic models.
43
+
44
+ ---
45
+
46
+ ## Running Unit Tests & Coverage
47
+
48
+ ### Local Pytest Execution
49
+
50
+ ```bash
51
+ # Install editable package
52
+ pip install -e .
53
+
54
+ # Run pytest test suite
55
+ pytest tests/
56
+
57
+ # Calculate code coverage
58
+ ./scripts/run_coverage.sh
59
+ ```
60
+
61
+ ### Docker Containerized Test Execution
62
+
63
+ ```bash
64
+ ./scripts/run_tests_docker.sh
65
+ ```
66
+
67
+ ---
68
+
69
+ *Part of the wisrovi SUITE ecosystem.*
@@ -0,0 +1,10 @@
1
+ wtinydb_mcp/__init__.py,sha256=wJsh9LgxlxtTqgixgHZJarLL-jkiSRFjb4W50_LMq4A,65
2
+ wtinydb_mcp/catalog.py,sha256=ExZDrKRvf9OjuJpasERa5axtaqy0yxjAznhiZt3zqnU,2372
3
+ wtinydb_mcp/server.py,sha256=saNB9Wr4VsA_5AI0d13b_avsEzt-NXMAix9bEbLq3rk,9362
4
+ wtinydb_mcp/templates.py,sha256=HAEyFuMQ6sY5uo7B56bTBP8fJq1u9aG3Y_eUbXJ-cC4,3386
5
+ wtinydb_mcp-0.1.0.dist-info/licenses/LICENSE,sha256=Oyqf3mzTxsLVAFwTwTpmcfEsdCeJnA4jMu5Dv-Jq_Ag,1074
6
+ wtinydb_mcp-0.1.0.dist-info/METADATA,sha256=0NJMeaRTuU61mvllo-wAY3Q5N8Hcph7djgWz8bkHeC4,2772
7
+ wtinydb_mcp-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
8
+ wtinydb_mcp-0.1.0.dist-info/entry_points.txt,sha256=d93l9KfgOZuIoTduDhtsTLYLquem42grZxwknIfNLao,56
9
+ wtinydb_mcp-0.1.0.dist-info/top_level.txt,sha256=-KDYh9p5VKwAAuEl4jL4_KHhl89ueOWZU07Bf1hfWgQ,12
10
+ wtinydb_mcp-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ wtinydb-mcp = wtinydb_mcp.server:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 William Rodriguez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ wtinydb_mcp