SterlingIndex Docs

Admin MCP Server

Local stdio MCP control surface for agent-driven Sterling operator workflows.

The Admin MCP server in apps/admin-mcp is a local stdio Model Context Protocol server for Codex, Claude-style desktop clients, and other MCP-capable agents. It gives an operator agent the same kind of runtime, discovery, review, press, artifact, and VPS publish controls that the Electron desktop app exposes, but without requiring a visual desktop shell.

The server is intentionally an adapter, not a second scraping implementation. The scraping and orchestration brain remains in services/platform-api/src/rosterscraper/*, with the FastAPI app mounted from rosterscraper.api.app:app. MCP calls either supervise the local API/worker runtime through @sterling/admin-runtime or call the control-plane HTTP routes exposed by that local API.

Architecture

MCP client
  |- Codex
  |- Claude Desktop
  `- other local MCP hosts
        |
        | stdio
        v
apps/admin-mcp
  |- src/index.ts
  |- src/server.ts
  |- src/tools.ts
  `- src/resources.ts
        |
        v
@sterling/admin-runtime
  |- env parsing and redaction
  |- secure env cache
  |- local API and worker process supervision
  |- readiness, watchdog, logs, and artifact paths
  |- control-plane HTTP client
  `- snapshot package builder
        |
        v
http://127.0.0.1:13000
services/platform-api/src/rosterscraper/api/app.py
  |- runtime, discovery, sessions, review, press, jobs
  |- Celery worker queues
  |- Postgres and Redis
  |- object storage and artifacts
  `- VPS sync API

The active Electron app remains available as a visual adapter. MCP is a second operator adapter over the same runtime boundary. New scrape logic should not be copied into apps/admin-mcp; add backend capabilities to services/platform-api first, then expose them through MCP as needed.

Package Layout

PathResponsibility
apps/admin-mcp/src/index.tsBoots the MCP server over StdioServerTransport.
apps/admin-mcp/src/server.tsCreates the server, context, tools, and resources.
apps/admin-mcp/src/tools.tsRegisters the Sterling MCP tool surface and zod input schemas.
apps/admin-mcp/src/resources.tsRegisters long-lived MCP resources and resource templates.
apps/admin-mcp/src/context.tsCreates the runtime manager and control-plane client context.
apps/admin-mcp/src/format.tsFormats successful and failed tool responses for MCP clients.
packages/admin-runtime/src/runtime-manager.tsSupervises the managed API and scrape-local worker processes.
packages/admin-runtime/src/secure-env-store.tsStores imported env bundles with Keychain-backed encryption on macOS.
packages/admin-runtime/src/env.tsParses env bundles, applies runtime defaults, and redacts secrets.
packages/admin-runtime/src/control-plane-client.tsWraps control-plane HTTP and SSE-style calls used by MCP tools.
packages/admin-runtime/src/snapshot-package.tsBuilds versioned snapshot_package payloads for VPS publish intent calls.

Startup Model

MCP connection is inert. Connecting Codex or another MCP host to apps/admin-mcp lists tools and resources only; it does not start scraping, open browsers, create jobs, or publish anything.

The managed runtime starts only when one of these happens:

  • sterling_runtime_start is called.
  • sterling_runtime_repair is called.
  • A workflow tool is called with ensure_runtime: true.

The default local API origin is http://127.0.0.1:13000. The runtime manager starts:

  • the FastAPI app with uvicorn rosterscraper.api.app:app,
  • a Celery worker that advertises scrape-local,validation-publish,
  • runtime heartbeat and readiness checks,
  • log capture under the MCP data directory.

The watchdog does not restart the API while startup is still in progress. It waits for the API and worker to finish their initial readiness path, then monitors health from there.

Env and Secret Handling

The operator imports runtime configuration through sterling_runtime_import_env_bundle. That env bundle becomes the local runtime source of truth for the MCP-managed API and worker.

Production/default storage:

  • Data directory: ~/Library/Application Support/Sterling Admin MCP/
  • Env cache: encrypted AES-256-GCM payload
  • Encryption key: macOS Keychain-backed secret

Plaintext env cache is allowed only for local tests and development when:

STERLING_MCP_ALLOW_PLAINTEXT_ENV_CACHE=true

Do not enable plaintext cache for real operator use.

The runtime redacts secrets when returning status or import previews. This includes obvious secret variables and URL credentials such as database passwords in DATABASE_URL, REDIS_URL, and related connection strings.

Environment Variables

VariablePurpose
STERLING_REPO_ROOTRepo root used to resolve services/platform-api and workspace paths. Defaults upward from the MCP app when possible.
STERLING_MCP_DATA_DIROverrides the default data/log/env-cache directory.
STERLING_MCP_BACKEND_DIROverrides the backend working directory. Defaults to services/platform-api.
STERLING_MCP_PYTHONPython executable used to launch uvicorn and Celery.
STERLING_MCP_ALLOW_PLAINTEXT_ENV_CACHEAllows plaintext env cache for tests/dev only.
STERLING_MCP_API_HOSTManaged API host. Default: 127.0.0.1.
STERLING_MCP_API_PORTManaged API port. Default: 13000.

The imported env bundle supplies backend values such as DATABASE_URL, REDIS_URL, OBJECT_STORAGE_*, ATTORNEY_MEDIA_*, LLM provider settings, browser/runtime settings, and VPS sync configuration. For production-direct operation from a Mac, Tailscale must be online when database or Redis hosts are reachable only on the tailnet.

Tool Surface

Runtime

ToolPurpose
sterling_runtime_statusReturns env-cache state, managed process status, API health, worker heartbeat, readiness, log paths, and VPS status.
sterling_runtime_import_env_bundleImports an env file or env text into the secure local cache and returns a redacted preview.
sterling_runtime_startStarts the managed API and worker.
sterling_runtime_stopStops the managed API and worker and frees the local API port.
sterling_runtime_repairReconciles runtime state by stopping stale managed processes and starting a clean runtime.
sterling_runtime_tail_logsReads recent lines from the managed API, worker, or runtime logs.
sterling_vps_statusChecks the configured VPS sync/health lane.

Roster Discovery

ToolPurpose
sterling_list_firmsLists configured firms from the control plane.
sterling_upsert_firmCreates or updates a firm configuration.
sterling_roster_chatSends a discovery chat message and returns conversation/run state.
sterling_get_conversationReads a discovery conversation by id.
sterling_save_previewSaves a discovered or edited preview explicitly.
sterling_export_attorneys_csvExports attorneys from a session/import path to CSV.

Discovery defaults are agent-flexible:

  • execution_target defaults to auto.
  • browser_provider defaults to null.
  • The backend can choose local/cloud/browser behavior according to runtime settings and readiness.

Discovery does not publish by itself. Save and publish remain separate MCP calls.

Review and Publish

ToolPurpose
sterling_list_review_batchesLists staged review batches.
sterling_get_staged_importReads a staged import and its rows.
sterling_update_staged_rowsUpdates staged review rows before publishing.
sterling_publish_sessionPublishes an approved session/import into the product-facing state.
sterling_publish_snapshot_to_vpsBuilds and sends a versioned snapshot package to /desktop/sync/publish-intent.

Publishing is explicit. Agents should not call publish tools unless the operator asked to publish or apply a snapshot.

Press Monitoring

ToolPurpose
sterling_press_discover_sourcePlans or discovers a press/news source for a firm or URL.
sterling_press_create_monitorCreates a monitor from a reviewed source plan.
sterling_press_run_nowRuns a press monitor immediately.
sterling_press_review_articlesLists discovered press articles needing review.
sterling_press_decide_articleApproves, rejects, or otherwise decides a reviewed press article.

Jobs and Artifacts

ToolPurpose
sterling_list_sessionsLists recent extraction/discovery sessions.
sterling_get_extractionReads extraction details by id.
sterling_get_source_reportReads source-report artifacts for a session.
sterling_list_scheduled_jobsLists recurring jobs.
sterling_create_scheduled_jobCreates a recurring roster scrape job for an approved EIP/skill.
sterling_update_scheduled_jobUpdates a recurring roster scrape job schedule, status, execution target, or review policy.
sterling_run_scheduled_job_nowRuns a scheduled job immediately.
sterling_delete_scheduled_jobDeletes or archives a recurring roster scrape job.

Resources

Resources expose long-lived context to MCP clients without forcing every interaction through a tool call.

ResourceTypePurpose
sterling://runtime/statusStatic resourceCurrent runtime status as JSON.
sterling://review/batchesStatic resourceCurrent staged review batch list.
sterling://logs/{service}TemplateAPI, worker, or runtime logs.
sterling://conversation/{id}TemplateDiscovery conversation context.
sterling://session/{id}TemplateSession/extraction context.
sterling://session/{id}/source-reportTemplateSource report for a session.
sterling://extraction/{id}TemplateExtraction detail context.

Using With Codex

Build the MCP server first:

pnpm --dir apps/admin-mcp build

Then configure Codex to start the compiled stdio server. A local Codex config entry should look like:

[mcp_servers.sterling_admin]
command = "node"
args = ["/Users/ciphore/viewport/apps/admin-mcp/dist/index.js"]
cwd = "/Users/ciphore/viewport"

[mcp_servers.sterling_admin.env]
STERLING_REPO_ROOT = "/Users/ciphore/viewport"

For development against TypeScript source, use the app script instead:

[mcp_servers.sterling_admin]
command = "pnpm"
args = ["--dir", "apps/admin-mcp", "start"]
cwd = "/Users/ciphore/viewport"

[mcp_servers.sterling_admin.env]
STERLING_REPO_ROOT = "/Users/ciphore/viewport"

A normal first-run operator sequence is:

  1. Call sterling_runtime_status.
  2. Call sterling_runtime_import_env_bundle with a trusted env file path.
  3. Start Tailscale if the env points at tailnet-only Postgres or Redis hosts.
  4. Call sterling_runtime_start.
  5. Confirm status shows lifecycle: "ready", apiHealthy: true, workerHeartbeatHealthy: true, and VPS status online when expected.
  6. Use read-only tools such as sterling_list_sessions and sterling_list_firms.
  7. Run discovery/review/publish tools only when the operator asks for that workflow.

Safety Rules

  • MCP connection alone must stay inert.
  • Discovery may create conversations or runs, but it must not publish.
  • Save, review, publish, and VPS apply are explicit tool calls.
  • VPS snapshot publish calls must be signed with DESKTOP_SYNC_SECRET_KEY or CONTROL_PLANE_SECRET_KEY.
  • Default discovery execution target is auto.
  • Default browser provider is unresolved/null so the backend and agent can choose the right route.
  • The MCP server should call existing control-plane APIs instead of duplicating backend logic.
  • The secure env cache should stay encrypted for real operator use.
  • Full scrape, row mutation, publish, and VPS snapshot calls are not part of a default smoke test.

Verification Runbook

Use these checks after changing apps/admin-mcp or packages/admin-runtime:

pnpm --dir packages/admin-runtime build
pnpm --dir packages/admin-runtime test
pnpm --dir apps/admin-mcp build
pnpm --dir apps/admin-mcp test

Run the existing desktop regression suite when shared runtime behavior could affect Electron:

pnpm --dir apps/admin-desktop test

For SDK-level smoke testing, start the MCP server through stdio and verify:

  • the server boots without starting the runtime,
  • tools/list returns the Sterling tools,
  • resources/list returns static resources,
  • resource templates include logs, conversations, sessions, reports, and extractions.

For production-direct live smoke testing, verify Tailscale and public API reachability first:

/usr/bin/nc -vz -G 5 100.79.46.125 15432
/usr/bin/nc -vz -G 5 100.79.46.125 16379
/usr/bin/curl -sS -m 5 https://api.sterlingindex.com/healthz

Then import a trusted env bundle, start the runtime, and confirm:

  • lifecycle is ready,
  • apiHealthy is true,
  • workerHeartbeatHealthy is true,
  • VPS status is online when the sync API is configured,
  • sterling_list_sessions returns recent session data,
  • sterling_list_firms returns configured firms,
  • sterling_runtime_stop shuts down the managed API and worker,
  • nothing remains listening on 127.0.0.1:13000.

Failure Modes

SymptomLikely causeOperator action
API stays in startup or readiness never resolvesTailnet database or Redis is unreachableStart Tailscale, then check the DB and Redis host/ports.
Runtime reports missing env cacheNo env bundle has been importedCall sterling_runtime_import_env_bundle with a trusted env file.
Port 13000 is occupiedAnother API process is already listeningUse sterling_runtime_status and logs to confirm ownership, then stop the conflicting process if appropriate.
Runtime identity mismatchA process on 13000 was not started by this MCP runtimeStop the foreign process or use its own owner to manage it.
Worker heartbeat unhealthyCelery failed to connect to Redis or crashed during startupTail worker logs and verify REDIS_URL.
VPS status offlineSync API health lane is unreachable or env is missingCheck public API health, Tailscale route, and VPS sync env.
MCP tool call times out during startupBackend dependency is blocking app startupTail API logs and verify database, Redis, object storage, and required secrets.

Current Boundaries

The first MCP version is local-first and operator-powerful, but it deliberately stays within existing Sterling runtime boundaries:

  • It does not replace services/platform-api.
  • It does not duplicate roster scraping, press discovery, validation, or publish logic.
  • It does not change dashboard product APIs.
  • It does not make Electron obsolete immediately; Electron remains the visual adapter.
  • It provides the shared @sterling/admin-runtime package that Electron can adopt later for runtime supervision parity.

On this page