[Backend][MCPServer] Pre-deployment cleanup for SpikerSoft.AI.MCPServer — demo leftovers, unregistered prompts, no observability wiring, no stack/CI #563

Closed
opened 2026-07-14 13:59:53 +00:00 by spikerj · 2 comments
Owner

QA Team — filed 2026-07-14 from the README audit findings, per spikerj's triage decision: the MCP server is headed to production ("pending rollout") and needs cleanup first. Items, all verified in code:

  1. Delete demo leftovers: EchoTool.AddCustomer ("Adds a customer to marks software with AI") is a live registered MCP tool that swallows all exceptions; MyPrompts is template boilerplate.
  2. Register or delete the prompt classes: CalendarPrompts (calendar summarization/scheduling templates) exists but WithPromptsFromAssembly() is never called in Program.cs, so no prompts are actually exposed.
  3. Observability wiring: no Serilog→Seq, no OpenTelemetry→Jaeger (Jaeger:EndPoint) — every other deployable service has both (AGENTS.md non-negotiable #1). Add before deployment.
  4. Dockerfile: copies ~11 sibling project files (SpikerSoft.Common, .Data, .Business.*, .Storage) that the csproj does not reference — trim to actual dependencies.
  5. Config hygiene: SpikerSoftApi:TokenEndpoint is configured but never read (token URL hard-coded in Program.cs) — honor the key or delete it; DefaultUserId in appsettings is a truncated GUID ('d1af2cdc-1e8c-4cb8-9ce7-f...') — fix or remove; MongoDB.EntityFrameworkCore + NRedisStack package refs are unused.
  6. Deployment scaffolding: stack file in spikersoft-infrastructure + Gitea CI workflow (build/publish/deploy) — none exist today.

The project README (rewritten in the audit) now carries a "pending rollout" status banner pointing at this ticket's class of work.

**QA Team** — filed 2026-07-14 from the README audit findings, per spikerj's triage decision: **the MCP server is headed to production ("pending rollout") and needs cleanup first.** Items, all verified in code: 1. **Delete demo leftovers:** `EchoTool.AddCustomer` ("Adds a customer to marks software with AI") is a live registered MCP tool that swallows all exceptions; `MyPrompts` is template boilerplate. 2. **Register or delete the prompt classes:** `CalendarPrompts` (calendar summarization/scheduling templates) exists but `WithPromptsFromAssembly()` is never called in Program.cs, so no prompts are actually exposed. 3. **Observability wiring:** no Serilog→Seq, no OpenTelemetry→Jaeger (`Jaeger:EndPoint`) — every other deployable service has both (AGENTS.md non-negotiable #1). Add before deployment. 4. **Dockerfile:** copies ~11 sibling project files (SpikerSoft.Common, .Data, .Business.*, .Storage) that the csproj does not reference — trim to actual dependencies. 5. **Config hygiene:** `SpikerSoftApi:TokenEndpoint` is configured but never read (token URL hard-coded in Program.cs) — honor the key or delete it; `DefaultUserId` in appsettings is a truncated GUID ('d1af2cdc-1e8c-4cb8-9ce7-f...') — fix or remove; `MongoDB.EntityFrameworkCore` + `NRedisStack` package refs are unused. 6. **Deployment scaffolding:** stack file in spikersoft-infrastructure + Gitea CI workflow (build/publish/deploy) — none exist today. The project README (rewritten in the audit) now carries a "pending rollout" status banner pointing at this ticket's class of work.
Author
Owner

Audited against origin/master — NOT DONE. All six items outstanding. File-verified:

  1. Demo leftovers live: Program.cs:88 EchoTool, :91 AddCustomer, :106 MyPrompts.
  2. Prompts still unregistered: the builder chain is AddMcpServer().WithHttpTransport().WithToolsFromAssembly() — no WithPromptsFromAssembly(). So Tools/CalendarPrompts.cs exposes nothing. (Another instance of the codebase's recurring shape: the code exists, the registration doesn't.)
  3. No observability: zero Serilog / OpenTelemetry / Jaeger references anywhere under SpikerSoft.AI.MCPServer/ — except README.md:106-107, which documents their absence.
  4. Dockerfile still copies 11 unreferenced sibling csprojs (Common, Data, Contracts.SignalR, Business, Business.Identity, Business.Books, Business.Ai, Business.Scheduling, Business.CodeExecution, Storage) while the csproj declares no ProjectReference at all.
  5. Config hygiene untouched: TokenEndpoint is read into Options/SpikerSoftApiOptions.cs:7 and never consumed; DefaultUserId is still the truncated "d1af2cdc-1e8c-4cb8-9ce7-f...", consumed at Services/AuthenticatedSpikerSoftApiClient.cs:44; MongoDB.EntityFrameworkCore + NRedisStack still in the csproj (also listed on #578).
  6. No deployment scaffolding: no MCP stack file in spikersoft-infrastructure, and none of the 36 backend workflows is an MCPServer pipeline.

One adjacent change did land but belongs to a different ticket: Program.cs now reads Keycloak:BaseUrl with a prod fallback, tagged "See #676".

On the plaintext ClientSecret in appsettings.json — I verified it (/SpikerSoftApi/ClientSecret, a literal, 32 chars, not ${VAR} indirection). It is already tracked: it's item 3 of #633 ("Keycloak client secret for spikersoft-backend — SpikerSoft.AI.MCPServer/appsettings.json + appsettings.Production.json"), which I re-audited earlier today and confirmed still committed. So it needs rotating there rather than a new ticket — flagging the linkage so it isn't filed twice or assumed handled by this cleanup.

Sequencing thought: item 6 (stack + CI) is the one that makes the rest verifiable — until this deploys anywhere, items 1–5 can't be validated against a running service. But it's also the item that would make a service carrying a committed credential publicly reachable, and #857 confirms the registry currently serves anonymous pull tokens, so its image would be freely downloadable. I'd do #633's rotation before item 6, not after.

Audited against `origin/master` — **NOT DONE. All six items outstanding.** File-verified: 1. **Demo leftovers live:** `Program.cs:88` `EchoTool`, `:91` `AddCustomer`, `:106` `MyPrompts`. 2. **Prompts still unregistered:** the builder chain is `AddMcpServer().WithHttpTransport().WithToolsFromAssembly()` — no `WithPromptsFromAssembly()`. So `Tools/CalendarPrompts.cs` exposes nothing. (Another instance of the codebase's recurring shape: the code exists, the registration doesn't.) 3. **No observability:** zero `Serilog` / `OpenTelemetry` / `Jaeger` references anywhere under `SpikerSoft.AI.MCPServer/` — except `README.md:106-107`, which documents their absence. 4. **Dockerfile still copies 11 unreferenced sibling csprojs** (Common, Data, Contracts.SignalR, Business, Business.Identity, Business.Books, Business.Ai, Business.Scheduling, Business.CodeExecution, Storage) while the csproj declares **no** `ProjectReference` at all. 5. **Config hygiene untouched:** `TokenEndpoint` is read into `Options/SpikerSoftApiOptions.cs:7` and never consumed; `DefaultUserId` is still the truncated `"d1af2cdc-1e8c-4cb8-9ce7-f..."`, consumed at `Services/AuthenticatedSpikerSoftApiClient.cs:44`; `MongoDB.EntityFrameworkCore` + `NRedisStack` still in the csproj (also listed on #578). 6. **No deployment scaffolding:** no MCP stack file in spikersoft-infrastructure, and none of the 36 backend workflows is an MCPServer pipeline. One adjacent change *did* land but belongs to a different ticket: `Program.cs` now reads `Keycloak:BaseUrl` with a prod fallback, tagged "See #676". **On the plaintext `ClientSecret` in `appsettings.json`** — I verified it (`/SpikerSoftApi/ClientSecret`, a literal, 32 chars, not `${VAR}` indirection). It is **already tracked**: it's item 3 of **#633** ("Keycloak client secret for `spikersoft-backend` — `SpikerSoft.AI.MCPServer/appsettings.json` + `appsettings.Production.json`"), which I re-audited earlier today and confirmed still committed. So it needs rotating there rather than a new ticket — flagging the linkage so it isn't filed twice or assumed handled by this cleanup. **Sequencing thought:** item 6 (stack + CI) is the one that makes the rest verifiable — until this deploys anywhere, items 1–5 can't be validated against a running service. But it's also the item that would make a service carrying a committed credential publicly reachable, and **#857** confirms the registry currently serves anonymous pull tokens, so its image would be freely downloadable. I'd do #633's rotation before item 6, not after.
Author
Owner

Migrated as part of the umbrella-tracker breakup.

This ticket needed changes in more than one repo, so it became one issue per repo:

Verified 2026-08-07 against spikersoft-backend@98102023 and spikersoft-infrastructure@86d03ff6 — all six items still outstanding: Program.cs:88/:91/:106 demo leftovers live, no WithPromptsFromAssembly(), zero Serilog/OTel references in the project, Dockerfile still copies 11 unreferenced csprojs against a csproj with no ProjectReference, TokenEndpoint bound-but-unread and DefaultUserId still truncated, and no stack file or CI workflow anywhere.
Status: not started.

Sequencing note carried into both children: rotate the committed ClientSecret (#633 item 3) before deploying, since #857 confirms anonymous registry pulls.

Closing here. Work now lives in the repos that hold the fix, so fixes #N in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.

— Opus 5 Agent

Migrated as part of the umbrella-tracker breakup. This ticket needed changes in more than one repo, so it became one issue per repo: - Backend (items 1–5 + the Gitea CI workflow, which lives in `spikersoft-backend/.gitea/workflows/`): **spikerj/spikersoft-backend#567** - Infrastructure (the swarm stack file / deploy side of item 6): **spikerj/spikersoft-infrastructure#184** Verified 2026-08-07 against `spikersoft-backend@98102023` and `spikersoft-infrastructure@86d03ff6` — **all six items still outstanding**: `Program.cs:88/:91/:106` demo leftovers live, no `WithPromptsFromAssembly()`, zero Serilog/OTel references in the project, Dockerfile still copies 11 unreferenced csprojs against a csproj with no `ProjectReference`, `TokenEndpoint` bound-but-unread and `DefaultUserId` still truncated, and no stack file or CI workflow anywhere. Status: not started. Sequencing note carried into both children: rotate the committed `ClientSecret` (#633 item 3) **before** deploying, since #857 confirms anonymous registry pulls. Closing here. Work now lives in the repos that hold the fix, so `fixes #N` in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only. — Opus 5 Agent
Sign in to join this conversation.