Skip to content

Install locally

This setup is for a test. The platform and an MCP server run as two Compose projects on one computer. The steps below use the GitLab server; another server works the same way (Install an MCP server). The route was checked on macOS with Docker Desktop. On Windows, use Git Bash for the commands.

  • Use mcp.localhost as the platform name, not localhost. Inside the server container localhost is the container itself, and nginx refuses a TLS name other than MCP_DOMAIN. Browsers and Node resolve *.localhost to the loopback address.
  • The certificate needs subjectAltName=DNS:mcp.localhost. Create it with a CA of your own.
  • The examples publish the platform on port 21443 (http 21080) on 127.0.0.1, so that it does not collide with another stack on 443.
  • A server container reaches the platform through extra_hosts, and the gateway reaches the server through host.docker.internal.

You need Docker Desktop, openssl and keytool (from any JDK).

  1. Create the CA and the certificate for mcp.localhost:

    Terminal window
    mkdir -p ~/mcp-local/ca
    cd ~/mcp-local/ca
    openssl req -x509 -newkey rsa:3072 -nodes -days 365 -keyout ca.key -out ca.crt -subj "/CN=MCP local CA" \
    -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"
    openssl req -newkey rsa:2048 -nodes -keyout tls.key -out tls.csr -subj "/CN=mcp.localhost"
    printf 'subjectAltName=DNS:mcp.localhost\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth\n' > ext.cnf
    openssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extfile ext.cnf -out tls.crt
  2. Make the browser trust ca.crt. On macOS:

    Terminal window
    sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/mcp-local/ca/ca.crt

    On Windows, in PowerShell as administrator:

    Terminal window
    certutil -addstore -f Root $HOME\mcp-local\ca\ca.crt
  3. If the system you connect (for example GitLab) uses a certificate from a company CA, save that CA certificate as ~/mcp-local/ca/company-ca.crt. The broker and the server both need it.

  1. Get the bundle and enter it:

    Terminal window
    mkdir -p ~/mcp-local
    cd ~/mcp-local
    git clone https://github.com/aiwcorpo/mcp-platform.git platform
    cd platform
  2. Copy the certificate and the CA. certs/company-ca.crt must hold your local CA, and the company CA after it if you have one:

    Terminal window
    cp ../ca/tls.crt ../ca/tls.key certs/
    cat ../ca/ca.crt > certs/company-ca.crt

    If you saved a company CA, append it: cat ../ca/company-ca.crt >> certs/company-ca.crt.

  3. Write .env. Each line is a separate command:

    Terminal window
    grep -v '^MCP_DOMAIN=' platform.env > .env
    echo COMPOSE_PROJECT_NAME=mcp-local >> .env
    echo MCP_DOMAIN=mcp.localhost >> .env
    echo MCP_BIND=127.0.0.1 >> .env
    echo MCP_HTTPS_PORT=21443 >> .env
    echo MCP_HTTP_PORT=21080 >> .env
    echo MCP_PUBLIC_ORIGIN=https://mcp.localhost:21443 >> .env

    COMPOSE_PROJECT_NAME gives the project its own volumes and networks, so a second project named mcp-platform on the same computer stays untouched.

  4. Start:

    Terminal window
    docker compose up -d
    docker compose ps

    After 3 to 5 minutes every service is healthy.

  5. Print the initial password of mcp-admin:

    Terminal window
    docker compose run --rm init show admin-password
  6. Open https://mcp.localhost:21443/auth/realms/mcp/account, sign in as mcp-admin, set a new password and an OTP. The portal is at https://mcp.localhost:21443/.

If you change company-ca.crt after the first start, run docker compose up -d, then docker compose logs init | grep warn. The log gives the docker compose restart ... command to run.

  1. Get the deploy/ directory of the server:

    Terminal window
    cd ~/mcp-local
    git clone https://github.com/aiwcorpo/mcp-server-gitlab.git server-gitlab
    cd server-gitlab/deploy
  2. Bind the server to the loopback address and make the platform name resolve inside its container:

    Terminal window
    echo MCP_GITLAB_BIND=127.0.0.1 > .env
    printf 'services:\n mcp-gitlab:\n extra_hosts: ["mcp.localhost:host-gateway"]\n' > compose.override.yaml
  3. Create the trust store of the server. It needs the local CA (to fetch the gateway’s keys) and the company CA if GitLab uses one:

    Terminal window
    keytool -importcert -noprompt -alias mcp-local -file ~/mcp-local/ca/ca.crt -keystore certs/truststore.p12 -storetype PKCS12 -storepass changeit
    keytool -importcert -noprompt -alias company-ca -file ~/mcp-local/ca/company-ca.crt -keystore certs/truststore.p12 -storetype PKCS12 -storepass changeit
    chmod 644 certs/truststore.p12

    Skip the second command if you have no company CA.

  4. Open mcp-gitlab.env and set these values. Uncomment the JAVA_TOOL_OPTIONS line:

    Terminal window
    MCP_GATEWAY_JWKS_URI=https://mcp.localhost:21443/.well-known/mcp-jwks.json
    MCP_CONNECT_URL=https://mcp.localhost:21443/connections?system={system}
    MCP_GITLAB_URL=https://<gitlab>
  5. Start the server and read its certificate fingerprint:

    Terminal window
    docker compose up -d
    docker compose logs mcp-gitlab | grep event=tls_certificate

    Keep the fingerprint for the approval in the portal. The computer must reach GitLab (company network or VPN), because both the server and the broker connect to it.

Sign in to the portal as mcp-admin and follow Servers and Systems. Use these values:

Where Value
Server address https://host.docker.internal:8443/mcp
Trust The certificate is self-signed, so the connection is pinned. Compare the fingerprint with the one from step 3.5.
Keycloak console https://mcp.localhost:21443/auth/admin/mcp/console/

Claude Code must trust the local CA and use the local address:

Terminal window
export NODE_EXTRA_CA_CERTS=$HOME/mcp-local/ca/ca.crt

Run the claude mcp add command from the portal page with the MCP address in the same shell. The address is https://mcp.localhost:21443/mcp. See Claude Code.

host.docker.internal is not defined on Linux. Create compose.override.yaml in the platform directory:

services:
gateway:
extra_hosts: ["host.docker.internal:host-gateway"]
Terminal window
cd ~/mcp-local/server-gitlab/deploy
docker compose down -v
cd ~/mcp-local/platform
docker compose down -v

down -v deletes the volumes of these two projects only. Then remove the local CA from the system certificate store.