@nowline/mcp 0.8.4 → 0.8.6
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/dist/branding.d.ts +3 -3
- package/dist/branding.js +3 -3
- package/dist/diagnostics.d.ts +3 -3
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/generated/ui-bundle.d.ts.map +1 -1
- package/dist/generated/ui-bundle.js +2 -2
- package/dist/generated/ui-bundle.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +6 -6
- package/dist/prompts.js.map +1 -1
- package/dist/schema-vocab.d.ts +3 -3
- package/dist/schema-vocab.d.ts.map +1 -1
- package/dist/schemas.d.ts +7 -7
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +5 -3
- package/dist/server.js.map +1 -1
- package/dist/ui/entry.js +17 -7
- package/dist/ui/entry.js.map +1 -1
- package/package.json +19 -17
- package/src/branding.ts +3 -3
- package/src/generated/ui-bundle.ts +2 -2
- package/src/index.ts +3 -3
- package/src/prompts.ts +7 -7
- package/src/server.ts +5 -3
- package/src/ui/entry.ts +19 -8
package/src/index.ts
CHANGED
|
@@ -15,8 +15,8 @@ import { readFileSync } from 'node:fs';
|
|
|
15
15
|
import { createServer } from 'node:http';
|
|
16
16
|
import { dirname, resolve } from 'node:path';
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';
|
|
19
|
+
import { StdioServerTransport } from '@modelcontextprotocol/server/stdio';
|
|
20
20
|
import { expandRootPath } from './root-path.js';
|
|
21
21
|
import { createMcpServer } from './server.js';
|
|
22
22
|
|
|
@@ -104,7 +104,7 @@ const server = createMcpServer({
|
|
|
104
104
|
|
|
105
105
|
if (port !== undefined) {
|
|
106
106
|
// Streamable HTTP transport — stateless (no session management).
|
|
107
|
-
const transport = new
|
|
107
|
+
const transport = new NodeStreamableHTTPServerTransport({
|
|
108
108
|
sessionIdGenerator: undefined,
|
|
109
109
|
});
|
|
110
110
|
await server.connect(transport);
|
package/src/prompts.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// MCP prompt registrations for @nowline/mcp.
|
|
2
2
|
// Wired into the server via registerPrompts(server).
|
|
3
3
|
|
|
4
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
7
|
export function registerPrompts(server: McpServer): void {
|
|
@@ -13,13 +13,13 @@ export function registerPrompts(server: McpServer): void {
|
|
|
13
13
|
title: 'Create Roadmap from Description',
|
|
14
14
|
description:
|
|
15
15
|
'Generate a new .nowline roadmap from a plain-English description. Composes the DSL reference and example files so the LLM has full context.',
|
|
16
|
-
argsSchema: {
|
|
16
|
+
argsSchema: z.object({
|
|
17
17
|
description: z
|
|
18
18
|
.string()
|
|
19
19
|
.describe(
|
|
20
20
|
'Plain-English description of the roadmap you want to create (teams, timeline, key milestones, etc.).',
|
|
21
21
|
),
|
|
22
|
-
},
|
|
22
|
+
}),
|
|
23
23
|
},
|
|
24
24
|
({ description }) => ({
|
|
25
25
|
messages: [
|
|
@@ -64,7 +64,7 @@ export function registerPrompts(server: McpServer): void {
|
|
|
64
64
|
title: 'Fix Roadmap Diagnostics',
|
|
65
65
|
description:
|
|
66
66
|
'Fix validation errors in a .nowline file. Describe the validate→fix→re-validate loop keyed on NL.E#### diagnostic codes.',
|
|
67
|
-
argsSchema: {
|
|
67
|
+
argsSchema: z.object({
|
|
68
68
|
source: z
|
|
69
69
|
.string()
|
|
70
70
|
.describe('The .nowline source text that contains validation errors.'),
|
|
@@ -74,7 +74,7 @@ export function registerPrompts(server: McpServer): void {
|
|
|
74
74
|
.describe(
|
|
75
75
|
'JSON array of diagnostic objects from the validate tool. Omit to let the LLM call validate itself.',
|
|
76
76
|
),
|
|
77
|
-
},
|
|
77
|
+
}),
|
|
78
78
|
},
|
|
79
79
|
({ source, diagnostics }) => {
|
|
80
80
|
const diagSection = diagnostics
|
|
@@ -113,7 +113,7 @@ export function registerPrompts(server: McpServer): void {
|
|
|
113
113
|
title: 'Convert to Nowline',
|
|
114
114
|
description:
|
|
115
115
|
'Convert a gantt/timeline from another format (Mermaid gantt, MS Project, Excel, Google Sheets, CSV) into Nowline DSL. Uses the conversion guide resource for format-specific rules.',
|
|
116
|
-
argsSchema: {
|
|
116
|
+
argsSchema: z.object({
|
|
117
117
|
source: z
|
|
118
118
|
.string()
|
|
119
119
|
.describe('The source content to convert (paste the raw text/CSV/XML here).'),
|
|
@@ -130,7 +130,7 @@ export function registerPrompts(server: McpServer): void {
|
|
|
130
130
|
.describe(
|
|
131
131
|
'Source format hint. Use "auto" (default) to let the LLM detect the format.',
|
|
132
132
|
),
|
|
133
|
-
},
|
|
133
|
+
}),
|
|
134
134
|
},
|
|
135
135
|
({ source, from }) => {
|
|
136
136
|
const formatHint =
|
package/src/server.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
registerAppResource,
|
|
15
15
|
registerAppTool,
|
|
16
16
|
} from '@modelcontextprotocol/ext-apps/server';
|
|
17
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
17
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
18
18
|
import { type NowlineFile, parseNowlineJson, printNowlineFile } from '@nowline/core';
|
|
19
19
|
import {
|
|
20
20
|
type ExportFormat,
|
|
@@ -616,7 +616,8 @@ export function createMcpServer(opts: McpServerOptions = {}): McpServer {
|
|
|
616
616
|
.boolean()
|
|
617
617
|
.optional()
|
|
618
618
|
.describe(
|
|
619
|
-
'When true, force the in-chat MCP Apps preview
|
|
619
|
+
'When true, force the in-chat MCP Apps preview; when false, return inline output even on an MCP Apps host. ' +
|
|
620
|
+
'Omit to follow the host: on MCP Apps hosts the preview auto-renders via _meta.ui.',
|
|
620
621
|
),
|
|
621
622
|
}),
|
|
622
623
|
outputSchema: RenderOutputSchema,
|
|
@@ -652,7 +653,8 @@ export function createMcpServer(opts: McpServerOptions = {}): McpServer {
|
|
|
652
653
|
pngScale: args.scale,
|
|
653
654
|
};
|
|
654
655
|
const host = createNodeHostEnv(filePath);
|
|
655
|
-
|
|
656
|
+
// Explicit true/false wins; undefined follows the host's capabilities.
|
|
657
|
+
const appActive = args.preview ?? clientSupportsAppsUi(server);
|
|
656
658
|
// Skip the full render when the bytes won't be used: apps host with
|
|
657
659
|
// no write-to-disk path and no review attachment requested.
|
|
658
660
|
const needsRender = !appActive || !!args.output || args.review === true;
|
package/src/ui/entry.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
declare const __MCP_VERSION__: string;
|
|
26
26
|
|
|
27
27
|
import { App } from '@modelcontextprotocol/ext-apps';
|
|
28
|
-
import { mountLivePreview } from '@nowline/preview';
|
|
28
|
+
import { type LivePreviewHandle, mountLivePreview } from '@nowline/preview';
|
|
29
29
|
import type { NowOverride, ThemeOverride } from '@nowline/preview-shell';
|
|
30
30
|
import {
|
|
31
31
|
type PreviewPayload,
|
|
@@ -59,8 +59,13 @@ function toThemeOverride(theme: string | undefined): ThemeOverride {
|
|
|
59
59
|
|
|
60
60
|
let mounted = false;
|
|
61
61
|
let mountedSource: string | undefined;
|
|
62
|
+
let live: LivePreviewHandle | undefined;
|
|
62
63
|
|
|
63
|
-
function
|
|
64
|
+
function hostTheme(app: App): 'light' | 'dark' | undefined {
|
|
65
|
+
return app.getHostContext()?.theme;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function mountFromPayload(payload: PreviewPayload, app: App): void {
|
|
64
69
|
const root = document.getElementById('nl-preview-root');
|
|
65
70
|
if (!root || typeof payload.source !== 'string') {
|
|
66
71
|
return;
|
|
@@ -72,11 +77,14 @@ function mountFromPayload(payload: PreviewPayload): void {
|
|
|
72
77
|
// re-invocation on the same iframe) tears down the prior mount first.
|
|
73
78
|
if (mounted) {
|
|
74
79
|
if (payload.source === mountedSource) return;
|
|
80
|
+
live?.dispose();
|
|
81
|
+
live = undefined;
|
|
75
82
|
(root as HTMLElement).replaceChildren();
|
|
76
83
|
}
|
|
77
84
|
|
|
78
|
-
mountLivePreview(root as HTMLElement, {
|
|
85
|
+
live = mountLivePreview(root as HTMLElement, {
|
|
79
86
|
source: payload.source,
|
|
87
|
+
mode: hostTheme(app) ?? 'system',
|
|
80
88
|
initialView: {
|
|
81
89
|
theme: toThemeOverride(payload.theme),
|
|
82
90
|
now: (payload.now ?? 'today') as NowOverride,
|
|
@@ -187,7 +195,7 @@ async function bootstrap(): Promise<void> {
|
|
|
187
195
|
// before the server finishes rendering. Mirrors the official ext-apps examples.
|
|
188
196
|
app.ontoolinput = ({ arguments: args }) => {
|
|
189
197
|
const payload = parsePreviewFromArguments(args as Record<string, unknown> | undefined);
|
|
190
|
-
if (payload) mountFromPayload(payload);
|
|
198
|
+
if (payload) mountFromPayload(payload, app);
|
|
191
199
|
};
|
|
192
200
|
|
|
193
201
|
// Authoritative path: the server-resolved lean preview payload. Reconciles the
|
|
@@ -195,11 +203,14 @@ async function bootstrap(): Promise<void> {
|
|
|
195
203
|
app.ontoolresult = ({ content, isError }) => {
|
|
196
204
|
if (isError) return;
|
|
197
205
|
const payload = parsePreviewFromContent(content);
|
|
198
|
-
if (payload) mountFromPayload(payload);
|
|
206
|
+
if (payload) mountFromPayload(payload, app);
|
|
199
207
|
};
|
|
200
208
|
|
|
201
|
-
// Re-report when the host changes our width / available height.
|
|
202
|
-
app.onhostcontextchanged = () =>
|
|
209
|
+
// Re-report when the host changes our width / available height / theme.
|
|
210
|
+
app.onhostcontextchanged = () => {
|
|
211
|
+
live?.handle.setMode(hostTheme(app) ?? 'system');
|
|
212
|
+
reportHeight(app);
|
|
213
|
+
};
|
|
203
214
|
|
|
204
215
|
await app.connect();
|
|
205
216
|
watchSize(app);
|
|
@@ -207,7 +218,7 @@ async function bootstrap(): Promise<void> {
|
|
|
207
218
|
|
|
208
219
|
if (!mounted) {
|
|
209
220
|
const fallback = readPayload();
|
|
210
|
-
if (fallback) mountFromPayload(fallback);
|
|
221
|
+
if (fallback) mountFromPayload(fallback, app);
|
|
211
222
|
}
|
|
212
223
|
}
|
|
213
224
|
|