AtlatestRepositoryfolio
1
#!/usr/bin/env bash2
# Regression test for MCP tool-dispatch error-isolation bug.3
#4
# Before the fix, a single tool-handler error poisoned in-process state so5
# subsequent responses serialised to the literal "#<object>" string and the6
# whole session was wedged. This test sends:7
#8
# 1. initialize + notifications/initialized9
# 2. tools/call folio/note-read with wrong arg key (path: instead of name:) → raises10
# 3. tools/call folio/status with valid empty args → should succeed11
#12
# and asserts neither of the two tool-call responses contains the literal13
# "#<object>" text. Exit 0 on pass, non-zero on fail.14
set -u16
FOLIO=${FOLIO:-$(dirname "$0")/../build/release/bin/folio}17
if [ ! -x "$FOLIO" ]; then18
FOLIO=$(dirname "$0")/../build/dev/bin/folio19
fi20
if [ ! -x "$FOLIO" ]; then21
echo "ERROR: no folio binary found at build/release/bin/folio or build/dev/bin/folio" >&222
exit 223
fi25
TMPDIR_ROOT=$(mktemp -d -t folio-err-iso.XXXXXX)26
export FOLIO_ROOT="$TMPDIR_ROOT"27
trap 'rm -rf "$TMPDIR_ROOT"' EXIT29
RESP_FILE=$(mktemp)30
(31
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{}}}'32
sleep 0.333
printf '%s\n' '{"jsonrpc":"2.0","method":"notifications/initialized"}'34
sleep 0.335
printf '%s\n' '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"folio/note-read","arguments":{"path":"whatever.md"}}}'36
sleep 0.537
printf '%s\n' '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"folio/status","arguments":{}}}'38
sleep 0.539
) | "$FOLIO" 2>/dev/null > "$RESP_FILE"41
FAIL=042
LINE2=$(sed -n '2p' "$RESP_FILE")43
LINE3=$(sed -n '3p' "$RESP_FILE")45
if [ -z "$LINE2" ] || [ -z "$LINE3" ]; then46
echo "FAIL: expected 3 response lines; got $(wc -l < "$RESP_FILE")" >&247
cat "$RESP_FILE" >&248
rm -f "$RESP_FILE"49
exit 150
fi52
if echo "$LINE2" | grep -Fq '#<object>'; then53
echo "FAIL: poisoned tool call response contains #<object>:" >&254
echo " $LINE2" >&255
FAIL=156
fi57
if echo "$LINE3" | grep -Fq '#<object>'; then58
echo "FAIL: follow-up valid call response contains #<object>:" >&259
echo " $LINE3" >&260
FAIL=161
fi62
if ! echo "$LINE3" | grep -Fq 'Folio Status'; then63
echo "FAIL: follow-up valid call did not contain 'Folio Status' marker:" >&264
echo " $LINE3" >&265
FAIL=166
fi68
rm -f "$RESP_FILE"70
if [ $FAIL -eq 0 ]; then71
echo "PASS: mcp tool-dispatch error isolation"72
exit 073
else74
exit 175
fi