Skip to content

Commit 9760844

Browse files
authored
feat(cli): surface the MCP endpoint in the server-ready banner (#3167) (#3239)
printServerReady prints the /api/v1/mcp URL + SKILL.md pointer when the MCP surface is enabled (isMcpServerEnabled — the same switch that auto-loads the plugin and gates the route), so a developer can connect an AI client straight from the os dev / os serve boot output. Hidden when OS_MCP_SERVER_ENABLED=false. Closes the dev-loop discoverability goal of #3167.
1 parent 0e41302 commit 9760844

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
@@ -2464,6 +2464,11 @@ export default class Serve extends Command {
24642464
multiTenant: resolveMultiOrgEnabled(),
24652465
seededAdmin,
24662466
automation: automationSummary,
2467+
// #3167 — surface the default-on MCP endpoint in the dev loop, where an
2468+
// AI client can connect to operate the running app. Same decision point
2469+
// that auto-loads the plugin + gates the route, so the banner never
2470+
// advertises an endpoint that isn't served.
2471+
mcpEnabled: isMcpServerEnabled(),
24672472
});
24682473

24692474
// ── 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)