awslabs.memcached-mcp-server 1.0.2__tar.gz → 1.0.4__tar.gz

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.
Files changed (26) hide show
  1. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/Dockerfile +33 -23
  2. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/PKG-INFO +73 -2
  3. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/README.md +71 -0
  4. awslabs_memcached_mcp_server-1.0.4/awslabs/memcached_mcp_server/context.py +39 -0
  5. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/memcached_mcp_server/main.py +14 -0
  6. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/memcached_mcp_server/tools/cache.py +40 -0
  7. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/docker-healthcheck.sh +7 -8
  8. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/pyproject.toml +2 -2
  9. awslabs_memcached_mcp_server-1.0.4/tests/test_cache_readonly.py +163 -0
  10. awslabs_memcached_mcp_server-1.0.4/uv-requirements.txt +26 -0
  11. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/uv.lock +645 -445
  12. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/.gitignore +0 -0
  13. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/.python-version +0 -0
  14. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/CHANGELOG.md +0 -0
  15. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/ELASTICACHECONNECT.md +0 -0
  16. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/LICENSE +0 -0
  17. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/NOTICE +0 -0
  18. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/__init__.py +0 -0
  19. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/memcached_mcp_server/__init__.py +0 -0
  20. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/memcached_mcp_server/common/config.py +0 -0
  21. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/memcached_mcp_server/common/connection.py +0 -0
  22. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/awslabs/memcached_mcp_server/common/server.py +0 -0
  23. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/tests/test_cache.py +0 -0
  24. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/tests/test_connection.py +0 -0
  25. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/tests/test_init.py +0 -0
  26. {awslabs_memcached_mcp_server-1.0.2 → awslabs_memcached_mcp_server-1.0.4}/tests/test_main.py +0 -0
@@ -12,8 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- #FROM public.ecr.aws/sam/build-python3.10:1.137.1-20250411084548
16
- FROM public.ecr.aws/sam/build-python3.10@sha256:d821662474d65f3cf2fc97dba2fa807a3adb580d02895fc4545527812550ea65 AS uv
15
+ # dependabot should continue to update this to the latest hash.
16
+ FROM public.ecr.aws/docker/library/python:3.13.5-alpine3.21@sha256:c9a09c45a4bcc618c7f7128585b8dd0d41d0c31a8a107db4c8255ffe0b69375d AS uv
17
17
 
18
18
  # Install the project into `/app`
19
19
  WORKDIR /app
@@ -31,40 +31,50 @@ ENV UV_PYTHON_PREFERENCE=only-system
31
31
  ENV UV_FROZEN=true
32
32
 
33
33
  # Copy the required files first
34
- COPY pyproject.toml uv.lock ./
34
+ COPY pyproject.toml uv.lock uv-requirements.txt ./
35
+
36
+ # Python optimization and uv configuration
37
+ ENV PIP_NO_CACHE_DIR=1 \
38
+ PIP_DISABLE_PIP_VERSION_CHECK=1
39
+
40
+ # Install system dependencies and Python package manager
41
+ RUN apk update && \
42
+ apk add --no-cache --virtual .build-deps \
43
+ build-base \
44
+ gcc \
45
+ musl-dev \
46
+ libffi-dev \
47
+ openssl-dev \
48
+ cargo
35
49
 
36
50
  # Install the project's dependencies using the lockfile and settings
37
51
  RUN --mount=type=cache,target=/root/.cache/uv \
38
- pip install uv==0.7.11 && \
39
- uv sync --frozen --no-install-project --no-dev --no-editable
52
+ pip install --require-hashes --requirement uv-requirements.txt --no-cache-dir && \
53
+ uv sync --python 3.13 --frozen --no-install-project --no-dev --no-editable
40
54
 
41
55
  # Then, add the rest of the project source code and install it
42
56
  # Installing separately from its dependencies allows optimal layer caching
43
57
  COPY . /app
44
58
  RUN --mount=type=cache,target=/root/.cache/uv \
45
- uv sync --frozen --no-dev --no-editable
59
+ uv sync --python 3.13 --frozen --no-dev --no-editable
46
60
 
47
61
  # Make the directory just in case it doesn't exist
48
62
  RUN mkdir -p /root/.local
49
63
 
50
- FROM public.ecr.aws/sam/build-python3.10@sha256:d821662474d65f3cf2fc97dba2fa807a3adb580d02895fc4545527812550ea65
64
+ FROM public.ecr.aws/docker/library/python:3.13.5-alpine3.21@sha256:c9a09c45a4bcc618c7f7128585b8dd0d41d0c31a8a107db4c8255ffe0b69375d
51
65
 
52
66
  # Place executables in the environment at the front of the path and include other binaries
53
- ENV PATH="/app/.venv/bin:$PATH:/usr/sbin"
54
-
55
- # Install lsof for the healthcheck
56
- # Install other tools as needed for the MCP server
57
- # Add non-root user and ability to change directory into /root
58
- RUN yum update -y && \
59
- yum install -y lsof && \
60
- yum clean all -y && \
61
- rm -rf /var/cache/yum && \
62
- groupadd --force --system app && \
63
- useradd app -g app -d /app && \
64
- chmod o+x /root
65
-
66
- # Get the project from the uv layer
67
- COPY --from=uv --chown=app:app /root/.local /root/.local
67
+ ENV PATH="/app/.venv/bin:$PATH" \
68
+ PYTHONUNBUFFERED=1
69
+
70
+ # Install runtime dependencies and create application user
71
+ RUN apk update && \
72
+ apk add --no-cache ca-certificates && \
73
+ update-ca-certificates && \
74
+ addgroup -S app && \
75
+ adduser -S app -G app -h /app
76
+
77
+ # Copy application artifacts from build stage
68
78
  COPY --from=uv --chown=app:app /app/.venv /app/.venv
69
79
 
70
80
  # Get healthcheck script
@@ -74,5 +84,5 @@ COPY ./docker-healthcheck.sh /usr/local/bin/docker-healthcheck.sh
74
84
  USER app
75
85
 
76
86
  # When running the container, add --db-path and a bind mount to the host's db file
77
- HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD [ "docker-healthcheck.sh" ]
87
+ HEALTHCHECK --interval=60s --timeout=10s --start-period=10s --retries=3 CMD ["docker-healthcheck.sh"]
78
88
  ENTRYPOINT ["awslabs.memcached-mcp-server"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awslabs.memcached-mcp-server
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: An AWS Labs Model Context Protocol (MCP) server for Amazon ElastiCache Memcached
5
5
  Project-URL: homepage, https://awslabs.github.io/mcp/
6
6
  Project-URL: docs, https://awslabs.github.io/mcp/servers/memcached-mcp-server/
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3.13
23
23
  Requires-Python: >=3.10
24
24
  Requires-Dist: loguru>=0.7.0
25
- Requires-Dist: mcp[cli]>=1.6.0
25
+ Requires-Dist: mcp[cli]>=1.11.0
26
26
  Requires-Dist: pydantic>=2.10.6
27
27
  Requires-Dist: pymemcache>=4.0.0
28
28
  Requires-Dist: python-dotenv>=0.9.9
@@ -40,6 +40,17 @@ MCP server for interacting with Amazon ElastiCache Memcached through a secure an
40
40
  - Secure communication with SSL/TLS encryption
41
41
  - Automatic connection management and pooling
42
42
  - Built-in retry mechanism for failed operations
43
+ - Readonly mode to prevent write operations
44
+
45
+ ### Readonly Mode
46
+
47
+ The server can be started in readonly mode, which prevents any write operations from being performed. This is useful for scenarios where you want to ensure that no data is modified, such as:
48
+
49
+ - Read-only replicas
50
+ - Production environments where writes should be restricted
51
+ - Debugging and monitoring without risk of data modification
52
+
53
+ When readonly mode is enabled, any attempt to perform a write operation (set, add, replace, delete, etc.) will return an error message.
43
54
 
44
55
  ## Prerequisites
45
56
 
@@ -51,6 +62,10 @@ MCP server for interacting with Amazon ElastiCache Memcached through a secure an
51
62
 
52
63
  ## Installation
53
64
 
65
+ | Cursor | VS Code |
66
+ |:------:|:-------:|
67
+ | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/install-mcp?name=awslabs.memcached-mcp-server&config=eyJjb21tYW5kIjoidXZ4IGF3c2xhYnMubWVtY2FjaGVkLW1jcC1zZXJ2ZXJAbGF0ZXN0IiwiZW52Ijp7IkZBU1RNQ1BfTE9HX0xFVkVMIjoiRVJST1IiLCJNRU1DQUNIRURfSE9TVCI6InlvdXItbWVtY2FjaGVkLWhvc3QiLCJNRU1DQUNIRURfUE9SVCI6IjExMjExIn0sImRpc2FibGVkIjpmYWxzZSwiYXV0b0FwcHJvdmUiOltdfQ%3D%3D) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=Memcached%20MCP%20Server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.memcached-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%2C%22MEMCACHED_HOST%22%3A%22your-memcached-host%22%2C%22MEMCACHED_PORT%22%3A%2211211%22%7D%2C%22disabled%22%3Afalse%2C%22autoApprove%22%3A%5B%5D%7D) |
68
+
54
69
  Here are some ways you can work with MCP (e.g. for Amazon Q Developer CLI MCP, `~/.aws/amazonq/mcp.json`):
55
70
 
56
71
  ```json
@@ -71,6 +86,26 @@ Here are some ways you can work with MCP (e.g. for Amazon Q Developer CLI MCP, `
71
86
  }
72
87
  ```
73
88
 
89
+ To run in readonly mode:
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "awslabs.memcached-mcp-server": {
95
+ "command": "uvx",
96
+ "args": ["awslabs.memcached-mcp-server@latest", "--readonly"],
97
+ "env": {
98
+ "FASTMCP_LOG_LEVEL": "ERROR",
99
+ "MEMCACHED_HOST": "your-memcached-host",
100
+ "MEMCACHED_PORT": "11211"
101
+ },
102
+ "disabled": false,
103
+ "autoApprove": []
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
74
109
  or docker after a successful `docker build -t awslabs/memcached-mcp-server .`:
75
110
 
76
111
  ```json
@@ -98,6 +133,34 @@ or docker after a successful `docker build -t awslabs/memcached-mcp-server .`:
98
133
  }
99
134
  ```
100
135
 
136
+ To run in readonly mode with Docker:
137
+
138
+ ```json
139
+ {
140
+ "mcpServers": {
141
+ "awslabs.memcached-mcp-server": {
142
+ "command": "docker",
143
+ "args": [
144
+ "run",
145
+ "--rm",
146
+ "--interactive",
147
+ "--env",
148
+ "FASTMCP_LOG_LEVEL=ERROR",
149
+ "--env",
150
+ "MEMCACHED_HOST=your-memcached-host",
151
+ "--env",
152
+ "MEMCACHED_PORT=11211",
153
+ "awslabs/memcached-mcp-server:latest",
154
+ "--readonly"
155
+ ],
156
+ "env": {},
157
+ "disabled": false,
158
+ "autoApprove": []
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
101
164
  ## Configuration
102
165
 
103
166
  ### Basic Connection Settings
@@ -155,3 +218,11 @@ docker run -p 8080:8080 \
155
218
  -e MEMCACHED_PORT=11211 \
156
219
  awslabs/memcached-mcp-server
157
220
  ```
221
+
222
+ To run in readonly mode:
223
+ ```bash
224
+ docker run -p 8080:8080 \
225
+ -e MEMCACHED_HOST=host.docker.internal \
226
+ -e MEMCACHED_PORT=11211 \
227
+ awslabs/memcached-mcp-server --readonly
228
+ ```
@@ -10,6 +10,17 @@ MCP server for interacting with Amazon ElastiCache Memcached through a secure an
10
10
  - Secure communication with SSL/TLS encryption
11
11
  - Automatic connection management and pooling
12
12
  - Built-in retry mechanism for failed operations
13
+ - Readonly mode to prevent write operations
14
+
15
+ ### Readonly Mode
16
+
17
+ The server can be started in readonly mode, which prevents any write operations from being performed. This is useful for scenarios where you want to ensure that no data is modified, such as:
18
+
19
+ - Read-only replicas
20
+ - Production environments where writes should be restricted
21
+ - Debugging and monitoring without risk of data modification
22
+
23
+ When readonly mode is enabled, any attempt to perform a write operation (set, add, replace, delete, etc.) will return an error message.
13
24
 
14
25
  ## Prerequisites
15
26
 
@@ -21,6 +32,10 @@ MCP server for interacting with Amazon ElastiCache Memcached through a secure an
21
32
 
22
33
  ## Installation
23
34
 
35
+ | Cursor | VS Code |
36
+ |:------:|:-------:|
37
+ | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/install-mcp?name=awslabs.memcached-mcp-server&config=eyJjb21tYW5kIjoidXZ4IGF3c2xhYnMubWVtY2FjaGVkLW1jcC1zZXJ2ZXJAbGF0ZXN0IiwiZW52Ijp7IkZBU1RNQ1BfTE9HX0xFVkVMIjoiRVJST1IiLCJNRU1DQUNIRURfSE9TVCI6InlvdXItbWVtY2FjaGVkLWhvc3QiLCJNRU1DQUNIRURfUE9SVCI6IjExMjExIn0sImRpc2FibGVkIjpmYWxzZSwiYXV0b0FwcHJvdmUiOltdfQ%3D%3D) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=Memcached%20MCP%20Server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.memcached-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%2C%22MEMCACHED_HOST%22%3A%22your-memcached-host%22%2C%22MEMCACHED_PORT%22%3A%2211211%22%7D%2C%22disabled%22%3Afalse%2C%22autoApprove%22%3A%5B%5D%7D) |
38
+
24
39
  Here are some ways you can work with MCP (e.g. for Amazon Q Developer CLI MCP, `~/.aws/amazonq/mcp.json`):
25
40
 
26
41
  ```json
@@ -41,6 +56,26 @@ Here are some ways you can work with MCP (e.g. for Amazon Q Developer CLI MCP, `
41
56
  }
42
57
  ```
43
58
 
59
+ To run in readonly mode:
60
+
61
+ ```json
62
+ {
63
+ "mcpServers": {
64
+ "awslabs.memcached-mcp-server": {
65
+ "command": "uvx",
66
+ "args": ["awslabs.memcached-mcp-server@latest", "--readonly"],
67
+ "env": {
68
+ "FASTMCP_LOG_LEVEL": "ERROR",
69
+ "MEMCACHED_HOST": "your-memcached-host",
70
+ "MEMCACHED_PORT": "11211"
71
+ },
72
+ "disabled": false,
73
+ "autoApprove": []
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
44
79
  or docker after a successful `docker build -t awslabs/memcached-mcp-server .`:
45
80
 
46
81
  ```json
@@ -68,6 +103,34 @@ or docker after a successful `docker build -t awslabs/memcached-mcp-server .`:
68
103
  }
69
104
  ```
70
105
 
106
+ To run in readonly mode with Docker:
107
+
108
+ ```json
109
+ {
110
+ "mcpServers": {
111
+ "awslabs.memcached-mcp-server": {
112
+ "command": "docker",
113
+ "args": [
114
+ "run",
115
+ "--rm",
116
+ "--interactive",
117
+ "--env",
118
+ "FASTMCP_LOG_LEVEL=ERROR",
119
+ "--env",
120
+ "MEMCACHED_HOST=your-memcached-host",
121
+ "--env",
122
+ "MEMCACHED_PORT=11211",
123
+ "awslabs/memcached-mcp-server:latest",
124
+ "--readonly"
125
+ ],
126
+ "env": {},
127
+ "disabled": false,
128
+ "autoApprove": []
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
71
134
  ## Configuration
72
135
 
73
136
  ### Basic Connection Settings
@@ -125,3 +188,11 @@ docker run -p 8080:8080 \
125
188
  -e MEMCACHED_PORT=11211 \
126
189
  awslabs/memcached-mcp-server
127
190
  ```
191
+
192
+ To run in readonly mode:
193
+ ```bash
194
+ docker run -p 8080:8080 \
195
+ -e MEMCACHED_HOST=host.docker.internal \
196
+ -e MEMCACHED_PORT=11211 \
197
+ awslabs/memcached-mcp-server --readonly
198
+ ```
@@ -0,0 +1,39 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Context management for Memcached MCP Server."""
16
+
17
+
18
+ class Context:
19
+ """Context class for Memcached MCP Server."""
20
+
21
+ _readonly = False
22
+
23
+ @classmethod
24
+ def initialize(cls, readonly: bool = False):
25
+ """Initialize the context.
26
+
27
+ Args:
28
+ readonly: Whether to run in readonly mode
29
+ """
30
+ cls._readonly = readonly
31
+
32
+ @classmethod
33
+ def readonly_mode(cls) -> bool:
34
+ """Check if the server is running in readonly mode.
35
+
36
+ Returns:
37
+ True if readonly mode is enabled, False otherwise
38
+ """
39
+ return cls._readonly
@@ -14,7 +14,9 @@
14
14
 
15
15
  """awslabs memcached MCP Server implementation."""
16
16
 
17
+ import argparse
17
18
  from awslabs.memcached_mcp_server.common.server import mcp
19
+ from awslabs.memcached_mcp_server.context import Context
18
20
  from awslabs.memcached_mcp_server.tools import cache # noqa: F401
19
21
  from loguru import logger
20
22
  from starlette.requests import Request # noqa: F401
@@ -41,6 +43,18 @@ class MemcachedMCPServer:
41
43
 
42
44
  def main():
43
45
  """Run the MCP server with CLI argument support."""
46
+ parser = argparse.ArgumentParser(
47
+ description='An AWS Labs Model Context Protocol (MCP) server for interacting with Memcached'
48
+ )
49
+ parser.add_argument(
50
+ '--readonly',
51
+ action=argparse.BooleanOptionalAction,
52
+ help='Prevents the MCP server from performing mutating operations',
53
+ )
54
+
55
+ args = parser.parse_args()
56
+ Context.initialize(args.readonly)
57
+
44
58
  logger.info('Amazon ElastiCache Memcached MCP Server Started...')
45
59
  MemcachedMCPServer().run()
46
60
 
@@ -16,6 +16,7 @@
16
16
 
17
17
  from awslabs.memcached_mcp_server.common.connection import MemcachedConnectionManager
18
18
  from awslabs.memcached_mcp_server.common.server import mcp
19
+ from awslabs.memcached_mcp_server.context import Context
19
20
  from pymemcache.exceptions import MemcacheError
20
21
  from typing import Any, Dict, List, Optional
21
22
 
@@ -106,6 +107,9 @@ async def cache_set(key: str, value: Any, expire: Optional[int] = None) -> str:
106
107
  Returns:
107
108
  Success message or error message
108
109
  """
110
+ if Context.readonly_mode():
111
+ return 'Operation not permitted: Server is in readonly mode'
112
+
109
113
  try:
110
114
  client = MemcachedConnectionManager.get_connection()
111
115
  client.set(key, value, expire=expire)
@@ -128,6 +132,9 @@ async def cache_cas(key: str, value: Any, cas: int, expire: Optional[int] = None
128
132
  Returns:
129
133
  Success message or error message
130
134
  """
135
+ if Context.readonly_mode():
136
+ return 'Operation not permitted: Server is in readonly mode'
137
+
131
138
  try:
132
139
  client = MemcachedConnectionManager.get_connection()
133
140
  if client.cas(key, value, cas, expire=expire):
@@ -149,6 +156,9 @@ async def cache_set_many(mapping: Dict[str, Any], expire: Optional[int] = None)
149
156
  Returns:
150
157
  Success message or error message
151
158
  """
159
+ if Context.readonly_mode():
160
+ return 'Operation not permitted: Server is in readonly mode'
161
+
152
162
  try:
153
163
  client = MemcachedConnectionManager.get_connection()
154
164
  failed = client.set_many(mapping, expire=expire)
@@ -186,6 +196,9 @@ async def cache_add(key: str, value: Any, expire: Optional[int] = None) -> str:
186
196
  Returns:
187
197
  Success message or error message
188
198
  """
199
+ if Context.readonly_mode():
200
+ return 'Operation not permitted: Server is in readonly mode'
201
+
189
202
  try:
190
203
  client = MemcachedConnectionManager.get_connection()
191
204
  if client.add(key, value, expire=expire):
@@ -208,6 +221,9 @@ async def cache_replace(key: str, value: Any, expire: Optional[int] = None) -> s
208
221
  Returns:
209
222
  Success message or error message
210
223
  """
224
+ if Context.readonly_mode():
225
+ return 'Operation not permitted: Server is in readonly mode'
226
+
211
227
  try:
212
228
  client = MemcachedConnectionManager.get_connection()
213
229
  if client.replace(key, value, expire=expire):
@@ -229,6 +245,9 @@ async def cache_append(key: str, value: str) -> str:
229
245
  Returns:
230
246
  Success message or error message
231
247
  """
248
+ if Context.readonly_mode():
249
+ return 'Operation not permitted: Server is in readonly mode'
250
+
232
251
  try:
233
252
  client = MemcachedConnectionManager.get_connection()
234
253
  if client.append(key, value):
@@ -249,6 +268,9 @@ async def cache_prepend(key: str, value: str) -> str:
249
268
  Returns:
250
269
  Success message or error message
251
270
  """
271
+ if Context.readonly_mode():
272
+ return 'Operation not permitted: Server is in readonly mode'
273
+
252
274
  try:
253
275
  client = MemcachedConnectionManager.get_connection()
254
276
  if client.prepend(key, value):
@@ -268,6 +290,9 @@ async def cache_delete(key: str) -> str:
268
290
  Returns:
269
291
  Success message or error message
270
292
  """
293
+ if Context.readonly_mode():
294
+ return 'Operation not permitted: Server is in readonly mode'
295
+
271
296
  try:
272
297
  client = MemcachedConnectionManager.get_connection()
273
298
  if client.delete(key):
@@ -287,6 +312,9 @@ async def cache_delete_many(keys: List[str]) -> str:
287
312
  Returns:
288
313
  Success message or error message
289
314
  """
315
+ if Context.readonly_mode():
316
+ return 'Operation not permitted: Server is in readonly mode'
317
+
290
318
  try:
291
319
  client = MemcachedConnectionManager.get_connection()
292
320
  failed = client.delete_many(keys)
@@ -321,6 +349,9 @@ async def cache_incr(key: str, value: int = 1) -> str:
321
349
  Returns:
322
350
  New value or error message
323
351
  """
352
+ if Context.readonly_mode():
353
+ return 'Operation not permitted: Server is in readonly mode'
354
+
324
355
  try:
325
356
  client = MemcachedConnectionManager.get_connection()
326
357
  result = client.incr(key, value)
@@ -342,6 +373,9 @@ async def cache_decr(key: str, value: int = 1) -> str:
342
373
  Returns:
343
374
  New value or error message
344
375
  """
376
+ if Context.readonly_mode():
377
+ return 'Operation not permitted: Server is in readonly mode'
378
+
345
379
  try:
346
380
  client = MemcachedConnectionManager.get_connection()
347
381
  result = client.decr(key, value)
@@ -363,6 +397,9 @@ async def cache_touch(key: str, expire: int) -> str:
363
397
  Returns:
364
398
  Success message or error message
365
399
  """
400
+ if Context.readonly_mode():
401
+ return 'Operation not permitted: Server is in readonly mode'
402
+
366
403
  try:
367
404
  client = MemcachedConnectionManager.get_connection()
368
405
  if client.touch(key, expire):
@@ -400,6 +437,9 @@ async def cache_flush_all(delay: int = 0) -> str:
400
437
  Returns:
401
438
  Success message or error message
402
439
  """
440
+ if Context.readonly_mode():
441
+ return 'Operation not permitted: Server is in readonly mode'
442
+
403
443
  try:
404
444
  client = MemcachedConnectionManager.get_connection()
405
445
  client.flush_all(delay=delay)
@@ -1,5 +1,4 @@
1
1
  #!/bin/sh
2
-
3
2
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
3
  #
5
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,13 +13,13 @@
14
13
  # See the License for the specific language governing permissions and
15
14
  # limitations under the License.
16
15
 
17
- if [ "$(lsof +c 0 -p 1 | grep -e grep -e "^awslabs\..*\s1\s.*\unix\s.*socket$" | wc -l)" -ne "0" ]; then
18
- echo -n "$(lsof +c 0 -p 1 | grep -e grep -e "^awslabs\..*\s1\s.*\unix\s.*socket$" | wc -l) awslabs.* streams found";
16
+ SERVER="memcached-mcp-server"
17
+
18
+ # Check if the server process is running
19
+ if pgrep -P 0 -a -l -x -f "/app/.venv/bin/python3 /app/.venv/bin/awslabs.$SERVER" > /dev/null; then
20
+ echo -n "$SERVER is running";
19
21
  exit 0;
20
- else
21
- echo -n "Zero awslabs.* streams found";
22
- exit 1;
23
22
  fi;
24
23
 
25
- echo -n "Never should reach here";
26
- exit 99;
24
+ # Unhealthy
25
+ exit 1;
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "awslabs.memcached-mcp-server"
3
- version = "1.0.2"
3
+ version = "1.0.4"
4
4
  description = "An AWS Labs Model Context Protocol (MCP) server for Amazon ElastiCache Memcached"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  dependencies = [
8
8
  "loguru>=0.7.0",
9
- "mcp[cli]>=1.6.0",
9
+ "mcp[cli]>=1.11.0",
10
10
  "pydantic>=2.10.6",
11
11
  "pymemcache>=4.0.0",
12
12
  "python-dotenv>=0.9.9"