sku-availability-mcp 1.0.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.
- sku_availability_mcp/__init__.py +14 -0
- sku_availability_mcp/__main__.py +10 -0
- sku_availability_mcp/server.py +149 -0
- sku_availability_mcp-1.0.0.dist-info/METADATA +144 -0
- sku_availability_mcp-1.0.0.dist-info/RECORD +9 -0
- sku_availability_mcp-1.0.0.dist-info/WHEEL +5 -0
- sku_availability_mcp-1.0.0.dist-info/entry_points.txt +2 -0
- sku_availability_mcp-1.0.0.dist-info/licenses/LICENSE +21 -0
- sku_availability_mcp-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SKU Availability MCP Server
|
|
3
|
+
Real-time inventory availability queries via Confluent Cloud ksqlDB
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "1.0.0"
|
|
7
|
+
__author__ = "Your Name"
|
|
8
|
+
__email__ = "your.email@example.com"
|
|
9
|
+
|
|
10
|
+
from .server import mcp, get_sku_availability
|
|
11
|
+
|
|
12
|
+
__all__ = ["mcp", "get_sku_availability"]
|
|
13
|
+
|
|
14
|
+
# Made with Bob
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
FastMCP Server for SKU Availability
|
|
4
|
+
Provides tools to query inventory availability from ksqlDB
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from dotenv import load_dotenv
|
|
12
|
+
from requests.auth import HTTPBasicAuth
|
|
13
|
+
from fastmcp import FastMCP
|
|
14
|
+
import math
|
|
15
|
+
|
|
16
|
+
# Load environment variables
|
|
17
|
+
load_dotenv()
|
|
18
|
+
|
|
19
|
+
# ksqlDB Configuration
|
|
20
|
+
KSQLDB_ENDPOINT = "https://pksqlc-mzv0x2.us-east1.gcp.confluent.cloud:443"
|
|
21
|
+
KSQLDB_API_KEY = os.getenv('KSQLDB_API_KEY')
|
|
22
|
+
KSQLDB_API_SECRET = os.getenv('KSQLDB_API_SECRET')
|
|
23
|
+
|
|
24
|
+
# Create FastMCP server
|
|
25
|
+
mcp = FastMCP("SKU Availability Server")
|
|
26
|
+
|
|
27
|
+
def validate_config():
|
|
28
|
+
"""Validate that all required configuration is present"""
|
|
29
|
+
required_vars = ['KSQLDB_ENDPOINT', 'KSQLDB_API_KEY', 'KSQLDB_API_SECRET']
|
|
30
|
+
missing_vars = [var for var in required_vars if not os.getenv(var)]
|
|
31
|
+
|
|
32
|
+
if missing_vars:
|
|
33
|
+
raise ValueError(f"Missing required environment variables: {', '.join(missing_vars)}")
|
|
34
|
+
|
|
35
|
+
if 'xxxxx' in str(KSQLDB_ENDPOINT) or 'your-ksqldb-api-key' in str(KSQLDB_API_KEY):
|
|
36
|
+
raise ValueError("Please update .env file with your actual ksqlDB credentials")
|
|
37
|
+
|
|
38
|
+
def query_ksqldb(query: str) -> list:
|
|
39
|
+
"""
|
|
40
|
+
Execute a query against ksqlDB
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
query: SQL query to execute
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
List of result records
|
|
47
|
+
"""
|
|
48
|
+
validate_config()
|
|
49
|
+
|
|
50
|
+
url = f"{KSQLDB_ENDPOINT}/query-stream"
|
|
51
|
+
headers = {
|
|
52
|
+
'Content-Type': 'application/vnd.ksql.v1+json'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
payload = {
|
|
56
|
+
"sql": query,
|
|
57
|
+
"properties": {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
# Ensure credentials are not None
|
|
62
|
+
if not KSQLDB_API_KEY or not KSQLDB_API_SECRET:
|
|
63
|
+
raise ValueError("KSQLDB_API_KEY and KSQLDB_API_SECRET must be set")
|
|
64
|
+
|
|
65
|
+
response = requests.post(
|
|
66
|
+
url,
|
|
67
|
+
headers=headers,
|
|
68
|
+
json=payload,
|
|
69
|
+
auth=HTTPBasicAuth(KSQLDB_API_KEY, KSQLDB_API_SECRET),
|
|
70
|
+
stream=True,
|
|
71
|
+
timeout=30
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
if response.status_code != 200:
|
|
75
|
+
raise Exception(f"HTTP {response.status_code}: {response.text}")
|
|
76
|
+
|
|
77
|
+
results = []
|
|
78
|
+
|
|
79
|
+
# Read streaming response
|
|
80
|
+
for line in response.iter_lines():
|
|
81
|
+
if line:
|
|
82
|
+
try:
|
|
83
|
+
data = json.loads(line.decode('utf-8'))
|
|
84
|
+
|
|
85
|
+
# Skip header row
|
|
86
|
+
if 'header' in data or 'columnNames' in data or 'columnTypes' in data:
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
# Process data row
|
|
90
|
+
if isinstance(data, list) and len(data) >= 3:
|
|
91
|
+
results.append({
|
|
92
|
+
'sku': data[0],
|
|
93
|
+
'branch': data[1],
|
|
94
|
+
'available_quantity': data[2]
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
except json.JSONDecodeError:
|
|
98
|
+
continue
|
|
99
|
+
except Exception:
|
|
100
|
+
continue
|
|
101
|
+
|
|
102
|
+
return results
|
|
103
|
+
|
|
104
|
+
except Exception as e:
|
|
105
|
+
raise Exception(f"Failed to query ksqlDB: {str(e)}")
|
|
106
|
+
|
|
107
|
+
@mcp.tool()
|
|
108
|
+
def get_sku_availability(sku: str = "", branch: str = "") -> str:
|
|
109
|
+
"""
|
|
110
|
+
Get real-time inventory availability for SKUs across branches.
|
|
111
|
+
|
|
112
|
+
Query the INVENTORY_AVAILABILITY table which aggregates inventory transactions.
|
|
113
|
+
Returns current stock levels calculated from all inventory adds and sales.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
sku: Optional SKU filter (e.g., 'LAPTOP-DELL-XPS-15'). Leave empty to get all SKUs.
|
|
117
|
+
branch: Optional branch filter (e.g., 'DubaiMall', 'MallOfEgypt'). Leave empty to get all branches.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
JSON string with availability records
|
|
121
|
+
"""
|
|
122
|
+
try:
|
|
123
|
+
# Build query - treat empty strings as no filter
|
|
124
|
+
if sku and branch:
|
|
125
|
+
query = f"SELECT * FROM INVENTORY_AVAILABILITY WHERE SKU='{sku}' AND BRANCH='{branch}';"
|
|
126
|
+
elif sku:
|
|
127
|
+
query = f"SELECT * FROM INVENTORY_AVAILABILITY WHERE SKU='{sku}';"
|
|
128
|
+
elif branch:
|
|
129
|
+
query = f"SELECT * FROM INVENTORY_AVAILABILITY WHERE BRANCH='{branch}';"
|
|
130
|
+
else:
|
|
131
|
+
query = "SELECT * FROM INVENTORY_AVAILABILITY;"
|
|
132
|
+
|
|
133
|
+
# Execute query
|
|
134
|
+
results = query_ksqldb(query)
|
|
135
|
+
|
|
136
|
+
# Format response
|
|
137
|
+
if not results:
|
|
138
|
+
return json.dumps({"message": "No inventory records found", "results": []})
|
|
139
|
+
|
|
140
|
+
return json.dumps({"results": results}, indent=2)
|
|
141
|
+
|
|
142
|
+
except Exception as e:
|
|
143
|
+
return json.dumps({"error": str(e)})
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
mcp.run()
|
|
148
|
+
|
|
149
|
+
# Made with Bob
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sku-availability-mcp
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MCP server for real-time SKU availability queries via Confluent Cloud ksqlDB
|
|
5
|
+
Home-page: https://github.com/yourusername/sku-availability-mcp
|
|
6
|
+
Author: Bob AI Assistant
|
|
7
|
+
Author-email: Bob AI Assistant <bob@example.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/yourusername/sku-availability-mcp
|
|
10
|
+
Project-URL: Bug Reports, https://github.com/yourusername/sku-availability-mcp/issues
|
|
11
|
+
Project-URL: Source, https://github.com/yourusername/sku-availability-mcp
|
|
12
|
+
Keywords: mcp,model-context-protocol,confluent,kafka,ksqldb,inventory
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: fastmcp>=2.14.4
|
|
27
|
+
Requires-Dist: requests>=2.32.0
|
|
28
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
Dynamic: requires-python
|
|
33
|
+
|
|
34
|
+
# SKU Availability MCP Server
|
|
35
|
+
|
|
36
|
+
A Model Context Protocol (MCP) server that provides real-time inventory availability queries from Confluent Cloud ksqlDB.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- 🔍 Real-time SKU availability queries
|
|
41
|
+
- ☁️ Integration with Confluent Cloud ksqlDB
|
|
42
|
+
- ⚡ FastMCP-based server implementation
|
|
43
|
+
- 🎯 Filter by SKU and/or branch
|
|
44
|
+
- 🔌 Easy integration with watsonx Orchestrate
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install sku-availability-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
Set the following environment variables:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
export KSQLDB_API_KEY="your-api-key"
|
|
58
|
+
export KSQLDB_API_SECRET="your-api-secret"
|
|
59
|
+
export KSQLDB_ENDPOINT="https://your-ksqldb-endpoint.confluent.cloud:443"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or create a `.env` file:
|
|
63
|
+
|
|
64
|
+
```env
|
|
65
|
+
KSQLDB_API_KEY=your-api-key
|
|
66
|
+
KSQLDB_API_SECRET=your-api-secret
|
|
67
|
+
KSQLDB_ENDPOINT=https://your-ksqldb-endpoint.confluent.cloud:443
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
### Run as a module
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
python -m sku_availability_mcp
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Run as a command
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
sku-availability-mcp
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Use with watsonx Orchestrate
|
|
85
|
+
|
|
86
|
+
Add the toolkit using the orchestrate CLI:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
orchestrate toolkits add \
|
|
90
|
+
--kind mcp \
|
|
91
|
+
--name "sku-availability-toolkit" \
|
|
92
|
+
--description "Real-time inventory availability from Confluent Cloud" \
|
|
93
|
+
--language python \
|
|
94
|
+
--package "sku-availability-mcp" \
|
|
95
|
+
--tools "*"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Available Tools
|
|
99
|
+
|
|
100
|
+
### get_sku_availability
|
|
101
|
+
|
|
102
|
+
Query real-time inventory availability for SKUs across branches.
|
|
103
|
+
|
|
104
|
+
**Parameters:**
|
|
105
|
+
- `sku` (optional): SKU filter (e.g., 'LAPTOP-DELL-XPS-15')
|
|
106
|
+
- `branch` (optional): Branch filter (e.g., 'DubaiMall', 'MallOfEgypt')
|
|
107
|
+
|
|
108
|
+
**Returns:**
|
|
109
|
+
JSON object with availability records containing:
|
|
110
|
+
- `sku`: Product SKU
|
|
111
|
+
- `branch`: Store branch name
|
|
112
|
+
- `available_quantity`: Current available quantity
|
|
113
|
+
|
|
114
|
+
**Example:**
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
# Get all inventory
|
|
118
|
+
get_sku_availability()
|
|
119
|
+
|
|
120
|
+
# Get specific SKU
|
|
121
|
+
get_sku_availability(sku="LAPTOP-DELL-XPS-15")
|
|
122
|
+
|
|
123
|
+
# Get inventory for specific branch
|
|
124
|
+
get_sku_availability(branch="DubaiMall")
|
|
125
|
+
|
|
126
|
+
# Get specific SKU at specific branch
|
|
127
|
+
get_sku_availability(sku="LAPTOP-DELL-XPS-15", branch="DubaiMall")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Architecture
|
|
131
|
+
|
|
132
|
+
This MCP server connects to Confluent Cloud ksqlDB to query the `INVENTORY_AVAILABILITY` table, which aggregates real-time inventory transactions from Kafka topics.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT License
|
|
137
|
+
|
|
138
|
+
## Contributing
|
|
139
|
+
|
|
140
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
141
|
+
|
|
142
|
+
## Support
|
|
143
|
+
|
|
144
|
+
For issues and questions, please open an issue on GitHub.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
sku_availability_mcp/__init__.py,sha256=LuKtg5t4TEjbKijzb6lu8pk8w_UvD5akQjApP4657mc,296
|
|
2
|
+
sku_availability_mcp/__main__.py,sha256=g736Zntdeh80a7-YvzYEvoaYPCYO5qgRLfW17Yg3Byc,160
|
|
3
|
+
sku_availability_mcp/server.py,sha256=T1UtuhppE-QXWj4yE3ppUjk73ZEhgPMnNzWVwswEYVw,4657
|
|
4
|
+
sku_availability_mcp-1.0.0.dist-info/licenses/LICENSE,sha256=wbZ-cDWp28xmjCM1RUzgBJCLJN3XnZTvqIBGsf2DSJQ,1076
|
|
5
|
+
sku_availability_mcp-1.0.0.dist-info/METADATA,sha256=uM_wATkg2NICDFa0mMvI6djMBpkccnNJD4NERmPnLDs,3791
|
|
6
|
+
sku_availability_mcp-1.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
7
|
+
sku_availability_mcp-1.0.0.dist-info/entry_points.txt,sha256=-4KsNSLIZb-dl5vWJTv_9b6yIXCGCJrVcme-mopVpVQ,74
|
|
8
|
+
sku_availability_mcp-1.0.0.dist-info/top_level.txt,sha256=wn9Ka1Xxku2p8WiGRzrM6P0vtIrB2SHTevs7imKGCNk,21
|
|
9
|
+
sku_availability_mcp-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SKU Availability MCP
|
|
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
|
+
sku_availability_mcp
|