awslabs.valkey-mcp-server 0.1.1__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,182 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
4
+ # with the License. A copy of the License is located at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
9
+ # OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
10
+ # and limitations under the License.
11
+
12
+ """Set operations for Valkey MCP Server."""
13
+
14
+ from awslabs.valkey_mcp_server.common.connection import ValkeyConnectionManager
15
+ from awslabs.valkey_mcp_server.common.server import mcp
16
+ from typing import Any, Optional
17
+ from valkey.exceptions import ValkeyError
18
+
19
+
20
+ @mcp.tool()
21
+ async def set_add(key: str, member: str) -> str:
22
+ """Add member to set.
23
+
24
+ Args:
25
+ key: The name of the key
26
+ member: Member to add
27
+
28
+ Returns:
29
+ Success message or error message
30
+ """
31
+ try:
32
+ r = ValkeyConnectionManager.get_connection()
33
+ result = r.sadd(key, member)
34
+ return f"Successfully added {result} new member to set '{key}'"
35
+ except ValkeyError as e:
36
+ return f"Error adding to set '{key}': {str(e)}"
37
+
38
+
39
+ @mcp.tool()
40
+ async def set_remove(key: str, member: str) -> str:
41
+ """Remove member from set.
42
+
43
+ Args:
44
+ key: The name of the key
45
+ member: Member to remove
46
+
47
+ Returns:
48
+ Success message or error message
49
+ """
50
+ try:
51
+ r = ValkeyConnectionManager.get_connection()
52
+ result = r.srem(key, member)
53
+ return f"Successfully removed {result} member from set '{key}'"
54
+ except ValkeyError as e:
55
+ return f"Error removing from set '{key}': {str(e)}"
56
+
57
+
58
+ @mcp.tool()
59
+ async def set_pop(key: str, count: Optional[int] = None) -> str:
60
+ """Remove and return random member(s) from set.
61
+
62
+ Args:
63
+ key: The name of the key
64
+ count: Number of members to pop (optional)
65
+
66
+ Returns:
67
+ Popped member(s) or error message
68
+ """
69
+ try:
70
+ r = ValkeyConnectionManager.get_connection()
71
+ if count:
72
+ result = r.spop(key, count)
73
+ else:
74
+ result = r.spop(key)
75
+ if result is None:
76
+ return f"Set '{key}' is empty"
77
+ return str(result)
78
+ except ValkeyError as e:
79
+ return f"Error popping from set '{key}': {str(e)}"
80
+
81
+
82
+ @mcp.tool()
83
+ async def set_move(source: str, destination: str, member: Any) -> str:
84
+ """Move member from one set to another.
85
+
86
+ Args:
87
+ source: Source set key
88
+ destination: Destination set key
89
+ member: Member to move
90
+
91
+ Returns:
92
+ Success message or error message
93
+ """
94
+ try:
95
+ r = ValkeyConnectionManager.get_connection()
96
+ result = r.smove(source, destination, member)
97
+ if result:
98
+ return f"Successfully moved member from set '{source}' to '{destination}'"
99
+ return f"Member not found in source set '{source}'"
100
+ except ValkeyError as e:
101
+ return f'Error moving between sets: {str(e)}'
102
+
103
+
104
+ @mcp.tool()
105
+ async def set_cardinality(key: str) -> str:
106
+ """Get number of members in set.
107
+
108
+ Args:
109
+ key: The name of the key
110
+
111
+ Returns:
112
+ Number of members or error message
113
+ """
114
+ try:
115
+ r = ValkeyConnectionManager.get_connection()
116
+ result = r.scard(key)
117
+ return str(result)
118
+ except ValkeyError as e:
119
+ return f"Error getting set cardinality for '{key}': {str(e)}"
120
+
121
+
122
+ @mcp.tool()
123
+ async def set_members(key: str) -> str:
124
+ """Get all members in set.
125
+
126
+ Args:
127
+ key: The name of the key
128
+
129
+ Returns:
130
+ List of members or error message
131
+ """
132
+ try:
133
+ r = ValkeyConnectionManager.get_connection()
134
+ result = r.smembers(key)
135
+ if not result:
136
+ return f"Set '{key}' is empty"
137
+ return str(result)
138
+ except ValkeyError as e:
139
+ return f"Error getting set members from '{key}': {str(e)}"
140
+
141
+
142
+ @mcp.tool()
143
+ async def set_random_member(key: str, count: Optional[int] = None) -> str:
144
+ """Get random member(s) from set without removing.
145
+
146
+ Args:
147
+ key: The name of the key
148
+ count: Number of members to return (optional)
149
+
150
+ Returns:
151
+ Random member(s) or error message
152
+ """
153
+ try:
154
+ r = ValkeyConnectionManager.get_connection()
155
+ if count:
156
+ result = r.srandmember(key, count)
157
+ else:
158
+ result = r.srandmember(key)
159
+ if result is None:
160
+ return f"Set '{key}' is empty"
161
+ return str(result)
162
+ except ValkeyError as e:
163
+ return f"Error getting random member from set '{key}': {str(e)}"
164
+
165
+
166
+ @mcp.tool()
167
+ async def set_contains(key: str, member: Any) -> str:
168
+ """Check if member exists in set.
169
+
170
+ Args:
171
+ key: The name of the key
172
+ member: Member to check
173
+
174
+ Returns:
175
+ Boolean result or error message
176
+ """
177
+ try:
178
+ r = ValkeyConnectionManager.get_connection()
179
+ result = r.sismember(key, member)
180
+ return str(result).lower()
181
+ except ValkeyError as e:
182
+ return f"Error checking set membership in '{key}': {str(e)}"
@@ -0,0 +1,359 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
4
+ # with the License. A copy of the License is located at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
9
+ # OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
10
+ # and limitations under the License.
11
+
12
+ """Sorted Set operations for Valkey MCP Server."""
13
+
14
+ from awslabs.valkey_mcp_server.common.connection import ValkeyConnectionManager
15
+ from awslabs.valkey_mcp_server.common.server import mcp
16
+ from typing import Any, Dict, Optional
17
+ from valkey.exceptions import ValkeyError
18
+
19
+
20
+ @mcp.tool()
21
+ async def sorted_set_add(key: str, mapping: Dict[Any, float]) -> str:
22
+ """Add member-score pairs to sorted set.
23
+
24
+ Args:
25
+ key: The name of the key
26
+ mapping: Dictionary of member-score pairs
27
+
28
+ Returns:
29
+ Success message or error message
30
+ """
31
+ try:
32
+ r = ValkeyConnectionManager.get_connection()
33
+ result = r.zadd(key, mapping)
34
+ return f"Successfully added {result} new member(s) to sorted set '{key}'"
35
+ except ValkeyError as e:
36
+ return f"Error adding to sorted set '{key}': {str(e)}"
37
+
38
+
39
+ @mcp.tool()
40
+ async def sorted_set_add_incr(key: str, member: Any, score: float) -> str:
41
+ """Add member to sorted set or increment its score.
42
+
43
+ Args:
44
+ key: The name of the key
45
+ member: The member to add/update
46
+ score: Score to add to existing score (or initial score)
47
+
48
+ Returns:
49
+ Success message or error message
50
+ """
51
+ try:
52
+ r = ValkeyConnectionManager.get_connection()
53
+ result = r.zincrby(key, score, member)
54
+ return f"Successfully set score for member in sorted set '{key}' to {result}"
55
+ except ValkeyError as e:
56
+ return f"Error incrementing score in sorted set '{key}': {str(e)}"
57
+
58
+
59
+ @mcp.tool()
60
+ async def sorted_set_remove(key: str, *members: Any) -> str:
61
+ """Remove member(s) from sorted set.
62
+
63
+ Args:
64
+ key: The name of the key
65
+ *members: Members to remove
66
+
67
+ Returns:
68
+ Success message or error message
69
+ """
70
+ try:
71
+ r = ValkeyConnectionManager.get_connection()
72
+ result = r.zrem(key, *members)
73
+ return f"Successfully removed {result} member(s) from sorted set '{key}'"
74
+ except ValkeyError as e:
75
+ return f"Error removing from sorted set '{key}': {str(e)}"
76
+
77
+
78
+ @mcp.tool()
79
+ async def sorted_set_remove_by_rank(key: str, start: int, stop: int) -> str:
80
+ """Remove members by rank range.
81
+
82
+ Args:
83
+ key: The name of the key
84
+ start: Start rank (inclusive)
85
+ stop: Stop rank (inclusive)
86
+
87
+ Returns:
88
+ Success message or error message
89
+ """
90
+ try:
91
+ r = ValkeyConnectionManager.get_connection()
92
+ result = r.zremrangebyrank(key, start, stop)
93
+ return f"Successfully removed {result} member(s) by rank from sorted set '{key}'"
94
+ except ValkeyError as e:
95
+ return f"Error removing by rank from sorted set '{key}': {str(e)}"
96
+
97
+
98
+ @mcp.tool()
99
+ async def sorted_set_remove_by_score(key: str, min_score: float, max_score: float) -> str:
100
+ """Remove members by score range.
101
+
102
+ Args:
103
+ key: The name of the key
104
+ min_score: Minimum score (inclusive)
105
+ max_score: Maximum score (inclusive)
106
+
107
+ Returns:
108
+ Success message or error message
109
+ """
110
+ try:
111
+ r = ValkeyConnectionManager.get_connection()
112
+ result = r.zremrangebyscore(key, min_score, max_score)
113
+ return f"Successfully removed {result} member(s) by score from sorted set '{key}'"
114
+ except ValkeyError as e:
115
+ return f"Error removing by score from sorted set '{key}': {str(e)}"
116
+
117
+
118
+ @mcp.tool()
119
+ async def sorted_set_remove_by_lex(key: str, min_lex: str, max_lex: str) -> str:
120
+ """Remove members by lexicographical range.
121
+
122
+ Args:
123
+ key: The name of the key
124
+ min_lex: Minimum value (inclusive)
125
+ max_lex: Maximum value (inclusive)
126
+
127
+ Returns:
128
+ Success message or error message
129
+ """
130
+ try:
131
+ r = ValkeyConnectionManager.get_connection()
132
+ result = r.zremrangebylex(key, min_lex, max_lex)
133
+ return f"Successfully removed {result} member(s) by lex range from sorted set '{key}'"
134
+ except ValkeyError as e:
135
+ return f"Error removing by lex range from sorted set '{key}': {str(e)}"
136
+
137
+
138
+ @mcp.tool()
139
+ async def sorted_set_cardinality(
140
+ key: str, min_score: Optional[float] = None, max_score: Optional[float] = None
141
+ ) -> str:
142
+ """Get number of members in sorted set.
143
+
144
+ Args:
145
+ key: The name of the key
146
+ min_score: Minimum score (optional)
147
+ max_score: Maximum score (optional)
148
+
149
+ Returns:
150
+ Number of members or error message
151
+ """
152
+ try:
153
+ r = ValkeyConnectionManager.get_connection()
154
+ if min_score is not None and max_score is not None:
155
+ result = r.zcount(key, min_score, max_score)
156
+ else:
157
+ result = r.zcard(key)
158
+ return str(result)
159
+ except ValkeyError as e:
160
+ return f"Error getting sorted set cardinality for '{key}': {str(e)}"
161
+
162
+
163
+ @mcp.tool()
164
+ async def sorted_set_score(key: str, member: Any) -> str:
165
+ """Get score of member in sorted set.
166
+
167
+ Args:
168
+ key: The name of the key
169
+ member: The member to get score for
170
+
171
+ Returns:
172
+ Score or error message
173
+ """
174
+ try:
175
+ r = ValkeyConnectionManager.get_connection()
176
+ result = r.zscore(key, member)
177
+ if result is None:
178
+ return f"Member not found in sorted set '{key}'"
179
+ return str(result)
180
+ except ValkeyError as e:
181
+ return f"Error getting score from sorted set '{key}': {str(e)}"
182
+
183
+
184
+ @mcp.tool()
185
+ async def sorted_set_rank(key: str, member: Any, reverse: bool = False) -> str:
186
+ """Get rank of member in sorted set.
187
+
188
+ Args:
189
+ key: The name of the key
190
+ member: The member to get rank for
191
+ reverse: If True, get rank in reverse order (highest first)
192
+
193
+ Returns:
194
+ Rank or error message
195
+ """
196
+ try:
197
+ r = ValkeyConnectionManager.get_connection()
198
+ if reverse:
199
+ result = r.zrevrank(key, member)
200
+ else:
201
+ result = r.zrank(key, member)
202
+ if result is None:
203
+ return f"Member not found in sorted set '{key}'"
204
+ return str(result)
205
+ except ValkeyError as e:
206
+ return f"Error getting rank from sorted set '{key}': {str(e)}"
207
+
208
+
209
+ @mcp.tool()
210
+ async def sorted_set_range(
211
+ key: str, start: int = 0, stop: int = -1, withscores: bool = False, reverse: bool = False
212
+ ) -> str:
213
+ """Get range of members from sorted set.
214
+
215
+ Args:
216
+ key: The name of the key
217
+ start: Start index (inclusive)
218
+ stop: Stop index (inclusive)
219
+ withscores: Include scores in result
220
+ reverse: Return results in reverse order
221
+
222
+ Returns:
223
+ List of members (with scores if requested) or error message
224
+ """
225
+ try:
226
+ r = ValkeyConnectionManager.get_connection()
227
+ if reverse:
228
+ result = r.zrevrange(key, start, stop, withscores=withscores)
229
+ else:
230
+ result = r.zrange(key, start, stop, withscores=withscores)
231
+ if not result:
232
+ return f"No members found in range for sorted set '{key}'"
233
+ return str(result)
234
+ except ValkeyError as e:
235
+ return f"Error getting range from sorted set '{key}': {str(e)}"
236
+
237
+
238
+ @mcp.tool()
239
+ async def sorted_set_range_by_score(
240
+ key: str,
241
+ min_score: float,
242
+ max_score: float,
243
+ withscores: bool = False,
244
+ reverse: bool = False,
245
+ offset: Optional[int] = None,
246
+ count: Optional[int] = None,
247
+ ) -> str:
248
+ """Get range of members by score.
249
+
250
+ Args:
251
+ key: The name of the key
252
+ min_score: Minimum score (inclusive)
253
+ max_score: Maximum score (inclusive)
254
+ withscores: Include scores in result
255
+ reverse: Return results in reverse order
256
+ offset: Number of members to skip
257
+ count: Maximum number of members to return
258
+
259
+ Returns:
260
+ List of members (with scores if requested) or error message
261
+ """
262
+ try:
263
+ r = ValkeyConnectionManager.get_connection()
264
+ if reverse:
265
+ result = r.zrevrangebyscore(
266
+ key, max_score, min_score, withscores=withscores, start=offset, num=count
267
+ )
268
+ else:
269
+ result = r.zrangebyscore(
270
+ key, min_score, max_score, withscores=withscores, start=offset, num=count
271
+ )
272
+ if not result:
273
+ return f"No members found in score range for sorted set '{key}'"
274
+ return str(result)
275
+ except ValkeyError as e:
276
+ return f"Error getting score range from sorted set '{key}': {str(e)}"
277
+
278
+
279
+ @mcp.tool()
280
+ async def sorted_set_range_by_lex(
281
+ key: str,
282
+ min_lex: str,
283
+ max_lex: str,
284
+ reverse: bool = False,
285
+ offset: Optional[int] = None,
286
+ count: Optional[int] = None,
287
+ ) -> str:
288
+ """Get range of members by lexicographical order.
289
+
290
+ Args:
291
+ key: The name of the key
292
+ min_lex: Minimum value (inclusive)
293
+ max_lex: Maximum value (inclusive)
294
+ reverse: Return results in reverse order
295
+ offset: Number of members to skip
296
+ count: Maximum number of members to return
297
+
298
+ Returns:
299
+ List of members or error message
300
+ """
301
+ try:
302
+ r = ValkeyConnectionManager.get_connection()
303
+ if reverse:
304
+ result = r.zrevrangebylex(key, max_lex, min_lex, start=offset, num=count)
305
+ else:
306
+ result = r.zrangebylex(key, min_lex, max_lex, start=offset, num=count)
307
+ if not result:
308
+ return f"No members found in lex range for sorted set '{key}'"
309
+ return str(result)
310
+ except ValkeyError as e:
311
+ return f"Error getting lex range from sorted set '{key}': {str(e)}"
312
+
313
+
314
+ @mcp.tool()
315
+ async def sorted_set_popmin(key: str, count: Optional[int] = None) -> str:
316
+ """Remove and return members with lowest scores.
317
+
318
+ Args:
319
+ key: The name of the key
320
+ count: Number of members to pop (optional)
321
+
322
+ Returns:
323
+ Popped members with scores or error message
324
+ """
325
+ try:
326
+ r = ValkeyConnectionManager.get_connection()
327
+ if count:
328
+ result = r.zpopmin(key, count)
329
+ else:
330
+ result = r.zpopmin(key)
331
+ if not result:
332
+ return f"Sorted set '{key}' is empty"
333
+ return str(result)
334
+ except ValkeyError as e:
335
+ return f"Error popping min from sorted set '{key}': {str(e)}"
336
+
337
+
338
+ @mcp.tool()
339
+ async def sorted_set_popmax(key: str, count: Optional[int] = None) -> str:
340
+ """Remove and return members with highest scores.
341
+
342
+ Args:
343
+ key: The name of the key
344
+ count: Number of members to pop (optional)
345
+
346
+ Returns:
347
+ Popped members with scores or error message
348
+ """
349
+ try:
350
+ r = ValkeyConnectionManager.get_connection()
351
+ if count:
352
+ result = r.zpopmax(key, count)
353
+ else:
354
+ result = r.zpopmax(key)
355
+ if not result:
356
+ return f"Sorted set '{key}' is empty"
357
+ return str(result)
358
+ except ValkeyError as e:
359
+ return f"Error popping max from sorted set '{key}': {str(e)}"