LearnNewsExamplesServices
Frontmatter
id10980
titleDocument MCP server BaseServer extension contract
stateClosed
labels
documentationenhancementaiarchitecture
assigneesneo-opus-4-7
createdAtMay 8, 2026, 7:13 PM
updatedAtMay 12, 2026, 4:09 AM
githubUrlhttps://github.com/neomjs/neo/issues/10980
authorneo-opus-4-7
commentsCount0
parentIssue10965
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 8, 2026, 7:39 PM

Document MCP server BaseServer extension contract

Closeddocumentationenhancementaiarchitecture
neo-opus-4-7
neo-opus-4-7 commented on May 8, 2026, 7:13 PM

Context

Filed 2026-05-08 as the AC10 follow-up from M2 #10965. M2 substrate landed in dev across PR1 (#10966 BaseServer scaffold) + PR2-PR6 (5 per-server migrations: knowledge-base #10973, github-workflow #10974, neural-link #10975, memory-core #10977, file-system #10976) on 2026-05-08. AC10 of #10965"Documentation: either new learn/agentos/tooling/MCPServerBaseClass.md OR §-section added to learn/agentos/tooling/Introduction.md describing the extension contract + when to override which hook" — was deferred during the per-server migration sequence.

Per feedback_close_as_completed_authority discipline, #10965 stays open until AC10 lands or operator resolves the gap explicitly.

The Problem

ai/mcp/server/BaseServer.mjs has a substantial extension surface (2 required hooks + 8+ optional hooks + composable lifecycle hooks + the boot() overridable seam). Future per-server-authors (or external developers building on the substrate via M6 SDK migration) need a single canonical doc to:

  1. Understand which hooks to override for which per-server behavior
  2. Choose between the canonical boot() vs custom boot() override paths
  3. Use the right escape-hatch for non-canonical bootstrap orders
  4. Avoid re-inventing patterns already covered by hooks (e.g. onHealthGateFailure for telemetry, beforeToolDispatch for pre-validation, wrapDispatch for context wrapping)

Currently this knowledge is scattered across:

  • BaseServer.mjs class-level JSDoc (good but verbose)
  • 5 per-server Server.mjs files (concrete examples, but no comparative narrative)
  • BaseServer.spec.mjs unit tests (validates contracts but reads as test code, not pedagogy)

The Architectural Reality

Target surface: learn/agentos/tooling/MCPServerBaseClass.md (new) OR §-section in learn/agentos/tooling/Introduction.md (existing — preferred since Introduction.md already covers the broader MCP server architecture).

Audience:

  • Per-server-authors maintaining the 5 in-tree servers
  • M6 SDK migration consumers (Tier-1 only) — external users building on the same primitive
  • Future cross-family agents picking up M-milestone work cold

Recommended pattern: §-section in Introduction.md keeps the doc ecosystem flat (no proliferation of doc files); a dedicated MCPServerBaseClass.md is appropriate only if the section grows past ~300 lines.

Decision: prefer §-section in Introduction.md; promote to dedicated file if section bloat warrants.

The Fix

Add §"MCP Server Base Class — extension contract" section to learn/agentos/tooling/Introduction.md covering:

  1. What BaseServer is — class-hierarchy ancestor for all 5 MCP servers; standardizes bootstrap/setupRequestHandlers/result-formatting/transport-connect into shared template-method scaffolding
  2. The two required override hooksgetServerMetadata, getToolService. With concrete examples from the 5 in-tree servers
  3. Optional override hooks with when-to-use guidance:
    • getDependentServices — for services with ready() to await
    • getHealthExemptTools — for tools that bypass the health gate
    • getHealthService — for health-gated dispatch (default null = no gate)
    • wrapDispatch — for tool-dispatch context wrapping (memory-core: RequestContextService.run() for tenant binding)
    • beforeToolDispatch — for pre-dispatch validation that must fire before health gate (memory-core: AuthMiddleware.validateNoIdentitySpoof)
    • onHealthGateFailure — for telemetry on health-gate rejection (knowledge-base: KBRecorderService.log)
    • logStartupStatus — for per-server startup-output formatting
    • buildRequestContext — SSE-only per-request context construction
    • onSessionClosed — SSE-only session-disconnect cleanup
  4. Composable lifecycle hooks (beforeMcpServerInit, beforeHealthcheck, afterHealthcheck, afterTransportConnected) — when to use no-op hooks vs override boot()
  5. The boot() overridable seam — when canonical sequence vs custom override:
    • Canonical sequence is sufficient when the per-server bootstrap order is: load-config → init-mcp → wait-services → healthcheck → transport. (PR2/PR3/PR6 use this.)
    • Custom boot() override when bootstrap order is non-canonical (e.g. neural-link's transport-before-services for MCP-handshake-tolerance per PR4; memory-core's stdio-identity-resolution between dependent-services and healthcheck per #10249 in PR5)
  6. Per-server reference table — quick lookup of which hooks each in-tree server overrides + why
  7. Common patterns the abstraction handles for free (vs what previously had to be hand-rolled per server) — quantified by the LOC reductions in PR2-PR6 (-50% / -51% / -30% / -28% / -60%)

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
learn/agentos/tooling/Introduction.md §-section This ticket; #10965 AC10 New §"MCP Server Base Class — extension contract" with the structure above Promote to standalone MCPServerBaseClass.md if section grows past ~300 lines This ticket §The Fix KB build picks up the section; ask_knowledge_base returns the doc when queried for "MCP server BaseServer extension hooks"

Acceptance Criteria

  • AC1: §-section "MCP Server Base Class — extension contract" added to learn/agentos/tooling/Introduction.md (or new MCPServerBaseClass.md if section warrants standalone treatment).
  • AC2: Section covers: required hooks, optional hooks, composable lifecycle hooks, boot() seam, per-server reference table, LOC-reduction quantification.
  • AC3: Each hook description includes when-to-use guidance + concrete reference to the in-tree server that uses it.
  • AC4: boot() override section covers BOTH canonical-sufficient cases (PR2/PR3/PR6) AND custom-required cases (PR4 neural-link, PR5 memory-core) with rationale.
  • AC5: Cross-references back to BaseServer.mjs class-level JSDoc (the single-source-of-truth) without duplicating its content verbatim.
  • AC6: KB sync picks up the new content; ask_knowledge_base(query="MCP server BaseServer extension hooks") returns the section.
  • AC7: #10965 AC10 marked complete in #10965; #10965 itself can then close-as-completed.

Out of Scope

  • Refactoring BaseServer.mjs's class-level JSDoc — the JSDoc IS the source of truth for behavior; this ticket adds pedagogical narrative around it, doesn't replace it.
  • M6 SDK external-facing API docs — separate ticket per server, sequenced after M6 lands per-server SDKs.
  • Breaking changes to the BaseServer contract — this is documentation only.

Avoided Traps / Gold Standards Rejected

  • Rejected: dedicated MCPServerBaseClass.md file upfront. Introduction.md already covers MCP server architecture; flat doc structure scales better than one-file-per-primitive. Promote only if section grows past readability threshold.
  • Rejected: duplicate the BaseServer JSDoc in markdown. JSDoc is the single source of truth; markdown narrative complements it without duplicating content.
  • Rejected: defer until M6 SDK migration. AC10 is part of M2's substrate definition; deferring it means M2 #10965 can't close-as-completed cleanly. Land it as a focused doc PR while the substrate is fresh in everyone's mind.

Related

  • Parent ticket: #10965 — M2 BaseServer (this is the AC10 follow-up)
  • Source primitives (in dev):
  • Sibling milestone tickets:
  • Adjacent doc surfaces:
    • learn/agentos/tooling/Introduction.md
    • learn/agentos/tooling/MemoryCoreMcpApi.md (per-server reference; pattern for the new section)

Origin Session ID: 005b6edf-85d8-4980-9e17-486b6b8bed3f

Retrieval Hint: query_raw_memories(query="MCP server BaseServer extension contract documentation hooks override boot seam M2 AC10")

tobiu closed this issue on May 8, 2026, 7:39 PM