Skip to content

Adopt Repl 0.11 with paged CLI/MCP results and complete release archives - #14

Merged
carldebilly merged 6 commits into
masterfrom
dev/cdb/repl-pagination
Sep 13, 2026
Merged

carldebilly merged 6 commits into
masterfrom
dev/cdb/repl-pagination

Conversation

@carldebilly

@carldebilly carldebilly commented Sep 12, 2026 •

Copy link
Copy Markdown
Member

Summary

Move the CLI and MCP command graph to Repl 0.11 modules and contexts, with on-demand TenantCloud pagination. Fix browser startup discovery so authentication waits for the browser-assigned debugging port.

Add a default JSON-aware human formatter so dynamic API responses display data fields rather than CLR metadata. Native support is proposed in yllibed/repl#92.

Package the complete publish directory before uploading artifacts, preserving dependency DLLs and runtime subdirectories. The release job reuses these ZIPs. Add a portable-archive startup smoke test. Platform-specific publications retain ReadyToRun; the portable publication remains framework-dependent without ReadyToRun or a platform-specific apphost.

Contract changes

  • List tools return items and pageInfo instead of data and count.
  • Use _replPageSize and _replCursor instead of maxResults.
  • Resolved names accompany each row instead of a root references map.
  • mcp serve is the canonical server command; mcp remains an alias.
  • Default human output uses json-human; explicit --human still selects the built-in Repl renderer. JSON/MCP output does not use the custom formatter.

Migration details are in docs/mcp-server.md.

Validation

  • Latest Windows Release test run at 97f8909: 59 passed, none failed or skipped, including authenticated TenantCloud API reads. The new provider regression tests failed before the fix and pass afterward.
  • MCP Inspector: data tools and resources, including cursor continuation; the final formatter build was checked again with list_properties.
  • Live interactive REPL: contexts, JSON field rendering, and page continuation.
  • Published Windows ReadyToRun executable: CLI, MCP Inspector, and interactive list / properties.
  • Portable publish with the CI options: extracted ZIP starts with dotnet tc-mcp.dll --help outside the repository. The local archive check used PowerShell ZIP tooling; the workflow uses Linux zip/unzip.

macOS arm64 validation at b5c39b2: the author's conformance report confirms 56 passed, none skipped, plus live MCP, interactive REPL, native/portable builds and ZIP extraction. Its fresh-browser interactive login path was not exercised because credentials came from the secure store. The follow-up provider fix and allocation change have not yet been rerun on macOS.

The initial GitHub CI passed: 44 tests succeeded and 12 authenticated API tests were skipped, with successful portable and Windows publication and portable-archive startup on Linux. CI is rerunning for the latest commits; live Linux API execution remains unverified.

Review follow-up

  • ad2962e: restore the provider's no-token fallback for browser startup failures, retain cleanup and caller cancellation, and add provider-level regression coverage.
  • 97f8909: enumerate paginated source memory without copying each slice.

The eight-lens local review panel confirmed the startup issue raised in the Codex review. A focused correctness recheck accepted the fix. No other functional or security defect was retained; optional broad style changes were not applied.

@carldebilly

Copy link
Copy Markdown
Member Author

@codex A review please

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-12T22:45:52.755400Z b5c39b2 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b5c39b200f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@carldebilly

Copy link
Copy Markdown
Member Author

PR #14 — macOS Conformance Report

Verdict: conforms. Every claim that can be verified on macOS was verified. No functional defect found. Three non-blocking observations and one pre-existing environment issue are listed at the end.

Environment

OS macOS 26.6 (Darwin 25.6.0)
Architecture osx-arm64 (Apple silicon)
.NET SDK 10.0.103 (global.json requires 10.0.102, rollForward: latestFeature)
Test runner MSTest 4.1.0 / Microsoft.Testing.Platform
Commit b5c39b2
Method Isolated git worktree; no source file modified

1. Summary claims

Claim (PR description) Status Evidence
CLI and MCP command graph moved to Repl 0.11 modules and contexts Verified Interactive REPL navigates list → properties, get → user → info, .. returns to parent. ManagementModule / TenantCloudModule map as described.
On-demand TenantCloud pagination Verified Five sequential MCP pages of 3 rows each: 15 rows, 0 duplicates, cursors chained 1:3:3 → 1:6:6 → 1:9:9 → 1:12:12 → 1:15:15. Backed by When_RequestingOneItem_Then_OnlyFirstApiPageIsFetched and When_AllRequested_Then_DoesNotFetchUnboundedResults.
Browser startup discovery waits for the browser-assigned debugging port Verified (unit + discovery); end-to-end not exercised The 7 Given_CdpBrowserStartup tests pass on macOS. ChromiumFinder.FindAll() resolves a real browser at a correct macOS path, so ResolveBrowserPath() would supply an executable. The full interactive login was not run — see Gap A.
Default JSON-aware human formatter shows data fields, not CLR metadata Verified Default output renders id, name, address1, … as key/value records with correct UTF-8 accent rendering. --human still prints the Repl built-in CLR view (Options / Parent / Root / Count), as documented.
Complete publish directory packaged before upload, preserving dependency DLLs and runtime subdirectories Verified Portable archive contains 48 entries including runtimes/win/lib/net10.0/*, tc-mcp.deps.json, tc-mcp.runtimeconfig.json, and all Repl.* / ModelContextProtocol.* dependencies. *.pdb and *.xml correctly excluded.
The release job reuses these ZIPs Verified by inspection Prepare release assets now does cp artifacts/binaries/tc-mcp-*/*.zip "$assets/", consuming the artifacts produced by Package binary. Not executed — see Gap C.
Portable-archive startup smoke test added Verified on macOS The new CI step reproduced locally: archive extracted to a temp directory outside the repository, then dotnet tc-mcp.dll --help → exit 0 with the full command graph.
Platform-specific publications retain ReadyToRun Verified PublishReadyToRun, PublishSingleFile, PublishSelfContained are true in the csproj; osx-arm64 output is a single 118 MB Mach-O 64-bit executable arm64.
Portable publication is framework-dependent, without ReadyToRun or a platform-specific apphost Verified No apphost emitted in publish/any (the new -p:UseAppHost=false takes effect); tc-mcp.dll + deps.json + runtimeconfig.json only.

2. Contract changes

Change Status Evidence
List tools return items and pageInfo instead of data and count Verified Every list tool returns {"$type":"page","items":[…],"pageInfo":{cursor,nextCursor,totalCount,pageSize,hasMore}}, in both content text and structuredContent.
_replPageSize and _replCursor replace maxResults Verified All five list tools expose exactly these two paging parameters. No maxResults anywhere in the MCP surface — the remaining occurrences are the internal IPaginatedSource.GetAll(ct, maxResults) client API, plus Given_TenantCloudRepl asserting its absence from the tool schema.
Resolved names accompany each row instead of a root references map Verified Transaction rows carry property_name and unit_name beside property_id / unit_id. No root references key in any response.
mcp serve canonical, mcp remains an alias Verified mcp --help shows serve as the only leaf; bare mcp starts the server through the args.Length == 1 rewrite in Program.cs and completes a full initialize / tools/list handshake.
Default human output uses json-human; --human selects the built-in renderer; JSON/MCP output unaffected by the custom formatter Verified Three-way comparison on the same command confirms all three behaviors; --json and MCP payloads are raw JSON (é escapes preserved), untouched by the formatter.
Migration details in docs/mcp-server.md Verified Section Pagination and migration from the previous MCP contract documents each change above, including --result:page-size / --result:cursor and the deliberate rejection of --result:all.

3. Reproduction of the PR's own validation runs

PR validation item Result on macOS
Release test run: 56 passed, none failed or skipped, incl. authenticated TenantCloud API reads Reproduced exactly — 56 passed / 0 failed / 0 skipped in 1m 05s. TestBase falls back to Assert.Inconclusive without credentials, so 0 skipped confirms the live Given_TcClient reads genuinely executed against the API.
MCP Inspector: data tools and resources, incl. cursor continuation Reproduced — @modelcontextprotocol/inspector --cli ran tools/list, tools/call, resources/list, resources/read, and a two-page cursor continuation, against both the native and the portable build.
Live interactive REPL: contexts, JSON field rendering, page continuation Reproduced
Portable publish with the CI options, extracted archive started outside the repository Reproduced, and closer to CI than the original run — the PR used PowerShell ZIP tooling; this used Info-ZIP zip/unzip, the same family as the Linux runner.
Published Windows ReadyToRun executable Out of scope on macOS.
"macOS/Linux execution has not been validated locally" No longer true for macOS arm64. Linux remains unvalidated.

4. Additional checks not claimed by the PR

Check Result
Build parity with CI (-c Release -warnaserror) 0 warnings, 0 errors
Executable bit survives zip → unzip for the native archive Preserved (-rwxr-xr-x), binary runs from the extracted location
MCP surface exposes data tools only 6 tools; login, logout, install correctly hidden by AutomationHidden()
Invalid cursor handling Clean isError: true with "Invalid TenantCloud continuation cursor." — no crash
Entity resources tc://guide and tc://property/{id} both resolve
install claude-desktop target path on macOS Correct: ~/Library/Application Support/Claude/claude_desktop_config.json; writes valid mcpServers JSON with ["mcp","serve"]
install claude-code invocation Correct: claude mcp add --transport stdio tc-mcp -- <exePath> mcp serve

Both install targets were exercised against a sandboxed HOME and a stub claude executable; no real configuration was modified.


5. Findings

F1 — Local restore fails on any machine with more than one NuGet feed (pre-existing, not introduced by this PR).
The repository ships no NuGet.config, so Central Package Management raises NU1507 as soon as the developer's global configuration lists more than one source. CI is unaffected because the runner only has nuget.org. This is the only issue that blocked the validation; it reproduces identically on master. Adding a NuGet.config with <clear /> plus nuget.org would fix it for every contributor.

F2 — MCP Inspector strict mode: 0 errors, 20 warnings across the 5 paged tools.
Two patterns, both in the page envelope's outputSchema, both generated by Repl 0.11 rather than written in this repository:

  • items.items is an empty schema {}, which constrains nothing.
  • Nullable fields use the array form "type": ["string","null"]. This is legal JSON Schema, but some MCP clients read type as a single string and either reject the tool or silently drop the constraint.

Not blocking, and consistent with the envelope being upstream — worth tracking alongside yllibed/repl#92.

F3 — macOS release archives will be quarantined by Gatekeeper.
The published osx-* binaries are neither signed nor notarized, so a user downloading tc-mcp-osx-arm64.zip from GitHub Releases will be blocked on first run. This was not verified — a locally produced archive carries no quarantine attribute, so confirming it requires a real release download. Documenting xattr -d com.apple.quarantine tc-mcp in docs/mcp-server.md would pre-empt it.

F4 — Cosmetic: context descriptions read as leaf descriptions.
Root --help shows get as "Get the signed-in TenantCloud user.", but get is a context and the actual command sits three levels down at get user info. The same inherited-description pattern appears on list and mcp. Not platform-specific.

6. Gaps

  • Gap A — End-to-end interactive login. CdpTokenProvider resolved a token from the secure store, so the new --remote-debugging-port=0 + DevToolsActivePort path was not driven end-to-end on macOS. Its logic is covered by the 7 passing Given_CdpBrowserStartup tests, and browser discovery was confirmed to resolve a real executable, but a full tc-mcp login on macOS remains unverified.
  • Gap B — Other platforms. Only osx-arm64 was built and run. osx-x64 (Intel) and all Linux RIDs are unverified.
  • Gap C — The workflow itself. CI steps were reproduced locally, step for step, but no GitHub Actions run was observed.

@carldebilly
carldebilly merged commit 554b38d into master Sep 13, 2026
7 checks passed
@carldebilly
carldebilly deleted the dev/cdb/repl-pagination branch September 13, 2026 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant