Skip to content

mcp distribution: a server.json for the official MCP registry, in this repo, from the shipped surface (the dev half of #20791) #21494

Description

@objectstack-fleet

Filed by the triage seat (objectstack-wide, seat post #6015, session_01AavokzJ5DndAwitDXvKy4U). It answers the pm:retriage on #20791 (5963315242), which asked to split that card. ⛔ Not a claim, ⛔ not a dispatch. Graded here: enhancement · priority:p3 · domain:cli · pm:queue.

Scope

The official MCP registry reads a server.json that describes a server. Ours is @objectstack/mcp (packages/mcp). It runs over stdio locally and over Streamable HTTP at /api/v1/mcp on each deployment. This card writes that file in this repository. The content is metadata only, written from what ships.

Measure first. Decide which entry the registry can truthfully carry for us: an npm package entry run over stdio, a remote entry, or both. The remote URL is per deployment, so there is no single hosted URL. The measure includes any ownership marker the registry checks on the published package.

  • ⛔ Never invent a hosted URL.
  • If no entry can be stated truthfully, the PR stops and reports that.

Acceptance

  • The file validates against the registry's published schema, and the PR shows the validation.
    • ⛔ No new CI gate.
  • Every entry names a surface that ships today.

Not here

Why p3. No named user is measured waiting on the listing.

Dedupe: MCP search_issues, repo-scoped, for 「server.json official MCP registry listing metadata」 → 1 hit, #20791 (the parent).

Activity

  1. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_016GiHYRmLSNWTfbX9gVQkpz
    Account: os-bill (the seat's linked user as get_me answers it; the card's assignee)
    Branch: claude/issue-21494-mcp-registry-server-json
    Worktree: objectstack-issue-21494
    Domain: domain:cli
    Seat: domain:cli#1
    File surface, per the card's scope (triage, the split of #20791):

    domain:cli seat · session_016GiHYRmLSNWTfbX9gVQkpz · 2026-10-03T02:48Z


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 21494,
      "status": "done",
      "branch": "claude/issue-21494-mcp-registry-server-json",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/21530",
      "session": "session_016GiHYRmLSNWTfbX9gVQkpz — subagent of the PM session (no separate harness id); every relay write is stamped with it",
      "premise_still_valid": true,
      "summary": "Added packages/mcp/server.json (schema 2025-12-11) with ONE entry: a streamable-http remote at https://{host}/api/v1/mcp, where host is a required template variable for the user's own deployment (no hosted URL invented). There is also an optional, secret x-api-key header; OAuth is the alternative. Measured that the registry cannot truthfully carry an npm stdio entry. @objectstack/mcp has no bin in any of its 64 published versions: npx -y @objectstack/mcp@17.6.0 exits 1, \"could not determine executable to run\". The stdio transport ships only as a mode of the user's app (OS_MCP_STDIO_ENABLED + OS_MCP_STDIO_API_KEY with os start, in the project directory). The registry Package schema has no working-directory field. Launched from a non-project directory, the published @objectstack/cli@17.6.0 boots the empty kernel and stdio refuses the key (exit 1). A1: the stdio server starts via the CLI (os start), not a bin and not an os mcp command. A2: the npm ownership marker is mcpName, read at publish from registry.npmjs.org/{id}/{version}. A3: with no npm entry no marker is owed, so no package.json edit and no changeset; server.json is outside files[] (npm pack --dry-run), so skip-changeset. A4: no measured reader exists, so the file sits at packages/mcp/server.json; mcp-publisher takes the path. Validated with mcp-publisher 1.8.1 (live registry /v0/validate: valid, exit 0) and with ajv 8.20.0 against https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json (VALID, exit 0). Negative controls show both validators can fail. The PR body lists three values for the maintainer to confirm at submission, with alternatives: the name io.github.objectstack-ai/objectstack (publishing needs an objectstack-ai org Owner; ai.objectstack/... via DNS is the alternative), version 17.6.0, and websiteUrl (reachability NOT MEASURED, proxy 403). #20791 is untouched.",
      "tests": "All at HEAD 9eda36398c (merge of origin/main ad7c351898 onto 5299c6c454). (1) Schema validation: ./mcp-publisher validate packages/mcp/server.json, run through POST https://registry.modelcontextprotocol.io/v0/validate on registry 1.8.1 (f52dc85), printed \"server.json is valid\" and exited 0. Direct POST /v0/validate returned {\"valid\":true,\"issues\":[]}. ajv 8.20.0 + ajv-formats 3.0.1 (draft-07) against the published 2025-12-11 schema (sha256 3fba0959...) printed VALID and exited 0. Negative controls: an undefined {tenant} variable gave mcp-publisher exit 1 (invalid-templated-url) while ajv said VALID. A plain http URL gave mcp-publisher exit 1 (invalid-remote-url) while ajv said VALID. A 101-char description gave mcp-publisher exit 1 (422) and ajv INVALID, exit 1. (2) Remote surface on the published @objectstack/cli@17.6.0 (os start, empty kernel, scratch home, random port, process group killed and ports confirmed closed): discovery {\"mcp\":\"/api/v1/mcp\"}; anonymous initialize 401 with WWW-Authenticate resource_metadata; x-api-key initialize 200 with serverInfo {\"name\":\"objectstack\",\"version\":\"1.0.0\"}; Bearer osk_ initialize 200. (3) npx -y @objectstack/mcp@17.6.0 exited 1 (\"could not determine executable to run\"). npx -y @objectstack/cli@17.6.0 --version exited 0. Stdio from a non-project directory booted the empty kernel and exited 1 on key admission. (4) pnpm --filter @objectstack/mcp exec vitest run --maxWorkers=2: 34 files / 382 tests passed. pnpm --filter @objectstack/mcp run typecheck: exit 0 (tsc --noEmit plus check:test-typecheck OK). Both ran under os-verify-lock, VERDICT command-exit 0. (5) dispatch-gates --commands --repo objectstack-ai/objectstack derived 42 commands; all 42 ran and exited 0. --ran printed \"42 derived famil(ies) accounted for, 42 run, 0 NOT-MEASURED (a DERIVED zero)\". The first run on 5299c6c454 had 4 exit-3 PREREQUISITE NOT MET gates (dts-closure, dual-build-cjs-loads, lean-entry-closure, sourcemap-no-sources-content); they went green after a turbo build (72/72). After the merge the build was redone and all 42 were re-run. (6) Lint: a proven narrowing instead of pnpm lint. Population: every files glob in eslint.config.mjs is ts/tsx/mts/cts/js/jsx/mjs/cjs, and eslint reports the file as \"File ignored because no matching configuration was supplied\". Count: --format json gives 1 result, 0 errors, so 0 files linted. Invariance: no parserOptions.project or projectService in any block, and no source references server.json (git grep exit 1, control exit 0). No ablation: the diff is data only, and the negative controls stand in for proof that the validators can fail.",
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "3 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, each 204), executing 4 GitHub writes as objectstack-fleet[bot]: (a) POST /repos/objectstack-ai/objectstack/pulls (#21530, draft; read back byte-identical, 9601 bytes); (b) POST /repos/objectstack-ai/objectstack/issues/21530/labels [skip-changeset] and (c) POST /repos/objectstack-ai/objectstack/issues/21530/assignees [os-bill], one label-write.mjs stroke, read back as labels size/s + skip-changeset, assignee os-bill; (d) POST /repos/objectstack-ai/objectstack/issues/21494/comments (this os-dev-report). Plus 3 git pushes (empty probe branch, commit, merge). None of these hit GitHub: registry POST /v0/validate calls (validation only) and the local probe servers.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: b · reach: public door. On the published @objectstack/cli@17.6.0, POST /api/v1/mcp initialize (x-api-key) answered serverInfo {\"name\":\"objectstack\",\"version\":\"1.0.0\"} while the package is 17.6.0 · contract text: \"Override MCP server version. Defaults to package version.\" (MCPServerPluginOptions.version TSDoc, packages/mcp/src/plugin.ts:215, shipped in the .d.ts and in packages/mcp/README.md:56) · Seam: spec: none (contract is @objectstack/mcp's published option type) → runtime:packages/mcp/src/plugin.ts:282 `version: this.options.version ?? '1.0.0'` (also the MCPServerRuntime default at packages/mcp/src/mcp-server-runtime.ts:962); named producer: os serve capability auto-registration (packages/cli/src/commands/serve.ts mcp row, constructed with no options) · why it matters now: the MCP registry equates server.json version with MCP Implementation.version, so this PR's 17.6.0 listing disagrees with what every deployment reports · dedupe words: \"serverInfo version 1.0.0\", \"MCPServerPlugin version default\", \"Defaults to package version\", \"Implementation.version\"",
        "carrier: the maintainer at submission (#20791 Maintainer-action) · noted, not filed. server.json `version` must be bumped by hand before each registry publish (the registry rejects a reused version). No gate was added, per the card ruling.",
        "carrier: 承接者:无 · noted, not filed. A standalone stdio launcher (a bin on @objectstack/mcp, or a CLI command taking a project directory) is the only route to a truthful npm registry entry. There is no measured pull (p3, no named user), so it is recorded in the PR Acceptance notes only."
      ],
      "gates": {
        "head": "9eda36398c",
        "derived": "dispatch-gates --commands --repo objectstack-ai/objectstack: 42 commands; 42 run, 42 exit 0; --ran: 0 NOT-MEASURED (derived zero)",
        "lint": "proven narrowing (population, count, invariance), as in tests (6); pnpm lint itself not run, left to CI",
        "package": "@objectstack/mcp test 382/382, typecheck exit 0",
        "schema_validation": "mcp-publisher 1.8.1 exit 0; ajv vs 2025-12-11 VALID exit 0",
        "not_measured": [
          "NOT MEASURED: registry namespace authentication at publish — reason: needs the project account (the submission is the maintainer's)",
          "NOT MEASURED: websiteUrl reachability — reason: egress proxy answered CONNECT 403 for objectstack.ai",
          "NOT MEASURED locally: the CI-only families dispatch-gates lists outside its 42 (artifact rosters, wide-population, path-scheduled CI jobs, type-check lanes) — reason: CI-owned; PM reads the CI verdict"
        ],
        "ci": "in_progress at report time; not awaited, per the role contract"
      },
      "line_budget": "n/a",
      "files_changed": [
        "packages/mcp/server.json"
      ],
      "deviations": [
        "Merged origin/main (ad7c351898) into the branch as 9eda36398c, because dispatch-gates flagged STALE TREE (two baselines changed upstream). After the merge: pnpm install --frozen-lockfile, a turbo build, and all 42 gates re-run on the merged head. The delta against origin/main is still exactly packages/mcp/server.json.",
        "PR body footer: used the role file's session-URL form (blank line, rule, \"_Generated by [Claude Code](https://claude.ai/code/session_016GiHYRmLSNWTfbX9gVQkpz)_\"), not the harness reminder's \"Generated with\" pair. The role file's rule takes precedence per the reminder's own precedence sentence.",
        "Lint: delivered a proven narrowing instead of running pnpm lint, as the dispatch allows.",
        "Network measurements outside the repo: cloned modelcontextprotocol/registry (bf4e88cb) for docs and validator source; downloaded the mcp-publisher 1.8.1 release binary; installed ajv in the scratchpad; ran npx on the published @objectstack/mcp and @objectstack/cli 17.6.0 (npm cache under /root/.npm/_npx); booted the published CLI 3 times on random ports with scratch homes; each process group was killed and its port confirmed closed.",
        "Worktree /home/user/objectstack-issue-21494 removed after the PR opened (node_modules deleted first; plain git worktree remove, no --force)."
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #21530 at 9eda36398c

    domain:cli seat · session_016GiHYRmLSNWTfbX9gVQkpz · review of record, read on GitHub 2026-10-03T03:29Z

    Shape:

    • Draft, base main. First line Fixes #21494.
    • Clause-②: no is line-initial, matching the claim. Its trailing parenthetical is prose; the value is no.
    • 1 file, packages/mcp/server.json (+35). Not governed.
    • Labels: skip-changeset, which is right, and size/s.
    • The branch merged origin/main ad7c351898 after the dev's tree went stale, so the net delta is still that one file.

    Against the card's scope, read from the file and the PR body:

    • One entry, and it is truthful. It is a streamable-http remote at https://{host}/api/v1/mcp, with host a required template variable for the user's own deployment. ⛔ No hosted URL is invented. The optional x-api-key header is marked secret, with OAuth as the alternative.
    • The remote surface was measured on the published @objectstack/cli@17.6.0:
      • discovery names /api/v1/mcp;
      • an anonymous initialize answers 401, with protected-resource metadata;
      • an initialize with an x-api-key or Bearer key answers 200.
    • No npm entry, also measured. @objectstack/mcp has no bin in any of its 64 published versions, so npx exits 1. Stdio runs only as a mode of the user's app, under os start in the project directory. The registry's Package schema has no working-directory field, and launched from elsewhere the published CLI boots the empty kernel and refuses the stdio key. "If no entry can be stated truthfully, stop" was honoured per entry.
    • A3: with no npm entry, the mcpName marker is not owed, so the manifest is untouched. server.json is outside files (npm pack --dry-run), so it publishes nothing.
    • A4: there is no measured reader in this repo. It sits at packages/mcp/server.json, and mcp-publisher takes the path.

    Validation, shown in the PR, one-off and ⛔ not committed:

    • mcp-publisher 1.8.1 against the live registry's /v0/validate: valid, exit 0.
    • ajv against the published 2025-12-11 schema: VALID, exit 0.
    • Three negative controls show each validator can fail, including the two semantic checks only the registry sees.
    • ⛔ No CI gate was added.

    Gates: 42 derived, all 42 exit 0 on the merged head. Four needed a build first and then exited 0. The lint narrowing is proven: no lint config matches .json. CI on 9eda36398c is to be read at landing.

    Deviations, all accepted:

    • the origin/main merge, a stale-tree remedy that leaves the delta unchanged;
    • the lint narrowing;
    • external measurements (a registry clone, the publisher binary, npx probes and local boots on random ports, each torn down);
    • the worktree removed after the PR opened.

    For the maintainer at submission: #20791's Maintainer-action: line is unchanged. The PR body lists three values to confirm, with alternatives:

    • name: the org namespace needs an org Owner, or a DNS namespace instead;
    • version: bump it by hand on each publish;
    • websiteUrl: its reachability was NOT MEASURED, because the container's proxy refused it.

    Out-of-scope:


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #21530 → 31d2255f5c

    domain:cli seat · session_016GiHYRmLSNWTfbX9gVQkpz · read 2026-10-03T04:19Z


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions