# Agent Test Backend / Portal PoC Browser-based PoC tester and hardcoded Portal Registry screen for: ```text Browser -> Agent Test Backend -> MCP Server -> Tool Server ``` ## Ports ```text Tool Server http://localhost:9092 MCP Server http://localhost:8080/mcp Agent Test Backend http://localhost:7070 ``` ## STS Run Import this folder as an existing Gradle project: ```text C:\Users\hyo\Documents\Codex\agent-test-backend ``` Run `com.example.agenttest.AgentTestBackendApplication`. Default environment: ```text AGENT_TEST_PORT=7070 MCP_ENDPOINT_URL=http://localhost:8080/mcp MCP_PROTOCOL_VERSION=2025-11-25 TOOL_MANIFEST_URL=http://localhost:9092/tool-manifest TOOL_SERVER_API_KEY=tool-server-key PORTAL_REGISTRY_REVISION=1 PORTAL_ROUTE_KEY=external TOOL_SERVICE_DOMAIN=http://localhost:9092 ``` Open: ```text http://localhost:7070 ``` ## Recommended Verification Order 1. Start Tool Server in STS. 2. Start MCP Server with Tool Server environment values. 3. Start Agent Test Backend. 4. Open `http://localhost:7070`. 5. Click `Initialize`, `Tools/List`, then run `Agent Chat` or `Tools/Call`. ## Portal PoC Scope The current screen intentionally uses hardcoded registry data instead of DB tables: ```text MCP Route external -> http://localhost:8080/mcp Tool Service external-tools -> http://localhost:9092/tool-manifest Mapping external -> external-tools ``` The MCP-facing Portal Registry API is: ```text GET http://localhost:7070/api/portal/registry/external ``` For this PoC, MCP can use these IntelliJ environment variables after applying `C:\Users\hyo\Documents\Codex\mcp-portal-registry.patch` to the MCP project: ```text MCP_DISCOVERY_ENABLED=true MCP_PORTAL_ENABLED=true MCP_PORTAL_ROUTE_KEY=external MCP_PORTAL_REGISTRY_URL=http://localhost:7070/api/portal/registry/external MCP_REGISTRY_REFRESH_INTERVAL_SECONDS=60 ``` `POST /api/agent/chat` is a first Agent Backend skeleton. It currently uses a simple rule-based planner so it can run without an OpenAI API key: ```text "서울 날씨 알려줘" -> external.weather_lookup "달러 환율 알려줘" -> external.exchange_rate ``` Later, replace the rule-based planner with Codex/OpenAI model selection while keeping the same MCP `tools/list` and `tools/call` boundary. ## Portal Tool Bundle Management The Portal now manages both seeded pull-discovery bundles through one API and UI flow: ```text external-tools -> http://localhost:9092/tool-manifest business-tools -> http://localhost:9090/tool-manifest ``` Bundle APIs: ```text GET /api/portal/bundles POST /api/portal/bundles PUT /api/portal/bundles/{bundleId} POST /api/portal/bundles/{bundleId}/sync ``` The API key is write-only. Read responses expose only `apiKeyConfigured`, and logs never contain the key value. Manifest synchronization validates the configured Bundle ID, Tool name prefix, required metadata objects, and the configured execution endpoint for every mapped Tool. Business Tool endpoint mappings are owned by the Portal/MCP configuration rather than the manifest: ```text business.customer_search -> POST http://localhost:9090/internal/tools/customer-search business.order_status -> POST http://localhost:9090/internal/tools/order-status business.ticket_create -> POST http://localhost:9090/internal/tools/ticket-create ``` The Bundle definitions and synchronized snapshots are currently held in memory because this PoC does not include a database dependency or an existing schema/migration framework. Therefore no DB migration is required. Restarting the Portal restores the two seeded definitions and clears cached manifest snapshots. For persistent operation, the `PortalBundleService` store is the boundary to replace with the project's chosen repository and migration framework. Start the business Tool server with pull discovery only: ```text TOOL_AUTO_REGISTER_ENABLED=false TOOL_HEARTBEAT_ENABLED=false TOOL_SERVER_PORT=9090 ``` After starting the Tool server, open the Portal and click `Sync Manifest` for `business-tools`.