🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

loopback-mcp-server

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

loopback-mcp-server - npm Package Compare versions

Comparing version
0.9.1
to
0.9.2
+76
-1
CHANGELOG.md

@@ -8,4 +8,79 @@ # Changelog

## [0.9.1] — 2026-07-27
## [0.9.2] — 2026-08-02
Ships the `init` fix below to adopters. 0.9.1 still writes a git-clone MCP
config, so source being correct changed nothing until this release.
### Added — `npm run bump <version>`
A release moves SIX hand-typed fields across five files (package.json,
`SERVER_VERSION`, server.json's version *and* every `packages[].version`, the
plugin manifest, and the marketplace entry). The gates enforce that they agree,
so a partial bump fails CI — but a *forgotten* bump fails later and worse:
`npm publish` refuses with "cannot publish over the previously published
versions" after the notes are written and the commit is pushed. That happened
on this release. The command edits only; build, gates and publish stay manual.
### Fixed — `init` handed every adopter a git-clone MCP config
`serverCommand()` emitted `npx -y github:joshidikshant/loopback` on any
EPHEMERAL run — which is precisely how the README documents onboarding
(`npx loopback-mcp-server init`). Every adopter following it got `.mcp.json`,
`.codex/config.toml` and `.gemini/settings.json` pointing at a **git clone that
runs a full `tsc` build on every cold MCP start**. That was the right call when
nothing was published; it became wrong the moment `loopback-mcp-server` shipped
to npm, and it survived because no gate could reach the branch. Now
`npx -y loopback-mcp-server`, unpinned so adopters get fixes without re-running
init. The four docs handing out the same stale command are corrected too.
Found by an adversarial audit that *reproduced* it rather than arguing it, and
gated twice over:
- `init-gate` runs the CLI from an `_npx`-shaped fixture — the only path that
reaches the branch. A first version invoked the normal `dist/index.js` and
**passed with the git spec restored**; the canary caught it.
- Its guard-the-guard then had the same disease: it searched raw text for
`"npx"` while the temp dir was named `loopback-npx-…`, so an absolute path in
a `node <path>` command satisfied it. Now asserts the parsed `command` field.
### Added — `npm run verify:release`
Post-publish verification of all three channels, by using them: installs the
published tarball into a clean directory, renders `init` from it, **runs the
MCP command init actually wrote** (not a path the script composes — the audit
reproduced a false green there too), confirms the MCP Registry listing resolves
to the shipped version, and runs the plugin's registered command from an empty
directory. Tools are checked by NAME, not count, so a rename cannot hide.
Deliberately not a per-push gate: it needs the network and tests published
artifacts, so on a PR it would pass while the branch is broken. Sweep is 19.
### Fixed — the plugin channel was two releases stale
A structural review found the Claude Code plugin shipping a **fourth** copy of
the skill playbook that nothing rendered, so it silently kept the
pre-attachments version while the other three were fixed. Alongside it, two
version fields still read `0.8.0` after two published releases, and the plugin
told Claude Code to install via `npx github:joshidikshant/loopback` — a git
clone that runs a full `tsc` build on every cold start — when the package is on
npm.
- `plugin/skills/loopback/SKILL.md` synced from the canonical template.
- `plugin/.claude-plugin/plugin.json` and `.claude-plugin/marketplace.json`
now track `package.json`.
- `plugin/.mcp.json` installs `loopback-mcp-server` from npm.
- `init-gate` gained five assertions covering all of it, canaried three ways;
the sweep is 18 checks. The npm release touches none of these files, which is
exactly why they rotted.
### Removed
`fv-probe.mjs` — a one-off Playwright scratch file from pass 6, referenced by
nothing.
### Changed — the repo map documents the whole tree
The six root dot-directories are `init` output (the repo onboards itself, and
`init-gate` re-renders them each CI run), but nothing said so, which read as
clutter. The map now covers them, `public/`, `assets/`, and the two root
manifests that do different jobs — `registry.json` for shadcn, `server.json`
for the MCP Registry. Also corrected the widget size, still quoted as
46KB/15KB against a measured 57KB/19KB.
## [0.9.1] — 2026-07-27 — published to npm and the MCP Registry
### Added — MCP Registry identity (`mcpName` + `server.json`)

@@ -12,0 +87,0 @@ The official MCP Registry proves package ownership by fetching the **published**

@@ -27,3 +27,13 @@ /**

const PACKAGE_ROOT = resolve(__dirname, "..");
const REPO_SPEC = "github:joshidikshant/loopback";
/**
* What an ephemeral (npx) run points agent configs at.
*
* This was `github:joshidikshant/loopback` back when nothing stable was
* published — which made every adopter who followed the README's own
* `npx loopback-mcp-server init` command git-CLONE the repo and run a full
* `tsc` build on every cold MCP start. The package is on npm now, so the
* ephemeral branch resolves a published tarball instead. Unpinned on
* purpose: an adopter should get fixes without re-running init.
*/
const NPM_SPEC = "loopback-mcp-server";
const SECTION_BEGIN = "<!-- loopback:queue:begin -->";

@@ -110,3 +120,3 @@ const SECTION_END = "<!-- loopback:queue:end -->";

* - Stable checkout elsewhere → absolute path (fast startup).
* - Ephemeral npx run → `npx github:` (nothing stable to point at).
* - Ephemeral npx run → `npx loopback-mcp-server` (the published package).
*/

@@ -117,3 +127,3 @@ function serverCommand(cwd) {

if (ephemeral || !existsSync(entry))
return { command: "npx", args: ["-y", REPO_SPEC] };
return { command: "npx", args: ["-y", NPM_SPEC] };
const inside = relative(cwd, entry);

@@ -120,0 +130,0 @@ if (!inside.startsWith("..") && !isAbsolute(inside)) {

+1
-1

@@ -6,3 +6,3 @@ /** MCP server definition: nine loopback_* tools over the feedback store. */

import { itemMarkdown, listMarkdown } from "./format.js";
export const SERVER_VERSION = "0.9.1";
export const SERVER_VERSION = "0.9.2";
function ok(text, structured) {

@@ -9,0 +9,0 @@ return {

@@ -69,2 +69,6 @@ /**

assert(srv.version === pkg.version && srv.packages.every((x) => x.version === pkg.version), `server.json versions track package.json (${srv.version} / ${srv.packages.map((x) => x.version).join(",")} vs ${pkg.version})`);
// The registry REJECTS on this rather than truncating, and it is the kind of
// field that grows during a docs pass. Caught for real: the first draft ran
// 191 chars and `mcp-publisher validate` 422'd.
assert(srv.description.length > 0 && srv.description.length <= 100, `server.json description is within the registry's 100-char limit (${srv.description.length})`);
assert(srv.packages.every((x) => x.identifier === pkgJson.name), `server.json package identifier is the published npm name (${srv.packages.map((x) => x.identifier).join(",")})`);

@@ -71,0 +75,0 @@ console.log(`✅ version + registry-identity parity: ${SERVER_VERSION} / ${srv.name}`);

@@ -16,3 +16,3 @@ # Claude Code × Loopback

# or zero-install from GitHub:
claude mcp add --scope user loopback -- npx -y github:joshidikshant/loopback
claude mcp add --scope user loopback -- npx -y loopback-mcp-server
```

@@ -19,0 +19,0 @@

@@ -15,3 +15,3 @@ # Codex × Loopback

args = ["/ABS/PATH/loopback/dist/index.js"]
# or zero-install: command = "npx" / args = ["-y", "github:joshidikshant/loopback"]
# or zero-install: command = "npx" / args = ["-y", "loopback-mcp-server"]
```

@@ -18,0 +18,0 @@

@@ -24,3 +24,3 @@ # Gemini CLI × Loopback

Zero-install alternative: `"command": "npx", "args": ["-y", "github:joshidikshant/loopback"]`.
Zero-install alternative: `"command": "npx", "args": ["-y", "loopback-mcp-server"]`.

@@ -27,0 +27,0 @@ **HTTP variant** — point at the long-running central instance instead:

{
"name": "loopback-mcp-server",
"mcpName": "io.github.joshidikshant/loopback",
"version": "0.9.1",
"author": "Dikshant Joshi",
"version": "0.9.2",
"files": [

@@ -23,2 +24,3 @@ "dist",

"build": "tsc",
"bump": "node scripts/bump-version.mjs",
"prepare": "npm run build",

@@ -39,3 +41,4 @@ "start": "node dist/index.js",

"a11y-gate": "node scripts/a11y-gate.mjs",
"canary": "node scripts/canary-all.mjs"
"canary": "node scripts/canary-all.mjs",
"verify:release": "node scripts/release-verify.mjs"
},

@@ -42,0 +45,0 @@ "repository": {

+41
-10

@@ -18,5 +18,5 @@ # Loopback

*Real screenshot: the contact form's backend bug was pinned, claimed by
claude-code, fixed with a PR, verified — pin and badge are green. The wrong AI
answer is still amber/open.*
*Seeded demo capture (generated by `scripts/screenshot.mjs`): the contact form's
backend bug pinned, claimed by claude-code, marked fixed with a linked change,
verified — pin and badge green. The wrong AI answer is still amber/open.*

@@ -90,3 +90,3 @@ ## Why

|---|---|---|
| **Claude Code** | `claude mcp add --scope user loopback -- npx -y github:joshidikshant/loopback` — or the plugin: `claude plugin marketplace add joshidikshant/loopback && claude plugin install loopback@loopback` | `@AGENTS.md` import in CLAUDE.md + skill at `.claude/skills/loopback/` → [claude.md](integrations/claude.md) |
| **Claude Code** | `claude mcp add --scope user loopback -- npx -y loopback-mcp-server` — or the plugin: `claude plugin marketplace add joshidikshant/loopback && claude plugin install loopback@loopback` | `@AGENTS.md` import in CLAUDE.md + skill at `.claude/skills/loopback/` → [claude.md](integrations/claude.md) |
| **Codex** | `~/.codex/config.toml`: `[mcp_servers.loopback]` `command`/`args` (or project-scoped `.codex/config.toml`) | AGENTS.md read natively + native SKILL.md at `.agents/skills/loopback/` → [codex.md](integrations/codex.md) |

@@ -361,6 +361,18 @@ | **Gemini CLI** | `~/.gemini/settings.json` → `mcpServers.loopback` | AGENTS.md via `context.fileName` + `@AGENTS.md` in GEMINI.md + `/loopback` command → [gemini.md](integrations/gemini.md) |

npm publish --otp=<code> # 2FA code from your authenticator
mcp-publisher validate # checks server.json against the live registry
mcp-publisher login github # opens a browser
mcp-publisher publish # reads server.json
npm run verify:release # proves all three channels from a clean dir
```
Run `validate` before `publish` — it checks the manifest against the real
registry without spending an attempt. Run `verify:release` after, and read what
it prints: it installs the published tarball into a clean directory, renders
`init` from it, speaks real MCP to the result, confirms the registry listing
resolves to the version you just shipped, and runs the plugin's own registered
command from an empty directory. Every one of those steps has caught a real bug
that the source-side gates could not see. `description` is capped at **100
characters** and is rejected, not truncated, past it, so `npm run smoke`
asserts that limit locally as well.
## Tests

@@ -429,5 +441,5 @@

the ingestion boundary.
7. **Widget is ~46KB / 15KB gzipped, not the ~10KB sketch** — ring buffers, failure-body
capture, live pins, and the walkthrough earn their bytes; still zero deps,
one file.
7. **Widget is 57KB / 19KB gzipped, not the ~10KB sketch** — ring buffers, failure-body
capture, live pins, repro steps, the route journey and the walkthrough earn
their bytes; still zero deps, one file, served pre-compressed with an ETag.
8. **Marker-based merges** — `init` re-runs are byte-idempotent; files a human

@@ -446,9 +458,28 @@ has taken over (generated marker removed) are left untouched.

design/ shared tokens.css — one design system for widget, dashboard, registry
skills/ canonical loopback SKILL.md (installed for Claude + Codex)
public/ built dashboard + the published shadcn registry (public/r)
skills/ CANONICAL loopback SKILL.md — every other copy is rendered from it
integrations/ canonical playbook + per-agent setup + widget embed + keep-alive
plugin/ Claude Code plugin (skill + MCP registration); repo doubles as its marketplace
scripts/ e2e.mjs · the six gates · screenshot.mjs
docs/ the decision history (spec → memo → paths → technical path)
scripts/ e2e.mjs · the six gates · canary-all.mjs · screenshot.mjs
docs/ the decision history (spec → memo → paths → technical path) + ROADMAP
assets/ the README screenshot (generated by scripts/screenshot.mjs)
```
Two manifests at the root do different jobs: `registry.json` publishes the
**shadcn** components, and `server.json` is the **MCP Registry** entry (see
[Publishing to the MCP Registry](#publishing-to-the-mcp-registry)).
The root also carries agent config that `init` itself writes — the repo
onboards *itself*, so these are working proof the command produces what it
claims, and `init-gate` re-renders them on every CI run to prove they have not
drifted:
```
AGENTS.md · CLAUDE.md · GEMINI.md the queue playbook, per agent
.claude/ .agents/ the loopback skill for Claude Code / Codex
.codex/ .gemini/ per-agent MCP + command registration
.mcp.json MCP server registration for this repo
.claude-plugin/ marketplace manifest (repo hosts its own plugin)
```
MIT © Dikshant Joshi