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.
Rules for the local name
Section titled “Rules for the local name”- Use
mcp.localhostas the platform name, notlocalhost. Inside the server containerlocalhostis the container itself, and nginx refuses a TLS name other thanMCP_DOMAIN. Browsers and Node resolve*.localhostto 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 throughhost.docker.internal.
You need Docker Desktop, openssl and keytool (from any JDK).
1. Create a CA and a certificate
Section titled “1. Create a CA and a certificate”-
Create the CA and the certificate for
mcp.localhost:Terminal window mkdir -p ~/mcp-local/cacd ~/mcp-local/caopenssl 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.cnfopenssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extfile ext.cnf -out tls.crt -
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.crtOn Windows, in PowerShell as administrator:
Terminal window certutil -addstore -f Root $HOME\mcp-local\ca\ca.crt -
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.
2. Start the platform
Section titled “2. Start the platform”-
Get the bundle and enter it:
Terminal window mkdir -p ~/mcp-localcd ~/mcp-localgit clone https://github.com/aiwcorpo/mcp-platform.git platformcd platform -
Copy the certificate and the CA.
certs/company-ca.crtmust 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.crtIf you saved a company CA, append it:
cat ../ca/company-ca.crt >> certs/company-ca.crt. -
Write
.env. Each line is a separate command:Terminal window grep -v '^MCP_DOMAIN=' platform.env > .envecho COMPOSE_PROJECT_NAME=mcp-local >> .envecho MCP_DOMAIN=mcp.localhost >> .envecho MCP_BIND=127.0.0.1 >> .envecho MCP_HTTPS_PORT=21443 >> .envecho MCP_HTTP_PORT=21080 >> .envecho MCP_PUBLIC_ORIGIN=https://mcp.localhost:21443 >> .envCOMPOSE_PROJECT_NAMEgives the project its own volumes and networks, so a second project namedmcp-platformon the same computer stays untouched. -
Start:
Terminal window docker compose up -ddocker compose psAfter 3 to 5 minutes every service is healthy.
-
Print the initial password of
mcp-admin:Terminal window docker compose run --rm init show admin-password -
Open
https://mcp.localhost:21443/auth/realms/mcp/account, sign in asmcp-admin, set a new password and an OTP. The portal is athttps://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.
3. Start an MCP server
Section titled “3. Start an MCP server”-
Get the
deploy/directory of the server:Terminal window cd ~/mcp-localgit clone https://github.com/aiwcorpo/mcp-server-gitlab.git server-gitlabcd server-gitlab/deploy -
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 > .envprintf 'services:\n mcp-gitlab:\n extra_hosts: ["mcp.localhost:host-gateway"]\n' > compose.override.yaml -
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 changeitkeytool -importcert -noprompt -alias company-ca -file ~/mcp-local/ca/company-ca.crt -keystore certs/truststore.p12 -storetype PKCS12 -storepass changeitchmod 644 certs/truststore.p12Skip the second command if you have no company CA.
-
Open
mcp-gitlab.envand set these values. Uncomment theJAVA_TOOL_OPTIONSline:Terminal window MCP_GATEWAY_JWKS_URI=https://mcp.localhost:21443/.well-known/mcp-jwks.jsonMCP_CONNECT_URL=https://mcp.localhost:21443/connections?system={system}MCP_GITLAB_URL=https://<gitlab> -
Start the server and read its certificate fingerprint:
Terminal window docker compose up -ddocker compose logs mcp-gitlab | grep event=tls_certificateKeep 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.
4. Add the server in the portal
Section titled “4. Add the server in the portal”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/ |
5. Connect Claude Code
Section titled “5. Connect Claude Code”Claude Code must trust the local CA and use the local address:
export NODE_EXTRA_CA_CERTS=$HOME/mcp-local/ca/ca.crtRun 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"]Remove everything
Section titled “Remove everything”cd ~/mcp-local/server-gitlab/deploydocker compose down -vcd ~/mcp-local/platformdocker compose down -vdown -v deletes the volumes of these two projects only. Then remove the local CA from the system certificate store.
