Skip to main content

Admin UI

The Agent Admin UI (mc-agent-admin-ui-app) is the visual console for the runtime. It runs on http://localhost:9090.

Running it

By default the Admin UI runs without authentication — no Keycloak, no Docker, no database. It starts immediately and logs you in as a fixed dev user (mc_user). The only required setting is the encryption key for stored LLM credentials:

export MINDCONNECT_ENCRYPTION_SECRET_KEY="change-me-to-a-32-char-secret!!!"
mvn -f agents/server/mc-agent-admin-ui-app/pom.xml spring-boot:run

The key must be 16, 24 or 32 characters long (it is used directly as an AES key) — any other length fails at the first encrypt/decrypt.

Open http://localhost:9090 — you're in.

Under the hood this is the mindconnect.auth.enabled=false mode (the default): all routes are permitted, CSRF is off, and no OIDC is wired. You can change the auto-login username with MC_DEV_USER.

Optional: Keycloak login (for deployments)

For a deployed instance you'll want real authentication. Activate the keycloak Spring profile and the app logs users in through Keycloak — the profile provides the OAuth2 client registration and flips auth.enabled on together. (Setting MC_AUTH_ENABLED=true alone does not work: without the profile there is no client registration and the app fails to start.) Keycloak must be running before you start the app, or login will fail.

1. Start Keycloak first

cd agents/server/mc-agent-admin-ui-app
cp .env.docker.example .env.docker # first time: fill in the passwords
./start-keycloak.sh

This brings up Keycloak (+ its Postgres) from docker-compose.yml via podman compose (install podman first, or run the compose file with docker yourself) and imports the mindconnect realm. Keycloak is then at http://localhost:8180 (realm: mindconnect, client: mc-admin-ui).

2. Start the Admin UI with the keycloak profile

MINDCONNECT_ENCRYPTION_SECRET_KEY="change-me-to-a-32-char-secret!!!" \
mvn -f agents/server/mc-agent-admin-ui-app/pom.xml spring-boot:run \
-Dspring-boot.run.arguments=--spring.profiles.active=keycloak

Open http://localhost:9090 and log in via Keycloak.

Keycloak users

The imported mindconnect realm contains these seed users (passwords are set from the KC_PASSWORD_MC_* values in .env.docker):

UsernameRealm role
mc_useruser
mc_adminadmin
mc_hrhr
mc_devdev

Fixing podman clock drift (fix-podman-clock.sh)

If you run Keycloak in a podman machine on macOS, the VM clock falls behind whenever the Mac sleeps. Keycloak then signs JWTs with an expiry in the past and OIDC login fails with Jwt expired at ....

The cause: podman's default chrony config (makestep 1.0 3) only steps the clock during the first few NTP updates after boot, then refuses large corrections — so a long suspend leaves the VM permanently behind.

The fix is a one-time script:

cd agents/server/mc-agent-admin-ui-app/keycloak
./fix-podman-clock.sh

It patches the VM's chrony to makestep 1.0 -1 (step at any time), restarts chronyd, and forces an immediate resync. The change persists until podman machine reset, after which clock drift self-heals within ~64s of each future suspend.

When to run it

Run it once per podman machine — or any time login starts failing with a "Jwt expired" error after your Mac has been asleep.

The main sections

The navigation has seven top-level entries:

SectionWhat you do there
AgentsCreate, edit, delete and copy agents. In the detail view: configure tools and start or continue sessions.
ToolsBrowse the available tools, inspect their schemas, and test a tool.
LLM ConfigsCreate, edit, delete and test LLM configs. API keys come from environment variables.
WorkflowsThe embedded workflow admin UI (mc-workflow-admin-rest): edit, save and run workflows.
Vector StoresManage vector-store templates and stores, upload files, run semantic searches.
MigrationsReview and apply changes to the bundled seed data (agents, LLM configs, workflows).
APIEmbedded Swagger UI for the REST API under /api/**.

The task manager

The header carries a small badge that says what the task queue is doing right now — 3 running · 2 waiting, or idle. It is live: the page attaches to a server-sent event stream (/admin/api/tasks/sse) once, and the stream stays attached while you navigate, so the count is current on every page without polling.

A click on the badge opens the task queue, the admin UI's Task Manager:

  • Running now — the live tasks as a tree, the way the queue links them: a chat turn, under it the tool calls it dispatched, and under a run_agent call the sub-agent's turn. Every row shows the agent or tool, what it is doing (session title, round), the status (running, queued, suspended while a turn waits on its sub-tasks, cancelling), the user it belongs to and how long it has been at it.
  • Finished recently — the last tasks that completed, failed or were cancelled; a failed one opens to show the reason.
  • Cancel — the ban icon on a row. Cancel is cooperative (a running task stops at its next checkpoint) and cascades: cancelling a turn takes its tool calls and sub-agents with it. It is offered for your own tasks only — the tasks whose session belongs to the signed-in user; other users' tasks are visible but not cancellable.

The dialog updates itself over the same stream while it is open.