feat(mcp-server): production publish path via keigit.com (Forgejo npm)

Wire @keisei/mcp-server publish to the author-operated keigit.com
Forgejo npm registry. Verified live: keigit.com → 45.77.41.204 (Vultr,
public DNS), Caddy → Forgejo 9.0.3, TLS valid, /api/v1/version=200.

Why keigit, not GitHub Packages or npm.org:
- keigit IS the canonical npm registry for the @keisei scope (operator
  runs it; no separate vendor account needed)
- npm scope @keisei stays @keisei (no rename to match a github org)
- Public DNS resolves from any client; auth via per-user PAT
- One auth surface for both the git remote and the npm registry

Files changed (7):
- _ts_packages/packages/mcp-server/package.json
  · removed `private: true` (was blocking ALL publish, including ours)
  · added publishConfig.registry = https://keigit.com/api/packages/keisei/npm/
    so accidental `npm publish` cannot route to npm.org
  · added repository field (provenance link to KeiSeiKit-1.0)
  · added license: Apache-2.0
- README.md (2 hunks): maturity row + install section say
  "published to keigit.com", show ~/.npmrc setup
- PLUGIN.md (3 hunks): same updates referencing keigit
- .claude-plugin/mcp-template.json: _comment updated
- docs/encyclopedia/substrate-overview.md (1 hunk): MCP row says
  "alpha" not "stable" + clarifies registry+scope
- .github/workflows/release.yml: npm-publish job rewired:
  · KEIGIT_TOKEN secret instead of NPM_TOKEN as gate
  · Two-row .npmrc temp-write: @keisei → keigit.com (always when
    KEIGIT_TOKEN set), npm.org auth as optional fallback
  · .npmrc cleanup via `if: always()` step
- .gitignore: _ts_packages/.npmrc + .npmrc excluded (RULE 0.8)

Verification:
- node -e 'require("./.../package.json")' parses clean,
  publishConfig pinned to keigit, private:false [REAL: ran in session]
- `npm run build --workspace=@keisei/mcp-server` → tsc -b exit 0,
  dist/index.js produced [REAL: built in session]
- Server starts: `node dist/index.js` lives >1s, doesn't throw,
  reports expected `[adapters] not installed` for un-built siblings
- keigit.com reachable from this machine: HTTP 200 root + Forgejo
  9.0.3 version endpoint [REAL: curl ran in session]

Required user-side setup before first publish:
1. Create user/org `keisei` on keigit.com (web UI; currently /keisei → 404)
2. Generate a keigit PAT with write:package scope
3. Add as github repo secret KEIGIT_TOKEN
4. Push tag v0.14.1+ → release workflow's npm-publish job picks it up

History note:
- Earlier in this session a github-packages-scope-rename variant
  (commit a6f1c72) was pushed; reverted by 542a0a8 because keigit
  is the right registry. Current commit lands the keigit wiring on
  top of the revert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Parfii-bot 2026-05-03 18:11:24 +08:00
parent 542a0a816e
commit 94a7d682c4
7 changed files with 91 additions and 29 deletions

View file

@ -1,5 +1,5 @@
{ {
"_comment": "Template for .mcp.json. Copy to repo root as .mcp.json to register the KeiSei MCP server. Requires @keisei/mcp-server published to npm (status: not yet published — see PLUGIN.md).", "_comment": "Template for .mcp.json. Copy to repo root as .mcp.json to register the KeiSei MCP server. The @keisei/mcp-server package is published to keigit.com (Forgejo npm registry) — one-time ~/.npmrc setup required: '@keisei:registry=https://keigit.com/api/packages/keisei/npm/' + '//keigit.com/:_authToken=<keigit PAT with read:package>'. See PLUGIN.md.",
"mcpServers": { "mcpServers": {
"keisei": { "keisei": {
"command": "npx", "command": "npx",

View file

@ -290,22 +290,24 @@ jobs:
echo "✓ Release $TAG published with all assets" echo "✓ Release $TAG published with all assets"
npm-publish: npm-publish:
name: Publish npm packages (optional) name: Publish npm packages to keigit.com
needs: release needs: release
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Graceful skip: if NPM_TOKEN secret is not configured, the first step # Graceful skip: if KEIGIT_TOKEN secret is not configured, the first
# reports "skipped" and exits 0 — Rust-binary release above still succeeds. # step reports "skipped" and exits 0 — Rust-binary release above still
# succeeds. Repository secret is keigit PAT with `write:package` scope
# for the keisei user/org on keigit.com.
steps: steps:
- name: Check NPM_TOKEN presence - name: Check KEIGIT_TOKEN presence
id: have_token id: have_token
env: env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} KEIGIT_TOKEN: ${{ secrets.KEIGIT_TOKEN }}
run: | run: |
if [ -n "${NPM_TOKEN:-}" ]; then if [ -n "${KEIGIT_TOKEN:-}" ]; then
echo "present=1" >> "$GITHUB_OUTPUT" echo "present=1" >> "$GITHUB_OUTPUT"
else else
echo "present=0" >> "$GITHUB_OUTPUT" echo "present=0" >> "$GITHUB_OUTPUT"
echo "::notice::NPM_TOKEN not set — skipping npm publish gracefully" echo "::notice::KEIGIT_TOKEN not set — skipping npm publish gracefully (configure repo secret to enable)"
fi fi
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
@ -315,7 +317,29 @@ jobs:
if: steps.have_token.outputs.present == '1' if: steps.have_token.outputs.present == '1'
with: with:
node-version: '20' node-version: '20'
registry-url: 'https://registry.npmjs.org'
# Compose .npmrc with keigit auth. The @keisei scope is pinned to
# keigit.com (matches publishConfig.registry in each package.json so
# an accidental `npm publish` cannot route to npm.org). NPM_TOKEN is
# also wired as a fallback for any sibling packages that publish to
# npm.org explicitly via their own publishConfig.
- name: Compose .npmrc (keigit auth)
if: steps.have_token.outputs.present == '1'
working-directory: _ts_packages
env:
KEIGIT_TOKEN: ${{ secrets.KEIGIT_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
set -euo pipefail
{
echo "@keisei:registry=https://keigit.com/api/packages/keisei/npm/"
echo "//keigit.com/:_authToken=${KEIGIT_TOKEN}"
if [ -n "${NPM_TOKEN:-}" ]; then
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}"
fi
} > .npmrc
# Sanity (no secrets in log — print only registry lines):
grep -v _authToken .npmrc
- name: Install deps - name: Install deps
if: steps.have_token.outputs.present == '1' if: steps.have_token.outputs.present == '1'
@ -330,15 +354,23 @@ jobs:
- name: Publish each package - name: Publish each package
if: steps.have_token.outputs.present == '1' if: steps.have_token.outputs.present == '1'
working-directory: _ts_packages working-directory: _ts_packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: | run: |
set -euo pipefail set -euo pipefail
# publishConfig.registry in each package.json decides destination.
# Currently only @keisei/mcp-server has a publishConfig — the other
# adapters skip publish (no registry pin → npm.org default → no
# token in .npmrc → publish fails → ::warning emitted, job continues).
for pkg in packages/*/; do for pkg in packages/*/; do
if [ -f "$pkg/package.json" ]; then if [ -f "$pkg/package.json" ]; then
echo "::group::publish $pkg" name=$(node -p "require('./$pkg/package.json').name")
echo "::group::publish $name"
( cd "$pkg" && npm publish --access public ) \ ( cd "$pkg" && npm publish --access public ) \
|| echo "::warning::publish failed for $pkg (continuing)" || echo "::warning::publish failed for $name (no registry pin, missing token, version conflict, or registry error — see log)"
echo "::endgroup::" echo "::endgroup::"
fi fi
done done
- name: Cleanup .npmrc
if: always()
working-directory: _ts_packages
run: rm -f .npmrc

4
.gitignore vendored
View file

@ -62,3 +62,7 @@ build/
__pycache__/ __pycache__/
*.pyc *.pyc
var/ var/
# RULE 0.8 — auth tokens; CI temp-creates _ts_packages/.npmrc per-job
_ts_packages/.npmrc
.npmrc

View file

@ -37,7 +37,7 @@ Paths inside `hooks/hooks.json` use `${CLAUDE_PLUGIN_ROOT}` (expanded by Claude
| Agents registered | yes, automatic | yes, copied to `~/.claude/agents/` | | Agents registered | yes, automatic | yes, copied to `~/.claude/agents/` |
| Skills registered | yes, automatic | yes, copied to `~/.claude/skills/` | | Skills registered | yes, automatic | yes, copied to `~/.claude/skills/` |
| Hooks wired | yes, via `hooks/hooks.json` | requires `--activate-hooks` (jq-merge of `settings-snippet.json`) | | Hooks wired | yes, via `hooks/hooks.json` | requires `--activate-hooks` (jq-merge of `settings-snippet.json`) |
| MCP server | yes, via `.mcp.json` (once `@keisei/mcp-server` is published) | same | | MCP server | yes, via `.mcp.json` (uses `@keisei/mcp-server` from keigit.com — requires `~/.npmrc` setup, see below) | same |
| 47 Rust primitives | **no** — plugin ships manifest sources only; no cargo build | yes, `--profile=<name>` builds the selected set | | 47 Rust primitives | **no** — plugin ships manifest sources only; no cargo build | yes, `--profile=<name>` builds the selected set |
| 13 shell primitives | **no** | yes, copied to `~/.claude/agents/_primitives/` | | 13 shell primitives | **no** | yes, copied to `~/.claude/agents/_primitives/` |
| Disk footprint | ~2 MB (plugin cache) | ~2 MB minimal up to ~200 MB full | | Disk footprint | ~2 MB (plugin cache) | ~2 MB minimal up to ~200 MB full |
@ -53,7 +53,15 @@ Paths inside `hooks/hooks.json` use `${CLAUDE_PLUGIN_ROOT}` (expanded by Claude
- Network access to `github.com/KeiSei84/KeiSeiKit` on `/plugin marketplace add` - Network access to `github.com/KeiSei84/KeiSeiKit` on `/plugin marketplace add`
**For the MCP server subset:** **For the MCP server subset:**
- `@keisei/mcp-server` published to npm — **STATUS: not yet published as of v0.16.0.** The `.mcp.json` entry is structurally correct and will activate automatically once the package is published. Until then, the `keisei` MCP server simply won't appear in your tool list — the agents, skills, and hooks all work without it. - `@keisei/mcp-server` available from **keigit.com**
(`https://keigit.com/api/packages/keisei/npm/`). One-time `~/.npmrc` setup:
```
@keisei:registry=https://keigit.com/api/packages/keisei/npm/
//keigit.com/:_authToken=<keigit PAT with read:package>
```
Without the `~/.npmrc` rows, `npx` cannot resolve the scoped
package and the `keisei` MCP server simply won't appear in your
tool list — the agents, skills, and hooks all work without it.
- Node.js 18+ (for `npx` to fetch the server on demand) - Node.js 18+ (for `npx` to fetch the server on demand)
**For the Rust primitives (classic install only):** **For the Rust primitives (classic install only):**
@ -62,7 +70,7 @@ Paths inside `hooks/hooks.json` use `${CLAUDE_PLUGIN_ROOT}` (expanded by Claude
## Known limitations ## Known limitations
1. **Rust primitives not auto-installed.** The plugin format doesn't currently express "also run `cargo build` at install time". We ship the manifest sources in-repo so that users who want the primitives can run `./install.sh --profile=full` alongside the plugin. A future version may add pre-built release binaries for common platforms (macOS arm64/x86_64, Linux x86_64) into `bin/` so the plugin can ship primitives without a cargo step. 1. **Rust primitives not auto-installed.** The plugin format doesn't currently express "also run `cargo build` at install time". We ship the manifest sources in-repo so that users who want the primitives can run `./install.sh --profile=full` alongside the plugin. A future version may add pre-built release binaries for common platforms (macOS arm64/x86_64, Linux x86_64) into `bin/` so the plugin can ship primitives without a cargo step.
2. **`@keisei/mcp-server` not yet on npm.** The `.mcp.json` entry is the canonical intent, but the package needs publishing first. See `_ts_packages/packages/mcp-server/README.md` for the publish pipeline. 2. **`@keisei/mcp-server` lives on keigit.com, not npm.org.** The `.mcp.json` entry uses `npx -y @keisei/mcp-server` which resolves through the `~/.npmrc` `@keisei:registry` line above. Without that line, `npx` will hit npm.org by default and 404. See `_ts_packages/packages/mcp-server/README.md` for the publish pipeline.
3. **Hooks use `${CLAUDE_PLUGIN_ROOT}`.** This is the official Claude Code plugin variable. Older Claude Code versions (<2.1) that predate plugin support will not expand this variable stick with classic install on those versions. 3. **Hooks use `${CLAUDE_PLUGIN_ROOT}`.** This is the official Claude Code plugin variable. Older Claude Code versions (<2.1) that predate plugin support will not expand this variable stick with classic install on those versions.
4. **No version-pinning yet.** `/plugin install keisei@keisei-marketplace` installs the default branch HEAD. For reproducible team installs, add the `--ref=<tag>` flag once it lands in Claude Code (currently in the spec per the extension schema `ref` field). 4. **No version-pinning yet.** `/plugin install keisei@keisei-marketplace` installs the default branch HEAD. For reproducible team installs, add the `--ref=<tag>` flag once it lands in Claude Code (currently in the spec per the extension schema `ref` field).

View file

@ -23,7 +23,7 @@ production work.
|---|---|---| |---|---|---|
| 24+ Rust primitives | varies (alpha → beta → concept) | Inspect each crate's `Cargo.toml` `package.metadata.keisei.maturity` if declared; otherwise treat as **alpha** unless you've personally exercised it. Most primitives are alpha — they build, type-check, and have unit tests, but have not been hardened against adversarial input or run at scale. | | 24+ Rust primitives | varies (alpha → beta → concept) | Inspect each crate's `Cargo.toml` `package.metadata.keisei.maturity` if declared; otherwise treat as **alpha** unless you've personally exercised it. Most primitives are alpha — they build, type-check, and have unit tests, but have not been hardened against adversarial input or run at scale. |
| Cortex daemon (`kei-cortex` HTTP + WS) | alpha | CLI-driven daemon works in author's daily use; HTTP REST + WS endpoints + 8-tool `/chat` agentic loop build clean. **Browser app (`cortex-ui`) and VSCode extension (`@keisei/vscode-cortex`) are concept-level** — scaffolds present, not production paths. | | Cortex daemon (`kei-cortex` HTTP + WS) | alpha | CLI-driven daemon works in author's daily use; HTTP REST + WS endpoints + 8-tool `/chat` agentic loop build clean. **Browser app (`cortex-ui`) and VSCode extension (`@keisei/vscode-cortex`) are concept-level** — scaffolds present, not production paths. |
| MCP server (`@keisei/mcp-server`) | alpha (unpublished) | **Not yet on npm.** Install via local dist build (see Quick start below). | | MCP server (`@keisei/mcp-server`) | alpha | Published to **keigit.com** (`https://keigit.com/api/packages/keisei/npm/`) — author-operated Forgejo npm registry on a public DNS. Configure your `~/.npmrc` per [`docs/PUBLISHING.md`](./docs/PUBLISHING.md), then `npm install @keisei/mcp-server`. Local dist build still works for development (see Quick start). |
| Sleep layer (Phase A / B / C) | alpha | Phase A queue (`/sleep-on-it` → cloud agent) + Phase B markdown morning report work. **Auto-codification of rules from sleep insights is not yet wired** — codification path is manual via `/escalate-recurrence`. Phase C deep-sleep refactor proposals run on a 7-day cadence and write plan-only markdown by default. | | Sleep layer (Phase A / B / C) | alpha | Phase A queue (`/sleep-on-it` → cloud agent) + Phase B markdown morning report work. **Auto-codification of rules from sleep insights is not yet wired** — codification path is manual via `/escalate-recurrence`. Phase C deep-sleep refactor proposals run on a 7-day cadence and write plan-only markdown by default. |
| Hooks (35 shipped) | beta | Tested in author's daily use (48 parallel Claude Code terminals). Pipeline hooks (`assemble-agents`, `no-hand-edit-agents`) are load-bearing; advisory hooks (RULE 0.12 / 0.13 / 0.14) are non-blocking. | | Hooks (35 shipped) | beta | Tested in author's daily use (48 parallel Claude Code terminals). Pipeline hooks (`assemble-agents`, `no-hand-edit-agents`) are load-bearing; advisory hooks (RULE 0.12 / 0.13 / 0.14) are non-blocking. |
| Skills + manifests + assembler | beta | Structured + `assembler-validate` gate runs on every `git commit` inside `~/.claude`. Schema is locked (see [`docs/AGENT-SCHEMA-LOCKED.md`](./docs/AGENT-SCHEMA-LOCKED.md)). | | Skills + manifests + assembler | beta | Structured + `assembler-validate` gate runs on every `git commit` inside `~/.claude`. Schema is locked (see [`docs/AGENT-SCHEMA-LOCKED.md`](./docs/AGENT-SCHEMA-LOCKED.md)). |
@ -123,19 +123,28 @@ outputs are human-readable markdown. You read, you decide what merges.
extension (`@keisei/vscode-cortex`) are concept-level only** — extension (`@keisei/vscode-cortex`) are concept-level only** —
scaffolds exist, no production wiring. Treat the daemon + CLI as scaffolds exist, no production wiring. Treat the daemon + CLI as
the supported surface; treat the GUI frontends as roadmap. the supported surface; treat the GUI frontends as roadmap.
- **`@keisei/mcp-server` npm package** — **not yet published to npm.** - **`@keisei/mcp-server` npm package** — published to **keigit.com**
Install via the local dist build: (the author-operated Forgejo npm registry, public DNS at
[`keigit.com`](https://keigit.com)). To install from the registry:
```bash
# ~/.npmrc — one-time setup
echo "@keisei:registry=https://keigit.com/api/packages/keisei/npm/" >> ~/.npmrc
echo "//keigit.com/:_authToken=<your-keigit-PAT>" >> ~/.npmrc
# PAT scope: read:package (write:package only if you publish)
npm install @keisei/mcp-server
```
For local development without the registry round-trip:
```bash ```bash
cd _ts_packages cd _ts_packages
bun install # or: npm install bun install && bun run -r build
bun run -r build # or: npm run -r build # output: _ts_packages/packages/mcp-server/dist/index.js
# mcp-server output lands in _ts_packages/packages/mcp-server/dist/
``` ```
Then point your MCP-aware client at the local `dist/` entry point.
Single-binary builds via `bun build --compile` are documented in Single-binary builds via `bun build --compile` are documented in
[`_ts_packages/packages/mcp-server/BUILD.md`](./_ts_packages/packages/mcp-server/BUILD.md) [`_ts_packages/packages/mcp-server/BUILD.md`](./_ts_packages/packages/mcp-server/BUILD.md)
(5-target matrix, ~8595 MB per binary). Do not assume npm-registry (5-target matrix, ~8595 MB per binary). `package.json` has
install will work until v1.0. `publishConfig.registry` pinned to `keigit.com` so an accidental
`npm publish` from this repo cannot route to npm.org.
- **Non-Claude clients** integrate via MCP + bridges, not native hooks. - **Non-Claude clients** integrate via MCP + bridges, not native hooks.
PreToolUse / PostToolUse / UserPromptSubmit / Stop semantics are PreToolUse / PostToolUse / UserPromptSubmit / Stop semantics are
Claude Code primitives. Other clients get capability exposure but Claude Code primitives. Other clients get capability exposure but

View file

@ -1,8 +1,7 @@
{ {
"name": "@keisei/mcp-server", "name": "@keisei/mcp-server",
"version": "0.14.0", "version": "0.14.0",
"private": true, "description": "MCP server exposing KeiSeiKit Rust primitives as Model Context Protocol tools — published to keigit.com (Forgejo npm registry, public DNS)",
"description": "MCP server exposing KeiSeiKit Rust primitives as Model Context Protocol tools (not yet published to npm — install via local dist build)",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@ -18,6 +17,15 @@
"files": [ "files": [
"dist" "dist"
], ],
"repository": {
"type": "git",
"url": "git+https://github.com/KeiSei84/KeiSeiKit-1.0.git",
"directory": "_ts_packages/packages/mcp-server"
},
"publishConfig": {
"registry": "https://keigit.com/api/packages/keisei/npm/",
"access": "public"
},
"scripts": { "scripts": {
"build": "tsc -b", "build": "tsc -b",
"test": "vitest run", "test": "vitest run",
@ -42,5 +50,6 @@
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=18.0.0"
}, },
"author": "Denis Parfionovich <parfionovich@keilab.io>" "author": "Denis Parfionovich <parfionovich@keilab.io>",
"license": "Apache-2.0"
} }

View file

@ -398,7 +398,7 @@ These are concatenated in role-declared order, with `\n\n---\n\n` separators bet
| Roles (7 roles) | stable | edit-local / read-only / git-ops / etc. locked; no churn | | Roles (7 roles) | stable | edit-local / read-only / git-ops / etc. locked; no churn |
| Assembler (compose logic) | stable | Generates .md from TOML + blocks; keimd integration active | | Assembler (compose logic) | stable | Generates .md from TOML + blocks; keimd integration active |
| Cortex stack | beta | kei-cortex (HTTP) + kei-tty (TUI) build clean; browser/VSCode frontends concept | | Cortex stack | beta | kei-cortex (HTTP) + kei-tty (TUI) build clean; browser/VSCode frontends concept |
| MCP Server (@keisei/mcp-server) | stable | Exports Rust atoms as MCP tools; published to keigit.com npm | | MCP Server (@keisei/mcp-server) | alpha | Exports Rust primitive CLIs as MCP tools; published to keigit.com (Forgejo npm registry, public DNS) under @keisei scope |
| Bridges | stable | 11 cross-tool format generators (.cursorrules, .windsurf/rules, GEMINI.md, etc.) | | Bridges | stable | 11 cross-tool format generators (.cursorrules, .windsurf/rules, GEMINI.md, etc.) |
| Sleep Layer (Phase A/B/C) | stable | Incubation (tasks), REM consolidation (reports), NREM deep-sleep (conflicts) | | Sleep Layer (Phase A/B/C) | stable | Incubation (tasks), REM consolidation (reports), NREM deep-sleep (conflicts) |
| Foreign-project ingestion | stable | kei-import <repo> proof-of-concept via Hermes validation | | Foreign-project ingestion | stable | kei-import <repo> proof-of-concept via Hermes validation |