Skip to content

Commit 67f0911

Browse files
committed
feat(cli): surface the MCP endpoint in the server-ready banner (#3167)
The MCP server (/api/v1/mcp) is a default-on core capability, but nothing in the os dev / os serve boot output pointed to it — a developer had to already know it was there to connect an AI client. This is the dev-loop discoverability gap #3167 set out to close: the platform's "let an AI operate the running app" channel was live but invisible. printServerReady now prints the MCP URL and the SKILL.md pointer whenever the surface is enabled — gated on isMcpServerEnabled(), the SAME switch that auto-loads the plugin and gates the route, so the banner can never advertise an endpoint that isn't served. Hidden when OS_MCP_SERVER_ENABLED=false. Runtime-verified: the line renders with the URL + skill pointer when enabled and is absent when disabled. CLI builds clean; lint clean. Closes the last (optional, DX) item on #3167 — the admission story itself landed in #3202/#3225. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pbmw3pMqNJfPbkvwh9Fkjs
1 parent 1b733db commit 67f0911

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

.changeset/mcp-dev-connect-hint.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'@objectstack/cli': patch
3+
---
4+
5+
feat(cli): surface the MCP endpoint in the server-ready banner (#3167)
6+
7+
The MCP server (`/api/v1/mcp`) is a default-on core capability, but nothing in
8+
the `os dev` / `os serve` boot output pointed to it — a developer had to already
9+
know it was there to connect an AI client. The server-ready banner now prints
10+
the MCP URL and the `SKILL.md` pointer whenever the surface is enabled
11+
(`isMcpServerEnabled()`, the same switch that auto-loads the plugin and gates
12+
the route), so an agent can operate the running app straight from the dev loop.
13+
Hidden when `OS_MCP_SERVER_ENABLED=false`.

packages/cli/src/commands/serve.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,11 @@ export default class Serve extends Command {
24552455
multiTenant: resolveMultiOrgEnabled(),
24562456
seededAdmin,
24572457
automation: automationSummary,
2458+
// #3167 — surface the default-on MCP endpoint in the dev loop, where an
2459+
// AI client can connect to operate the running app. Same decision point
2460+
// that auto-loads the plugin + gates the route, so the banner never
2461+
// advertises an endpoint that isn't served.
2462+
mcpEnabled: isMcpServerEnabled(),
24582463
});
24592464

24602465
// ── Publish the actually-bound port ────────────────────────────

packages/cli/src/utils/format.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ export interface ServerReadyOptions {
203203
* armed. Collected from the live engine after runtime.start().
204204
*/
205205
automation?: AutomationReadySummary;
206+
/**
207+
* Whether the MCP server surface (`/api/v1/mcp`) is on (#3167). Default-on
208+
* core capability, but nothing in the dev loop surfaces it — an AI client
209+
* (Claude Code, Cursor, …) can operate the running app the instant a
210+
* developer knows the endpoint is there. The banner is where they look, so
211+
* print the URL + the SKILL.md pointer when it's live.
212+
*/
213+
mcpEnabled?: boolean;
206214
}
207215

208216
export interface AutomationReadySummary {
@@ -233,6 +241,10 @@ export function printServerReady(opts: ServerReadyOptions) {
233241
if (opts.uiEnabled && opts.consolePath) {
234242
console.log(chalk.cyan(' ➜') + chalk.bold(' Console: ') + chalk.cyan(base + opts.consolePath + '/'));
235243
}
244+
if (opts.mcpEnabled) {
245+
console.log(chalk.cyan(' ➜') + chalk.bold(' MCP: ') + chalk.cyan(base + '/api/v1/mcp'));
246+
console.log(chalk.dim(` connect an AI client (Claude Code, Cursor, …) · skill: ${base}/api/v1/mcp/skill`));
247+
}
236248
if (opts.seededAdmin) {
237249
console.log('');
238250
console.log(

0 commit comments

Comments
 (0)