Skip to content
Merged
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Please contact [hello@swirlaiconnect.com](mailto:hello@swirlaiconnect.com) for m
- [PostgreSQL](doc/service-setup.md#postgresql)
- [Connecting Swirl to the Enterprise](doc/service-setup.md#connecting-swirl-to-the-enterprise)
- [Connecting to Microsoft IDP](doc/service-setup.md#connecting-to-microsoft-idp)

- [Configuring MCP Proxy (optional)](doc/mcp-proxy-setup.md)
## Controlling and Monitoring Swirl Service
- [Controlling Swirl Service](doc/controlling-swirl-service.md)
- Start, stop, and restart the Swirl service.
Expand All @@ -52,6 +52,7 @@ Please contact [hello@swirlaiconnect.com](mailto:hello@swirlaiconnect.com) for m

# Downloads
- [Swirl Enterprise Edition Docker Environment 4.3.0 tar file](https://github.com/swirlai/docker-compose/archive/refs/tags/v4_3_0_0.tar.gz)
- [Swirl Enterprise Edition Docker Environment 4.3.0 with MCP 1.0.5 tar file](https://github.com/swirlai/docker-compose/archive/refs/tags/v4_3_0_0_mcp_v1_0_5.tar.gz)

# Additional Documentation

Expand Down
18 changes: 18 additions & 0 deletions doc/mcp-proxy-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Overview
The MCP server proxy acts as a TCP server that exposes a set of tools, resources, and prompts for clients to interact with.
It handles authentication, manages client sessions, and delegates requests (such as listing tools, resources, and prompts, or
executing commands) to internal logic. It serves as a gateway for clients to access and interact with the
MCP (Multi-Component Platform) backend services over TCP.

## Setting up MCP Proxy
* MCP_ENABLED: Set to "true" to enable the MCP proxy service.
* MCP_VERSION: Specifies the version of the MCP proxy to use (e.g., "v1_0_5").
* MCP_PORT: The port on which the MCP proxy will listen for incoming connections (defaults "9000").
* SWIRL_MCP_USERNAME: Required authentication username for accessing the MCP proxy.
* SWIRL_MCP_PASSWORD: Required authentication password for accessing the MCP proxy.
* SWIRL_API_USERNAME: The username for the Swirl API, used for MCP to Swirl authentication.
* SWIRL_API_PASSWORD: The password for the Swirl API, used for MCP to Swirl authentication.
* MCP_SWIRL_BASE_PATH: The base URL path for the Swirl API that MCP will interact with (e.g., "https://swirl.example.com/api").
* MCP_TIMEOUT: Optional timeout setting for MCP operations (in seconds, defaults to "30").

The MCP proxy runs as a container named `swirl_mcp` and is controlled via the same systemd service as Swirl.
39 changes: 27 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,33 @@ services:
timeout: 5s
retries: 5

mcp:
profiles: [ "all", "svc", "mcp" ]
image: swirlai/release-mcp-proxy-enterprise:${MCP_VERSION}
container_name: swirl_mcp
networks: [ "swirl" ]
ports:
- "${MCP_PORT}:${MCP_PORT}" # expose the MCP port
environment:
SWIRL_API_BASE: "${MCP_SWIRL_BASE_URL}"
SWIRL_API_BASE_PATH: "${MCP_SWIRL_BASE_PATH}"
SWIRL_API_PASSWORD: "${SWIRL_API_PASSWORD}"
SWIRL_API_USERNAME: "${SWIRL_API_USERNAME}"
SWIRL_MCP_SERVER_HOST: "0.0.0.0"
SWIRL_MCP_SERVER_PORT: "${MCP_PORT}"
SWIRL_MCP_SWIRL_API_TIMEOUT: "${MCP_TIMEOUT}"
SWIRL_MCP_PASSWORD: "${SWIRL_MCP_PASSWORD}"
SWIRL_MCP_USERNAME: "${SWIRL_MCP_USERNAME}"
healthcheck:
test: [ "CMD-SHELL", "/app/scripts/check-mcp-health.sh || exit 1" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
depends_on:
swirl:
condition: service_healthy

tika:
profiles: ["all", "svc", "tika"]
image: swirlai/release-tika-enterprise:${TIKA_VERSION}
Expand Down Expand Up @@ -113,18 +140,6 @@ services:
networks: ["swirl"]
command: ["python", "swirl.py", "migrate", "-v"]

swirl-reload:
profiles: ["all", "reload"]
image: swirlai/release-swirl-search-enterprise:${SWIRL_VERSION}
container_name: swirl_app_reload_prompts
env_file:
- .env
networks: ["swirl"]
command: ["python", "swirl.py", "reload_ai_prompts"]
depends_on:
swirl:
condition: service_healthy

swirl:
profiles: ["all", "svc", "swirl"]
image: swirlai/release-swirl-search-enterprise:${SWIRL_VERSION}
Expand Down
34 changes: 28 additions & 6 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,32 @@
CERTBOT_EMAIL=admin@swirl.today # CHANGE_ME
CERTBOT_VERSION=
NGINX_VERSION=
POSTGRES_VERSION=
REDIS_VERSION=
SWIRL_VERSION=
TIKA_VERSION=
TTM_VERSION=
POSTGRES_VERSION=16
REDIS_VERSION=8
SWIRL_VERSION=v4_3_0_0
TIKA_VERSION=v4_3_0_0
TTM_VERSION=v4_3_0_0
MCP_VERSION=v1_0_5
USE_CERT=false # CHANGE_ME
USE_LOCAL_POSTGRES=true # CHANGE_ME
USE_NGINX=false # CHANGE_ME
USE_TLS=false # CHANGE_ME

# Swirl
ADMIN_USER_EMAIL="admin@swirl.today" # CHANGE_ME

# SWIRL_FQDN will be automatically added to this list
ALLOWED_HOSTS="localhost,127.0.0.1,swirl," # CHANGE_ME

AXES_CLIENT_IP_CALLABLE=""
AZ_GOV_COMPATIBLE=false # CHANGE_ME
CACHE_REDIS_URL="redis://redis:6379/1"
CELERY_BROKER_URL="redis://redis:6379/0"
CELERY_RESULT_BACKEND="redis://redis:6379/0"
CSRF_TRUSTED_ORIGINS="http://localhost:8000" # CHANGE_ME

# If undefined, autopopulated by PROTOCOL, SWIRL_FQDN, and PROT
# CSRF_TRUSTED_ORIGINS="http://localhost:8000" # CHANGE_ME

GOOGLE_APPLICATION_CREDENTIALS="/app/secrets/google-credentials.json"

# Uncomment and set the GOOGLE_AUTH_CLIENT_ID if you want to use Google authentication
Expand All @@ -33,6 +40,12 @@ MICROSOFT_CLIENT_ID=""
MICROSOFT_CLIENT_SECRET=""
MICROSOFT_REDIRECT_URI=""

MCP_ENABLED=false
MCP_PORT="9000"
MCP_SWIRL_BASE_URL="0.0.0.0"
MCP_SWIRL_BASE_PATH="/api/swirl"
MCP_TIMEOUT="30"

# Uncomment and set the following if you want to use Microsoft authentication
# MS_AUTH_CLIENT_ID=""
# MS_TENANT_ID=""
Expand All @@ -59,6 +72,7 @@ SQL_ENGINE="django.db.backends.postgresql"
SQL_HOST="postgres" # CHANGE_ME
SQL_PORT="5432" # CHANGE_ME
SQL_SSLMODE="prefer" # CHANGE_ME

SWIRL_ES_VERSION="8"
SWIRL_EXPLAIN="True"
SWIRL_FQDN="localhost" # CHANGE_ME
Expand All @@ -73,6 +87,14 @@ SWIRL_TEXT_SUMMARIZATION_URL="http://ttm:7029"
TIKA_SERVER_ENDPOINT="http://tika:9998"

# Secrets
## MCP Endpoint Authentication
SWIRL_MCP_USERNAME="" # CHANGE_ME
SWIRL_MCP_PASSWORD="" # CHANGE_ME
## User in Swirl to which MCP requests will be authenticated
SWIRL_API_USERNAME=""
SWIRL_API_PASSWORD=""

## CHANGE THESE VALUES
ADMIN_PASSWORD="" # CHANGE_ME
GOOGLE_CREDENTIALS="" # CHANGE_ME
SQL_PASSWORD="" # CHANGE_ME
Expand Down
6 changes: 6 additions & 0 deletions scripts/swirl-load-job.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@ fi
python swirl.py load_data
python swirl.py reload_ai_prompts
python swirl.py load_branding

# Optionally Swirl API User if environment variables are set
if [ -n "$SWIRL_API_USERNAME" ] && [ -n "$SWIRL_API_PASSWORD" ]; then
echo "MCP Support: Creating Swirl API user: $SWIRL_API_USERNAME"
python manage.py shell -c "from django.contrib.auth.models import User, Group; user=User.objects.create_user(username='${SWIRL_API_USERNAME}', password='${SWIRL_API_PASSWORD}'); group, _ = Group.objects.get_or_create(name='swirl_auto_provisioned_group'); user.groups.add(group)"
fi
21 changes: 21 additions & 0 deletions scripts/swirl-load.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@ set -e # Exit the script immediately if any command fails

echo "Setting up swirl"

# auto populating Variables
export PROTOCOL=${PROTOCOL:-http}
if [ -z "$PORT" ]; then
export CSRF_TRUSTED_ORIGINS=${CSRF_TRUSTED_ORIGINS:-$PROTOCOL://$SWIRL_FQDN}
else
export CSRF_TRUSTED_ORIGINS=${CSRF_TRUSTED_ORIGINS:-$PROTOCOL://$SWIRL_FQDN:$PORT}
fi

# if $SWIRL_FQDN is not in ALLOWED_HOSTS, add it
if [[ -z "$ALLOWED_HOSTS" ]]; then
export ALLOWED_HOSTS=localhost,$SWIRL_FQDN
elif [[ ! "$ALLOWED_HOSTS" =~ (^|,)$SWIRL_FQDN(,|$) ]]; then
export ALLOWED_HOSTS=$ALLOWED_HOSTS,$SWIRL_FQDN
fi

echo "SWIRL_FQDN is set to: $SWIRL_FQDN"
echo "ALLOWED_HOSTS is set to: $ALLOWED_HOSTS"
echo "CSRF_TRUSTED_ORIGINS is set to: $CSRF_TRUSTED_ORIGINS"



# Remove any existing swirl configuration directory
rm -rf .swirl

Expand Down
9 changes: 5 additions & 4 deletions scripts/swirl-service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,12 @@ else
cp $PARENT_DIR/nginx/nginx-template.notls $PARENT_DIR/nginx/nginx.template
fi

if [ "$MCP_ENABLED" == "true" ]; then
COMPOSE_PROFILES="$COMPOSE_PROFILES,mcp"
fi

ONETIME_JOB_FLAG="$PARENT_DIR/.swirl-application-setup-job-complete.flag"
if [ -f "$ONETIME_JOB_FLAG" ]; then
log "Application setup job already completed. Skipping initial setup."
COMPOSE_PROFILES="$COMPOSE_PROFILES,reload"
else
if [ ! -f "$ONETIME_JOB_FLAG" ]; then
log "Setting up run one-time application setup job..."
# Run the initial setup job
COMPOSE_PROFILES="$COMPOSE_PROFILES,setup"
Expand Down