@nudge-ui/mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -0
- package/dist/LICENSE +21 -0
- package/dist/bridge.d.ts +79 -0
- package/dist/bridge.js +731 -0
- package/dist/cli-entry.d.ts +1 -0
- package/dist/cli-entry.js +5 -0
- package/dist/cli.d.ts +36 -0
- package/dist/cli.js +173 -0
- package/dist/cli.mjs +22663 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/protocol.d.ts +27 -0
- package/dist/protocol.js +18 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.js +243 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# `@nudge-ui/mcp`
|
|
2
|
+
|
|
3
|
+
`@nudge-ui/mcp` connects a local Nudge UI inspector to an MCP-capable coding
|
|
4
|
+
agent. It combines a standard MCP stdio server with a project-scoped loopback
|
|
5
|
+
browser bridge. The browser does not speak MCP directly.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pnpm add -D @nudge-ui/mcp
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Configure automatically
|
|
14
|
+
|
|
15
|
+
From the application project root, use [`add-mcp`](https://github.com/neon-solutions/add-mcp) to detect supported coding agents and write each host's native configuration format:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npx add-mcp \
|
|
19
|
+
'npx -y @nudge-ui/mcp@latest --project-id my-app --origin http://localhost:5173 --workspace-root .' \
|
|
20
|
+
--name nudge_ui
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The command prompts for detected project agents. Use `-a codex` (or another
|
|
24
|
+
supported agent name) to target one host, or `-y` to skip the prompt and use
|
|
25
|
+
the detected project agents. Keep this project-scoped; do not use `-g` unless
|
|
26
|
+
the configuration intentionally targets one fixed project.
|
|
27
|
+
|
|
28
|
+
`--origin` must exactly match the development application's browser origin.
|
|
29
|
+
The `--project-id` value must match the ID used by the Nudge host integration.
|
|
30
|
+
For standard Vite and Astro projects, `my-app` normally matches the project
|
|
31
|
+
directory name. Next.js and standalone HTML projects use host-specific IDs, so
|
|
32
|
+
retain the explicit ID from their integration configuration.
|
|
33
|
+
|
|
34
|
+
The generated command uses the published `@nudge-ui/mcp` package through
|
|
35
|
+
`npx`. Pin the package version instead of `@latest` when reproducible tool
|
|
36
|
+
versions are required. After configuration, restart or reload the agent host
|
|
37
|
+
so it refreshes its MCP tool catalog.
|
|
38
|
+
|
|
39
|
+
The package has no install-time project mutation. The manual configuration
|
|
40
|
+
below remains useful when an agent host is not supported by `add-mcp` or when
|
|
41
|
+
you need an explicit custom command.
|
|
42
|
+
|
|
43
|
+
After adding or changing the host configuration, restart or reload the MCP
|
|
44
|
+
server, or start a fresh agent task. Open **Connect MCP** from the inspector's
|
|
45
|
+
prompt menu for setup instructions, connection status, and explicit pairing.
|
|
46
|
+
You can pair a page before the agent starts listening. Ask the agent to call
|
|
47
|
+
`nudge_listen` and keep it active to enable sending. **Copy prompt** remains
|
|
48
|
+
available while the agent is idle; prompts are not queued.
|
|
49
|
+
|
|
50
|
+
For Codex desktop, confirm that `nudge_ui` appears in the current task after
|
|
51
|
+
the MCP restart. For Codex CLI, `codex mcp list` verifies the project entry.
|
|
52
|
+
Restart a long-running OpenCode service after adding or changing its MCP
|
|
53
|
+
configuration so it refreshes its tool catalog.
|
|
54
|
+
|
|
55
|
+
## Run manually
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
pnpm exec nudge-mcp \
|
|
59
|
+
--project-id my-app \
|
|
60
|
+
--origin http://localhost:5173 \
|
|
61
|
+
--workspace-root /path/to/my-app
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Pass the exact application origin with `--origin` (or
|
|
65
|
+
`NUDGE_UI_ORIGIN`). The bridge rejects browser origins that are not explicitly
|
|
66
|
+
configured; it never trusts the first origin that connects. The bridge chooses
|
|
67
|
+
a deterministic loopback port from the project ID so the inspector can find
|
|
68
|
+
it without a port file. Use `--port 0` for an ephemeral test port.
|
|
69
|
+
|
|
70
|
+
For integrations that establish the browser origin out of band, trusted host
|
|
71
|
+
code can use the `pairBrowser` API as an explicit manual approval path. An
|
|
72
|
+
unconfigured bridge does not accept HTTP pairing requests.
|
|
73
|
+
|
|
74
|
+
The agent should call `nudge_listen` immediately, apply the delivered prompt
|
|
75
|
+
through its normal source-editing workflow, call `nudge_report_status`, and
|
|
76
|
+
listen again. Canvas tools are limited to same-origin routes and agent-owned
|
|
77
|
+
groups.
|
package/dist/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Charles Smart
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/bridge.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type Server } from "node:http";
|
|
2
|
+
import type { AgentPromptRequest, AgentRequestOutcome, AgentStatusSnapshot, AgentStatusUpdate, CanvasCommandResult, PairingResponse } from "@nudge-ui/agent-protocol";
|
|
3
|
+
/** A clock port keeps command timeout tests deterministic. */
|
|
4
|
+
export interface BridgeClock {
|
|
5
|
+
now(): number;
|
|
6
|
+
setTimeout(callback: () => void, delayMs: number): unknown;
|
|
7
|
+
clearTimeout(handle: unknown): void;
|
|
8
|
+
}
|
|
9
|
+
export interface BrowserBridgeOptions {
|
|
10
|
+
/** Stable project identity used to scope every browser message. */
|
|
11
|
+
readonly projectId: string;
|
|
12
|
+
/** Canonical app origin that browser routes must use. */
|
|
13
|
+
readonly origin?: string;
|
|
14
|
+
/** Explicit browser origins accepted by the loopback HTTP server. */
|
|
15
|
+
readonly allowedOrigins?: readonly string[];
|
|
16
|
+
readonly host?: "127.0.0.1" | "::1" | "localhost";
|
|
17
|
+
/** Use port 0 in tests or when several projects run concurrently. */
|
|
18
|
+
readonly port?: number;
|
|
19
|
+
readonly commandTimeoutMs?: number;
|
|
20
|
+
readonly clock?: BridgeClock;
|
|
21
|
+
/** Test seam; production defaults to cryptographically random tokens. */
|
|
22
|
+
readonly tokenFactory?: () => string;
|
|
23
|
+
/** Test seam; production defaults to random UUIDs. */
|
|
24
|
+
readonly idFactory?: () => string;
|
|
25
|
+
/**
|
|
26
|
+
* Best-effort hook used by the CLI to reopen the last paired page when an
|
|
27
|
+
* agent rearms listening but no browser controller stream is attached.
|
|
28
|
+
*/
|
|
29
|
+
readonly onControllerUnavailable?: (pageUrl: string) => Promise<void> | void;
|
|
30
|
+
}
|
|
31
|
+
export interface BridgeAddress {
|
|
32
|
+
readonly host: string;
|
|
33
|
+
readonly port: number;
|
|
34
|
+
readonly url: string;
|
|
35
|
+
}
|
|
36
|
+
export type BridgeLifecycle = "created" | "listening" | "closed";
|
|
37
|
+
export interface BrowserBridge {
|
|
38
|
+
readonly httpServer: Server;
|
|
39
|
+
readonly projectId: string;
|
|
40
|
+
readonly origin: string | null;
|
|
41
|
+
/** The configured origin, or the explicitly approved browser origin. */
|
|
42
|
+
readonly effectiveOrigin: string | null;
|
|
43
|
+
readonly lifecycle: BridgeLifecycle;
|
|
44
|
+
readonly address: BridgeAddress | null;
|
|
45
|
+
readonly sessionToken: string | null;
|
|
46
|
+
readonly lastPageUrl: string | null;
|
|
47
|
+
/** Current companion/browser state, safe to expose to the browser. */
|
|
48
|
+
getStatus(): AgentStatusSnapshot;
|
|
49
|
+
start(): Promise<BridgeAddress>;
|
|
50
|
+
close(): Promise<void>;
|
|
51
|
+
/** Blocks until a paired browser dispatches a prompt. */
|
|
52
|
+
waitForPrompt(signal?: AbortSignal): Promise<AgentPromptRequest>;
|
|
53
|
+
/** Marks the agent-side listener as stopped without ending the project. */
|
|
54
|
+
cancelListener(reason?: string): void;
|
|
55
|
+
/** Reports the terminal result for the currently running browser request. */
|
|
56
|
+
updateRequestStatus(update: AgentStatusUpdate | AgentRequestOutcome): void;
|
|
57
|
+
/** Sends a Canvas command to the browser and waits for one bounded ack. */
|
|
58
|
+
dispatchCanvasCommand(command: CanvasCommandInput): Promise<CanvasCommandResult>;
|
|
59
|
+
/** Returns the currently paired browser token to the host process only. */
|
|
60
|
+
pairBrowser(projectId: string, requestOrigin: string, pageUrl?: string): PairingResponse;
|
|
61
|
+
/** Revokes a browser pairing; no data is written to disk. */
|
|
62
|
+
disconnectBrowser(token: string): void;
|
|
63
|
+
}
|
|
64
|
+
export type CanvasCommandInput = Omit<import("@nudge-ui/agent-protocol").ReadCanvasStateCommand, "commandId"> & {
|
|
65
|
+
readonly commandId?: string;
|
|
66
|
+
} | Omit<import("@nudge-ui/agent-protocol").PresentRoutesCommand, "commandId"> & {
|
|
67
|
+
readonly commandId?: string;
|
|
68
|
+
} | Omit<import("@nudge-ui/agent-protocol").FocusCanvasGroupCommand, "commandId"> & {
|
|
69
|
+
readonly commandId?: string;
|
|
70
|
+
} | Omit<import("@nudge-ui/agent-protocol").FitCanvasCommand, "commandId"> & {
|
|
71
|
+
readonly commandId?: string;
|
|
72
|
+
} | Omit<import("@nudge-ui/agent-protocol").RemoveCanvasGroupCommand, "commandId"> & {
|
|
73
|
+
readonly commandId?: string;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Creates the local browser bridge. It binds only to loopback and keeps every
|
|
77
|
+
* pairing, prompt, command, and acknowledgement in process memory.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createLoopbackBridge(options: BrowserBridgeOptions): BrowserBridge;
|