Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions distribution/examples/mcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# MCP Tool Blocking with Membrane

This example shows how to place a Membrane API Gateway in front of an MCP server and block a specific tool call based on the MCP request body.

The backend MCP server exposes two tools:

- `echo`
- `secretHello`

The setup is:

- backend MCP server on `http://localhost:8081/mcp`
- Membrane API Gateway on `http://localhost:2000/mcp`

The gateway forwards all MCP requests to the backend, but blocks calls to `secretHello`.

## Running the Example

1. Go to this example directory.

2. Start the backend MCP server.

Linux / macOS:
```sh
./start-backend.sh
```

Windows:
```bat
start-backend.cmd
```
Comment on lines +21 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Document how mcp-server-demo.jar is produced/obtained before startup.

Lines 21–31 instruct starting the backend directly, but scripts require a local mcp-server-demo.jar. If that jar is removed before merge, this example becomes non-runnable without an explicit build/download step.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@distribution/examples/mcp/README.md` around lines 21 - 31, The README's
startup instructions assume a local mcp-server-demo.jar exists but don't state
how to get or build it; update the README to document producing/obtaining that
JAR by adding one-line instructions before the "Start the backend MCP server"
section that reference the build or download step (e.g., how to run the
Maven/Gradle build or where to download the artifact) and note that
start-backend.sh and start-backend.cmd expect mcp-server-demo.jar in the same
directory; mention the exact artifact name mcp-server-demo.jar and the scripts
start-backend.sh / start-backend.cmd so readers can locate the build command or
download URL.


3. Start Membrane.

Linux / macOS:
```sh
./membrane.sh
```

Windows:
```bat
membrane.cmd
```

4. Start the MCP Inspector:

```sh
npx @modelcontextprotocol/inspector
```

5. Open the Inspector UI in your browser.

6. Create a connection to the gateway with these values:

- **Transport:** `Streamable HTTP`
- **URL:** `http://localhost:2000/mcp`

7. Connect.

## Testing with the Inspector

### 1. Inspect available tools

Open the **Tools** section.

You should see both backend tools:

- `echo`
- `secretHello`

This example blocks the execution of one tool at the gateway layer. It does not remove the tool from `tools/list`.

### 2. Call the allowed tool

Select the `echo` tool and set the text to e.g. "Hello".

### 3. Call the blocked tool

Select the `secretHello` tool and use the same text:

`Blocked by Membrane gateway: tool secretHello is not allowed`
36 changes: 36 additions & 0 deletions distribution/examples/mcp/apis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
api:
name: demo-mcp-gateway
port: 2000
path:
uri: /mcp
flow:
- request:
- if:
language: SpEL
test: "isJSON() and json.method == 'tools/call' and json['params'] != null and json['params']['name'] == 'secretHello'"
flow:
- template:
contentType: application/json
src: |
{
"jsonrpc": "2.0",
"id": ${json.id},
"result": {
"content": [
{
"type": "text",
"text": "Blocked by Membrane gateway: tool secretHello is not allowed"
}
],
"isError": true
}
}
- return:
status: 200
contentType: application/json

- log: {}

target:
host: localhost
port: 8081
Binary file added distribution/examples/mcp/mcp-server-demo.jar
Binary file not shown.
24 changes: 24 additions & 0 deletions distribution/examples/mcp/membrane.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@echo off
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Commit this batch file with CRLF endings.

Line 1 indicates a Windows batch script; LF-only endings can cause runtime parsing issues under cmd.exe.

🧰 Tools
🪛 Blinter (1.0.112)

[error] 1-1: Unix line endings detected. Explanation: Batch file uses Unix line endings (LF-only) which can cause GOTO/CALL label parsing failures and script malfunction due to Windows batch parser 512-byte boundary bugs. Recommendation: Convert file to Windows line endings (CRLF). Use tools like dos2unix, notepad++, or configure git with 'git config core.autocrlf true'. Context: File uses Unix line endings (LF-only) - 24 LF sequences found

(E018)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@distribution/examples/mcp/membrane.cmd` at line 1, This batch script starts
with the Windows-specific line "@echo off" and must be committed with CRLF line
endings to avoid cmd.exe parsing issues; convert the file
distribution/examples/mcp/membrane.cmd to use CRLF line endings (or add a
.gitattributes entry like "*.cmd text eol=crlf" if you want to enforce it), then
recommit so the repository stores/normalizes the file with CRLF.

setlocal EnableExtensions

set "SCRIPT_DIR=%~dp0"
if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"

set "dir=%SCRIPT_DIR%"

:search_up
if exist "%dir%\LICENSE.txt" if exist "%dir%\scripts\run-membrane.cmd" goto found
for %%A in ("%dir%\..") do set "next=%%~fA"
if /I "%next%"=="%dir%" goto notfound
set "dir=%next%"
goto search_up

:found
set "MEMBRANE_HOME=%dir%"
set "MEMBRANE_CALLER_DIR=%SCRIPT_DIR%"
call "%MEMBRANE_HOME%\scripts\run-membrane.cmd" %*
exit /b %ERRORLEVEL%

:notfound
>&2 echo Could not locate Membrane root. Ensure directory structure is correct.
exit /b 1
21 changes: 21 additions & 0 deletions distribution/examples/mcp/membrane.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh
# Default: ./proxies.xml (next to this script); fallback -> $MEMBRANE_HOME/conf/proxies.xml
# JAVA_OPTS: relative -D paths are auto-resolved against $MEMBRANE_HOME (absolute/URI unchanged).
# Examples:
# export JAVA_OPTS='-Dlog4j.configurationFile=examples/logging/access/log4j2_access.xml'
# export JAVA_OPTS='-Dlog4j.configurationFile=/abs/path/log4j2.xml'

SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)

dir="$SCRIPT_DIR"
while [ "$dir" != "/" ]; do
if [ -f "$dir/LICENSE.txt" ] && [ -f "$dir/scripts/run-membrane.sh" ]; then
export MEMBRANE_HOME="$dir"
export MEMBRANE_CALLER_DIR="$SCRIPT_DIR"
exec sh "$dir/scripts/run-membrane.sh" "$@"
fi
dir=$(dirname "$dir")
done

echo "Could not locate Membrane root. Ensure directory structure is correct." >&2
exit 1
4 changes: 4 additions & 0 deletions distribution/examples/mcp/start-backend.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@echo off
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use CRLF line endings for this .cmd file.

Line 1 starts a batch script that should be committed with CRLF; LF-only line endings can break label/call parsing in cmd.exe.

Suggested repo-level guard
+# .gitattributes
+*.cmd text eol=crlf
🧰 Tools
🪛 Blinter (1.0.112)

[error] 1-1: Unix line endings detected. Explanation: Batch file uses Unix line endings (LF-only) which can cause GOTO/CALL label parsing failures and script malfunction due to Windows batch parser 512-byte boundary bugs. Recommendation: Convert file to Windows line endings (CRLF). Use tools like dos2unix, notepad++, or configure git with 'git config core.autocrlf true'. Context: File uses Unix line endings (LF-only) - 4 LF sequences found

(E018)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@distribution/examples/mcp/start-backend.cmd` at line 1, The .cmd file
containing the batch entry "@echo off" must use CRLF line endings instead of LF;
update start-backend.cmd to have CRLF line endings (use your editor's
line-ending conversion or unix2dos/EditorConfig) and commit the change, and
optionally add a .gitattributes rule to force CRLF for *.cmd files to prevent
future LF-only commits.

setlocal
cd /d "%~dp0"
java -jar mcp-server-demo.jar
4 changes: 4 additions & 0 deletions distribution/examples/mcp/start-backend.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
cd "$SCRIPT_DIR" || exit 1
exec java -jar ./mcp-server-demo.jar
Loading