Skip to content

docs: Add nico-mcp operator guide#3498

Merged
kfelternv merged 5 commits into
NVIDIA:mainfrom
kfelternv:codex/nico-mcp-docs-main
Jul 22, 2026
Merged

docs: Add nico-mcp operator guide#3498
kfelternv merged 5 commits into
NVIDIA:mainfrom
kfelternv:codex/nico-mcp-docs-main

Conversation

@kfelternv

@kfelternv kfelternv commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Adds a Day 2 NICo MCP operator guide, links it from the Helm chart, and includes it in documentation navigation. The guide explains supported deployment topologies, configuration precedence, and the credential-to-REST-destination behavior implemented by #3499 so operators can configure the service without forwarding credentials to an unintended destination.

Related issues

Resolves #2801.

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

Detailed verification and reproduction steps are in the existing top-level verification comment.

Signed-off-by: Kyle Felter <kfelter@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 18ee5099-b314-407c-b3d7-45a174b402e6

📥 Commits

Reviewing files that changed from the base of the PR and between 51f34f4 and 364971a.

📒 Files selected for processing (1)
  • docs/operations/nico-mcp.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/operations/nico-mcp.md

Summary by CodeRabbit

  • Documentation
    • Added an Operations (Day 2) guide for the NICo MCP Server, including supported deployment topology, configuration precedence, runtime behavior, and security/logging requirements.
    • Added a Helm chart README for NICo MCP with deployment overview and operational pointers.
    • Updated documentation navigation to link the new “NICo MCP Server” page.
    • Clarified documentation standards for Helm-backed settings, including default labeling and precedence guidance.

Walkthrough

Adds operational documentation for deploying, configuring, securing, and debugging the NICo MCP server, with Helm chart guidance and documentation navigation updates.

Changes

NICo MCP Operations

Layer / File(s) Summary
Server topology and operating model
docs/operations/nico-mcp.md
Documents the stateless read-only MCP wrapper, Kubernetes topology, external access controls, and standalone usage.
Helm deployment and chart configuration
docs/operations/nico-mcp.md, helm/rest/nico-mcp/README.md, docs/index.yml, AGENTS.md
Describes Helm installation, image handling, chart values, bearer-token handling, chart scope, documentation standards, and navigation updates.
Runtime precedence and security controls
docs/operations/nico-mcp.md
Defines startup configuration, per-tool argument precedence, destination and credential restrictions, and debug-log redaction behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR is documentation-only and does not implement the REST API, nicocli, or handler/workflow changes required by #2801. Implement the measurables trust-approve REST and nicocli feature set from #2801, or retarget this PR to the documentation task.
Out of Scope Changes check ⚠️ Warning The docs changes are unrelated to the linked feature work in #2801 and are out of scope for that issue. Move the guide and navigation edits to a documentation-focused issue or separate PR from the feature implementation.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: adding the nico-mcp operator guide.
Description check ✅ Passed The description is directly related to the documentation updates and navigation changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@kfelternv
kfelternv requested review from a team, Coco-Ben, polarweasel and thossain-nv and removed request for Coco-Ben July 15, 2026 23:11
@kfelternv
kfelternv marked this pull request as ready for review July 16, 2026 18:27
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 259 16 29 79 7 128
machine-validation-runner 538 41 117 184 15 181
machine_validation 538 41 117 184 15 181
machine_validation-aarch64 538 41 117 184 15 181
nvmetal-carbide 538 41 117 184 15 181
TOTAL 2417 180 497 821 67 852

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-07-16 18:30:55 UTC | Commit: 67ce2b3

@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: 67ce2b39c8

ℹ️ 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".

Comment thread docs/operations/nico-mcp.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/operations/nico-mcp.md`:
- Around line 21-23: Update docs/operations/nico-mcp.md lines 21-23 to describe
ClusterIP and port 8080 as defaults, while stating that production deployments
must retain those settings. Update helm/rest/nico-mcp/README.md line 3 to say
that, by default, the chart deploys a ClusterIP Service.
- Around line 132-144: Update the startup-settings documentation around the
table to clarify that the environment-variable fallback describes standalone
binary behavior only. State that Helm renders explicit --listen, --path, and
--shutdown-timeout arguments, so those Helm values take precedence over the
corresponding NICO_MCP_* environment variables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cfc20088-c31d-4501-a139-174b0856e401

📥 Commits

Reviewing files that changed from the base of the PR and between 536bb26 and 67ce2b3.

📒 Files selected for processing (3)
  • docs/index.yml
  • docs/operations/nico-mcp.md
  • helm/rest/nico-mcp/README.md

Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
@kfelternv
kfelternv requested a review from a team as a code owner July 16, 2026 18:47
@ajf

ajf commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

@kfelternv the PR description is too long since it winds up as the git commit message, so basically should just be the what and why. The how it was tested & how to reproduce testing should probably go into a comment after the PR description so it doesn't wind up in the git commit.

@kfelternv

Copy link
Copy Markdown
Contributor Author

How we verified it

Verified the exact current merge result on macOS 26.5.1 arm64. The docs head was signed commit 67ce2b39c813aef4de130ac670cfa924a8e5f23f; current main was d83e8c6296c7e932b1f639472994fc900082b0ba; and their clean merge produced tree 3fbb282e71432f13127d9c2f8bac200d15527888. The diff remained limited to docs/index.yml, docs/operations/nico-mcp.md, and helm/rest/nico-mcp/README.md.

Hands-on verification built the Go 1.26.4 nico-mcp binary and exercised its streamable-HTTP tools/call path against two real localhost HTTP receivers:

  • a caller-selected URL different from the configured startup URL was rejected before either an inherited bearer or an explicit per-call token reached that receiver;
  • matching configured URLs, including a trailing-slash variant, reached only the configured receiver with the expected inherited bearer;
  • with no configured startup URL, inherited inbound and startup tokens were rejected for a caller-selected destination, while an explicit per-call token was forwarded and a no-token call remained unauthenticated.

Supporting checks:

  • go test ./mcp/... -count=1 passed;
  • go vet ./mcp/... passed;
  • helm lint helm/rest/nico-mcp ... linted one chart with zero failures;
  • helm template rendered the documented ClusterIP Service, port 8080, image, /mcp path, fixed base URL, organization, and API name;
  • Fern CLI 5.57.0 reported zero configuration errors, and the rendered NICo MCP page returned HTTP 200 with all new sections present;
  • rumdl 0.2.34 reported no issues in the two changed Markdown files; and
  • git diff --check passed.

The optional Fern broken-link scan reported existing errors in files outside this three-file diff; it reported no broken link in the new guide or chart README.

How to reproduce the verification

Prerequisites: Git, Go with toolchain download enabled, Helm 3, Node.js/npm, Python 3, curl, and uvx.

Start from a clean checkout and construct the exact verified tree:

git clone https://github.com/NVIDIA/infra-controller.git
cd infra-controller
git fetch origin refs/pull/3498/head:pr-3498
git checkout --detach d83e8c6296c7e932b1f639472994fc900082b0ba
git merge --no-ff --no-commit pr-3498
git write-tree

The merge must be conflict-free and git write-tree must print 3fbb282e71432f13127d9c2f8bac200d15527888.

Build and run the focused checks:

VERIFY_ROOT="$(cd .. && pwd)/pr3498-verification"
mkdir -p "$VERIFY_ROOT/gopath/bin"

cd rest-api
GOPATH="$VERIFY_ROOT/gopath" make nico-mcp
GOPATH="$VERIFY_ROOT/gopath" go test ./mcp/... -count=1
GOPATH="$VERIFY_ROOT/gopath" go vet ./mcp/...
cd ..

helm lint helm/rest/nico-mcp \
  --set global.image.repository=registry.example.com/nico \
  --set global.image.tag=2.0.0 \
  --set config.baseURL=http://nico-rest-api:8388 \
  --set config.org=example-org \
  --set config.apiName=nico

npx --yes fern-api@5.57.0 check --warnings
uvx rumdl check docs/operations/nico-mcp.md helm/rest/nico-mcp/README.md
git diff --cached --check

For the real credential-routing path, create a standard-library receiver:

cat >"$VERIFY_ROOT/receiver.py" <<'PY'
import json
import sys
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        print(json.dumps({
            "port": self.server.server_port,
            "path": self.path,
            "authorization": self.headers.get("Authorization", ""),
        }), flush=True)
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(b"[]")
    def log_message(self, _format, *_args):
        pass

ThreadingHTTPServer(("127.0.0.1", int(sys.argv[1])), Handler).serve_forever()
PY

python3 -u "$VERIFY_ROOT/receiver.py" 19110 >"$VERIFY_ROOT/caller.log" 2>&1 &
CALLER_PID=$!
python3 -u "$VERIFY_ROOT/receiver.py" 19111 >"$VERIFY_ROOT/configured.log" 2>&1 &
CONFIGURED_PID=$!

"$VERIFY_ROOT/gopath/bin/nico-mcp" \
  --listen 127.0.0.1:19112 \
  --path /mcp \
  --base-url http://127.0.0.1:19111 \
  --org test-org >"$VERIFY_ROOT/nico-mcp.log" 2>&1 &
MCP_PID=$!

Send one mismatched and one matching call:

curl --retry 10 --retry-connrefused --retry-delay 1 -sS \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Authorization: Bearer mismatch-inherited-sentinel' \
  --data '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"nico_get_all_site","arguments":{"base_url":"http://127.0.0.1:19110","org":"test-org"}}}' \
  http://127.0.0.1:19112/mcp

curl -sS \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Authorization: Bearer matching-inherited-sentinel' \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"nico_get_all_site","arguments":{"base_url":"http://127.0.0.1:19111/","org":"test-org"}}}' \
  http://127.0.0.1:19112/mcp

test ! -s "$VERIFY_ROOT/caller.log"
rg 'matching-inherited-sentinel' "$VERIFY_ROOT/configured.log"
kill "$MCP_PID" "$CONFIGURED_PID" "$CALLER_PID"

The mismatched call must return isError: true with per-call base_url does not match the configured server base URL, and the caller-selected receiver log must remain empty. The matching call must return []; the configured receiver must record /v2/org/test-org/nico/site?pageNumber=1 with Bearer matching-inherited-sentinel.

Finally, render the guide:

npx --yes fern-api@5.57.0 docs dev --port 19120 &
FERN_PID=$!
curl --retry 20 --retry-connrefused --retry-delay 1 -fsS \
  http://127.0.0.1:19120/infra-controller/documentation/operations-day-2/ni-co-mcp-server \
  | rg 'Supported Deployment Topologies|Runtime Configuration|Security Requirements|Debug Logging'
kill "$FERN_PID"

The page must return HTTP 200 and contain all four section headings.

Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
@kfelternv
kfelternv requested a review from shayan1995 July 21, 2026 10:50

@shayan1995 shayan1995 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — I cross-checked the guide against the chart templates/values and the server source (ServeFlags, FromCallConfig, the debug-header redaction in cli/pkg/client.go), and every default, env var, precedence rule, and security claim matches the code, including the subtle ones (no env var for --debug, trailing-slash tolerance on base_url, empty-token-allowed). Nice work.

A few non-blocking nits inline. One optional thought with no good anchor line: the guide doesn't mention that the chart's probes are TCP-only and the endpoint only answers JSON-RPC POSTs (both noted in the deployment template comments) — a one-liner under the production topology section could save an operator wiring an HTTP-health-checking gateway some confusion.

Comment thread docs/operations/nico-mcp.md Outdated
Comment thread docs/operations/nico-mcp.md Outdated
@kfelternv
kfelternv merged commit 85e7389 into NVIDIA:main Jul 22, 2026
121 checks passed
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.

Add REST API support for measurables / trust approve rules (admin-cli measurables parity)

4 participants