mcp-native 0.9.3 → 1.0.0-beta.1
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 +30 -80
- package/bin/mcp-native.mjs +260 -0
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# mcp-native
|
|
4
4
|
|
|
5
|
-
### One entry point for the MCP Native
|
|
5
|
+
### One entry point for the low-level MCP Native runtime and UI layers
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/mcp-native)
|
|
8
8
|
[](https://www.npmjs.com/package/mcp-native)
|
|
@@ -13,28 +13,42 @@
|
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
`mcp-native` is the
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
`@mcp-native/host`
|
|
20
|
-
|
|
16
|
+
`mcp-native` is the convenience entry point for the core, A2UI, React Native, mixed-surface, and
|
|
17
|
+
WebView APIs. It does not include the official MCP SDK adapter or the high-level host. Install
|
|
18
|
+
[`@mcp-native/mcp`](https://www.npmjs.com/package/@mcp-native/mcp) for the adapter or
|
|
19
|
+
[`@mcp-native/host`](https://www.npmjs.com/package/@mcp-native/host) for the connect-call-render
|
|
20
|
+
workflow. Use this package when the application wants to compose the low-level layers itself.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
This package contains the validated low-level React Native feature set: A2UI v1 Candidate and the
|
|
23
|
+
stable MCP Apps `2026-01-26` host flow. Public standard-contract registration and
|
|
24
|
+
application-defined custom input adapters remain post-1.0 work. Negotiated, locally compiled
|
|
25
|
+
semantic host extensions are already supported.
|
|
26
26
|
|
|
27
27
|
For the big picture, start with the [product guide](https://github.com/pablospaniard/mcp-native/blob/main/docs/product-guide.md).
|
|
28
28
|
|
|
29
29
|
## Install
|
|
30
30
|
|
|
31
|
+
Until the stable `1.0.0` release, select the beta package explicitly:
|
|
32
|
+
|
|
31
33
|
```bash
|
|
32
|
-
npm install mcp-native react
|
|
34
|
+
npm install mcp-native@beta react
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
React `>=18.1.0` is the only peer dependency. Native components and platform integrations are
|
|
36
38
|
supplied by the host application. The package is ESM-only and includes TypeScript declarations.
|
|
37
39
|
|
|
40
|
+
Run the bundled local diagnostics or generate safe starting points without network access:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx mcp-native doctor
|
|
44
|
+
npx mcp-native scaffold-catalog src/mcp
|
|
45
|
+
npx mcp-native scaffold-extension com.example/data-grid DataGrid src/mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Scaffolds refuse to overwrite existing files. The extension command emits a closed, bounded
|
|
49
|
+
manifest and a local React Native registration skeleton; the application must still negotiate it
|
|
50
|
+
and supply explicit policy.
|
|
51
|
+
|
|
38
52
|
## A2UI v1 Candidate path
|
|
39
53
|
|
|
40
54
|
The package re-exports the APIs needed to negotiate the project-owned binding, resolve official
|
|
@@ -42,78 +56,15 @@ v1 JSONL lifecycle envelopes, maintain bounded ordered surface state, apply expl
|
|
|
42
56
|
component/event/function policies, and mount the supported native subset through
|
|
43
57
|
`A2uiV1NativeSurface`. The mounted surface keeps typed input edits renderer-local and returns validated
|
|
44
58
|
official action envelopes to a host callback; it never selects a return transport. See the
|
|
45
|
-
[
|
|
59
|
+
[A2UI package guide](https://github.com/pablospaniard/mcp-native/tree/main/packages/a2ui)
|
|
46
60
|
and the [`@mcp-native/react-native` adapter documentation](https://github.com/pablospaniard/mcp-native/tree/main/packages/react-native#a2ui-v1-render-plan-adapter).
|
|
47
61
|
|
|
48
|
-
## Legacy custom `0.1` migration
|
|
49
|
-
|
|
50
|
-
For `0.9.x`, migrate these imports to `mcp-native/legacy`. Root aliases are removed at `1.0.0`;
|
|
51
|
-
the explicit legacy subpath stays frozen for migration and security fixes.
|
|
52
|
-
|
|
53
|
-
```tsx
|
|
54
|
-
import { McpNativeRuntime, createAllowlistActionPolicy, type McpClient } from "mcp-native";
|
|
55
|
-
import {
|
|
56
|
-
McpNativeSurface,
|
|
57
|
-
parseA2uiSurface,
|
|
58
|
-
useMcpNativeActionDispatcher,
|
|
59
|
-
} from "mcp-native/legacy";
|
|
60
|
-
import { Button, Text, TextInput, View } from "react-native";
|
|
61
|
-
|
|
62
|
-
const components = { Button, Text, TextInput, View };
|
|
63
|
-
|
|
64
|
-
const client: McpClient = {
|
|
65
|
-
async listTools() {
|
|
66
|
-
return { tools: [] };
|
|
67
|
-
},
|
|
68
|
-
async callTool(name, arguments_) {
|
|
69
|
-
return {
|
|
70
|
-
content: [{ type: "text", text: `Called ${name}` }],
|
|
71
|
-
structuredContent: { name, arguments: arguments_ },
|
|
72
|
-
};
|
|
73
|
-
},
|
|
74
|
-
async readResource(uri) {
|
|
75
|
-
return { contents: [{ uri, text: "" }] };
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const runtime = new McpNativeRuntime(client, {
|
|
80
|
-
actionPolicy: createAllowlistActionPolicy([{ name: "continue_flow" }]),
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const surface = parseA2uiSurface({
|
|
84
|
-
version: "0.1",
|
|
85
|
-
root: {
|
|
86
|
-
id: "welcome",
|
|
87
|
-
type: "container",
|
|
88
|
-
children: [
|
|
89
|
-
{ id: "title", type: "text", text: "Hello from MCP" },
|
|
90
|
-
{
|
|
91
|
-
id: "continue",
|
|
92
|
-
type: "button",
|
|
93
|
-
label: "Continue",
|
|
94
|
-
action: { type: "tool", name: "continue_flow" },
|
|
95
|
-
},
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
function NativeScreen() {
|
|
101
|
-
const onAction = useMcpNativeActionDispatcher(runtime, {
|
|
102
|
-
onError: (error) => console.error("MCP action failed", error),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return <McpNativeSurface surface={surface} components={components} onAction={onAction} />;
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
The host supplies the locally bundled native components and explicitly allows the tools a surface may dispatch, including their arguments. Without an `actionPolicy`, surface action dispatch is denied; trusted host code can still call `callTool()` directly after JSON validation. MCP Native never downloads and executes server-provided React Native JavaScript.
|
|
110
|
-
|
|
111
62
|
## Included packages
|
|
112
63
|
|
|
113
64
|
| Package | What it provides |
|
|
114
65
|
| ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
|
|
115
66
|
| [`@mcp-native/core`](https://www.npmjs.com/package/@mcp-native/core) | MCP client contracts, runtime delegation, JSON types, and declared tool actions. |
|
|
116
|
-
| [`@mcp-native/a2ui`](https://www.npmjs.com/package/@mcp-native/a2ui) | Feature-scoped v1 Candidate
|
|
67
|
+
| [`@mcp-native/a2ui`](https://www.npmjs.com/package/@mcp-native/a2ui) | Feature-scoped v1 Candidate negotiation, parsing, and surface state. |
|
|
117
68
|
| [`@mcp-native/react-native`](https://www.npmjs.com/package/@mcp-native/react-native) | Trusted plans, local v1 state/actions, hooks, and a host-owned component catalog. |
|
|
118
69
|
| [`@mcp-native/webview`](https://www.npmjs.com/package/@mcp-native/webview) | Stable Apps discovery, sandbox, native adapter, and JSON-RPC bridge. |
|
|
119
70
|
|
|
@@ -121,10 +72,9 @@ Install an individual package instead when you only need one layer.
|
|
|
121
72
|
|
|
122
73
|
Use the separately installable [`@mcp-native/mcp`](https://github.com/pablospaniard/mcp-native/tree/main/packages/mcp) package to connect these APIs to the official MCP TypeScript SDK without forcing that SDK dependency on every `mcp-native` consumer.
|
|
123
74
|
|
|
124
|
-
##
|
|
75
|
+
## Available across the package line
|
|
125
76
|
|
|
126
77
|
- transport-independent MCP runtime contracts;
|
|
127
|
-
- isolated migration support for the deprecated custom `0.1` surface;
|
|
128
78
|
- declared tool-action dispatch;
|
|
129
79
|
- strict A2UI resource-link resolution from tool results;
|
|
130
80
|
- schema-validated A2UI v1 JSONL lifecycle state and explicit host policies;
|
|
@@ -151,8 +101,8 @@ Use the separately installable [`@mcp-native/mcp`](https://github.com/pablospani
|
|
|
151
101
|
|
|
152
102
|
For the release-by-release history, see the
|
|
153
103
|
[changelog](https://github.com/pablospaniard/mcp-native/blob/main/CHANGELOG.md). The runnable
|
|
154
|
-
[Expo Go todo app](
|
|
155
|
-
pieces working together.
|
|
104
|
+
[Expo Go todo app](https://github.com/pablospaniard/mcp-native/tree/main/examples/expo-go-todolist)
|
|
105
|
+
shows the main A2UI and React Native pieces working together.
|
|
156
106
|
|
|
157
107
|
## Security model
|
|
158
108
|
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { basename, join, resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const [, , command = "doctor", ...arguments_] = process.argv;
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
if (command === "doctor") {
|
|
10
|
+
runDoctor(arguments_);
|
|
11
|
+
} else if (command === "scaffold-catalog") {
|
|
12
|
+
scaffoldCatalog(arguments_);
|
|
13
|
+
} else if (command === "scaffold-extension") {
|
|
14
|
+
scaffoldExtension(arguments_);
|
|
15
|
+
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
16
|
+
printHelp();
|
|
17
|
+
} else {
|
|
18
|
+
fail(`Unknown command ${JSON.stringify(command)}. Run mcp-native help.`);
|
|
19
|
+
}
|
|
20
|
+
} catch (error) {
|
|
21
|
+
fail(error instanceof Error ? error.message : "MCP Native CLI failed.");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function runDoctor(commandArguments) {
|
|
25
|
+
const json = commandArguments.includes("--json");
|
|
26
|
+
const directoryArgument = commandArguments.find((value) => value !== "--json") ?? ".";
|
|
27
|
+
const directory = resolve(directoryArgument);
|
|
28
|
+
const manifestPath = join(directory, "package.json");
|
|
29
|
+
if (!existsSync(manifestPath)) {
|
|
30
|
+
throw new Error(`No package.json found in ${directory}`);
|
|
31
|
+
}
|
|
32
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
33
|
+
const dependencyMaps = [
|
|
34
|
+
manifest.dependencies ?? {},
|
|
35
|
+
manifest.devDependencies ?? {},
|
|
36
|
+
manifest.peerDependencies ?? {},
|
|
37
|
+
];
|
|
38
|
+
const dependencies = Object.assign({}, ...dependencyMaps);
|
|
39
|
+
const hasWorkspaces = manifest.workspaces !== undefined;
|
|
40
|
+
const mcpNativeEntries = Object.entries(dependencies).filter(
|
|
41
|
+
([name]) => name === "mcp-native" || name.startsWith("@mcp-native/"),
|
|
42
|
+
);
|
|
43
|
+
const findings = [];
|
|
44
|
+
if (mcpNativeEntries.length === 0) {
|
|
45
|
+
findings.push(
|
|
46
|
+
finding(
|
|
47
|
+
hasWorkspaces ? "warning" : "error",
|
|
48
|
+
hasWorkspaces ? "packages-not-at-workspace-root" : "packages-missing",
|
|
49
|
+
hasWorkspaces
|
|
50
|
+
? "No MCP Native package is declared at the workspace root; run doctor in the consuming workspace too."
|
|
51
|
+
: "No MCP Native package is declared.",
|
|
52
|
+
),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const ranges = new Set(mcpNativeEntries.map(([, range]) => String(range)));
|
|
56
|
+
if (ranges.size > 1) {
|
|
57
|
+
findings.push(
|
|
58
|
+
finding(
|
|
59
|
+
"error",
|
|
60
|
+
"version-ranges-mixed",
|
|
61
|
+
"MCP Native packages use different version ranges; align them before installation.",
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const usesNative = mcpNativeEntries.some(
|
|
66
|
+
([name]) =>
|
|
67
|
+
name === "mcp-native" || name === "@mcp-native/react-native" || name === "@mcp-native/host",
|
|
68
|
+
);
|
|
69
|
+
if (usesNative && dependencies.react === undefined) {
|
|
70
|
+
findings.push(
|
|
71
|
+
finding("error", "react-missing", "A React dependency is required by the native renderer."),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (usesNative && dependencies["react-native"] === undefined) {
|
|
75
|
+
findings.push(
|
|
76
|
+
finding(
|
|
77
|
+
"warning",
|
|
78
|
+
"react-native-not-declared",
|
|
79
|
+
"No React Native dependency is declared; ignore this only when the package is supplied by the application platform.",
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
const metroPaths = ["metro.config.js", "metro.config.cjs", "metro.config.mjs"].map((name) =>
|
|
84
|
+
join(directory, name),
|
|
85
|
+
);
|
|
86
|
+
if (usesNative && hasWorkspaces && !metroPaths.some(existsSync)) {
|
|
87
|
+
findings.push(
|
|
88
|
+
finding(
|
|
89
|
+
"warning",
|
|
90
|
+
"metro-workspace-config-missing",
|
|
91
|
+
"This workspace has no Metro configuration; verify watchFolders, resolver paths, and duplicate React exclusion.",
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (usesNative && !existsSync(join(directory, "tsconfig.json"))) {
|
|
96
|
+
findings.push(
|
|
97
|
+
finding(
|
|
98
|
+
"warning",
|
|
99
|
+
"typescript-config-missing",
|
|
100
|
+
"No tsconfig.json was found, so typed catalog adapters cannot be checked here.",
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (findings.length === 0) {
|
|
105
|
+
findings.push(
|
|
106
|
+
finding("ok", "configuration-ready", "No common package or workspace issue found."),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
const report = { directory, packageName: manifest.name ?? basename(directory), findings };
|
|
110
|
+
if (json) {
|
|
111
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
112
|
+
} else {
|
|
113
|
+
process.stdout.write(`MCP Native doctor: ${report.packageName}\n`);
|
|
114
|
+
for (const item of findings) {
|
|
115
|
+
process.stdout.write(`${item.level.toUpperCase()} ${item.code}: ${item.message}\n`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (findings.some((item) => item.level === "error")) process.exitCode = 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function scaffoldCatalog(commandArguments) {
|
|
122
|
+
const outputDirectory = resolve(commandArguments[0] ?? ".");
|
|
123
|
+
const outputPath = join(outputDirectory, "mcpNativeCatalog.tsx");
|
|
124
|
+
writeNewFile(outputPath, catalogTemplate());
|
|
125
|
+
process.stdout.write(`Created ${outputPath}\n`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function scaffoldExtension(commandArguments) {
|
|
129
|
+
const [extensionId, componentName, directoryArgument = "."] = commandArguments;
|
|
130
|
+
if (
|
|
131
|
+
extensionId === undefined ||
|
|
132
|
+
!/^[a-z0-9]+(?:[._-][a-z0-9]+)+(?:\/[a-z0-9]+(?:[._-][a-z0-9]+)*)?$/u.test(extensionId)
|
|
133
|
+
) {
|
|
134
|
+
throw new Error("scaffold-extension requires a namespaced extension ID");
|
|
135
|
+
}
|
|
136
|
+
if (componentName === undefined || !/^[A-Z][A-Za-z0-9]*$/u.test(componentName)) {
|
|
137
|
+
throw new Error("scaffold-extension requires a PascalCase component name");
|
|
138
|
+
}
|
|
139
|
+
const outputDirectory = resolve(directoryArgument);
|
|
140
|
+
const manifestPath = join(outputDirectory, `${componentName}.manifest.json`);
|
|
141
|
+
const componentPath = join(outputDirectory, `${componentName}.tsx`);
|
|
142
|
+
assertNewFiles([manifestPath, componentPath]);
|
|
143
|
+
writeNewFile(
|
|
144
|
+
manifestPath,
|
|
145
|
+
`${JSON.stringify(extensionManifest(extensionId, componentName), null, 2)}\n`,
|
|
146
|
+
);
|
|
147
|
+
writeNewFile(componentPath, extensionComponentTemplate(componentName));
|
|
148
|
+
process.stdout.write(`Created ${manifestPath}\nCreated ${componentPath}\n`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function assertNewFiles(paths) {
|
|
152
|
+
const existingPath = paths.find(existsSync);
|
|
153
|
+
if (existingPath !== undefined) {
|
|
154
|
+
throw new Error(`Refusing to overwrite existing file ${existingPath}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function writeNewFile(path, content) {
|
|
159
|
+
if (existsSync(path)) throw new Error(`Refusing to overwrite existing file ${path}`);
|
|
160
|
+
mkdirSync(resolve(path, ".."), { recursive: true });
|
|
161
|
+
writeFileSync(path, content, { encoding: "utf8", flag: "wx" });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function extensionManifest(extensionId, componentName) {
|
|
165
|
+
return {
|
|
166
|
+
profileVersion: "1",
|
|
167
|
+
extensionId,
|
|
168
|
+
catalogId: `${extensionId}@1`,
|
|
169
|
+
catalogVersion: "1",
|
|
170
|
+
schemaVersion: "1.0.0",
|
|
171
|
+
componentName: `${extensionId}:${componentName}`,
|
|
172
|
+
propsSchema: {
|
|
173
|
+
type: "object",
|
|
174
|
+
properties: { label: { type: "string", minLength: 1, maxLength: 128 } },
|
|
175
|
+
required: ["label"],
|
|
176
|
+
additionalProperties: false,
|
|
177
|
+
},
|
|
178
|
+
events: [],
|
|
179
|
+
platforms: ["android", "ios"],
|
|
180
|
+
accessibility: {
|
|
181
|
+
ownership: "host",
|
|
182
|
+
requiresLabel: true,
|
|
183
|
+
behavior: "Expose one host-rendered labeled value.",
|
|
184
|
+
},
|
|
185
|
+
resourceNeeds: [],
|
|
186
|
+
permissionNeeds: [],
|
|
187
|
+
limits: {
|
|
188
|
+
maximumInstances: 16,
|
|
189
|
+
maximumEventPayloadValues: 8,
|
|
190
|
+
maximumEventPayloadStringCodeUnits: 512,
|
|
191
|
+
maximumPropsValues: 16,
|
|
192
|
+
maximumPropsStringCodeUnits: 2048,
|
|
193
|
+
maximumUpdatesPerSurface: 32,
|
|
194
|
+
},
|
|
195
|
+
fallback: { kind: "reject" },
|
|
196
|
+
compatibility: { owner: "Replace with the responsible application team" },
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function catalogTemplate() {
|
|
201
|
+
return `import { createA2uiV1NativeHost } from "@mcp-native/react-native";
|
|
202
|
+
import { Button, Text, TextInput, View } from "react-native";
|
|
203
|
+
|
|
204
|
+
// Keep this registration at module scope so component identity and local state remain stable.
|
|
205
|
+
export const mcpNativeHost = createA2uiV1NativeHost({
|
|
206
|
+
components: { Button, Text, TextInput, View },
|
|
207
|
+
allowedEventNames: [],
|
|
208
|
+
allowedFunctionNames: [],
|
|
209
|
+
layoutContracts: {
|
|
210
|
+
View: {
|
|
211
|
+
allowedParents: ["bounded", "scroll", "unbounded"],
|
|
212
|
+
sizing: "intrinsic",
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function extensionComponentTemplate(componentName) {
|
|
220
|
+
return `import manifestJson from "./${componentName}.manifest.json";
|
|
221
|
+
import { createNativeHostExtensionRegistration } from "@mcp-native/react-native";
|
|
222
|
+
import { Text } from "react-native";
|
|
223
|
+
|
|
224
|
+
function ${componentName}({ label, accessibilityLabel }: { label: string; accessibilityLabel?: string }) {
|
|
225
|
+
return <Text accessibilityLabel={accessibilityLabel}>{label}</Text>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export const ${componentName[0].toLowerCase()}${componentName.slice(1)}Registration =
|
|
229
|
+
createNativeHostExtensionRegistration(
|
|
230
|
+
manifestJson,
|
|
231
|
+
${componentName},
|
|
232
|
+
({ accessibilityLabel, semanticProps }) => {
|
|
233
|
+
if (typeof semanticProps.label !== "string") {
|
|
234
|
+
throw new Error("Validated extension props do not match the local component");
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
label: semanticProps.label,
|
|
238
|
+
...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
);
|
|
242
|
+
`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function finding(level, code, message) {
|
|
246
|
+
return { level, code, message };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function printHelp() {
|
|
250
|
+
process.stdout.write(`Usage:
|
|
251
|
+
mcp-native doctor [directory] [--json]
|
|
252
|
+
mcp-native scaffold-catalog [output-directory]
|
|
253
|
+
mcp-native scaffold-extension <extension-id> <PascalCaseName> [output-directory]
|
|
254
|
+
`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function fail(message) {
|
|
258
|
+
process.stderr.write(`mcp-native: ${message}\n`);
|
|
259
|
+
process.exitCode = 1;
|
|
260
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
4
|
"description": "Convenience package for the MCP Native runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"a2ui",
|
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
"url": "git+https://github.com/pablospaniard/mcp-native.git",
|
|
20
20
|
"directory": "packages/mcp-native"
|
|
21
21
|
},
|
|
22
|
+
"bin": {
|
|
23
|
+
"mcp-native": "./bin/mcp-native.mjs"
|
|
24
|
+
},
|
|
22
25
|
"files": [
|
|
26
|
+
"bin",
|
|
23
27
|
"dist",
|
|
24
28
|
"LICENSE",
|
|
25
29
|
"README.md"
|
|
@@ -44,10 +48,10 @@
|
|
|
44
48
|
"access": "public"
|
|
45
49
|
},
|
|
46
50
|
"dependencies": {
|
|
47
|
-
"@mcp-native/a2ui": "^0.
|
|
48
|
-
"@mcp-native/core": "^0.
|
|
49
|
-
"@mcp-native/react-native": "^0.
|
|
50
|
-
"@mcp-native/webview": "^0.
|
|
51
|
+
"@mcp-native/a2ui": "^1.0.0-beta.1",
|
|
52
|
+
"@mcp-native/core": "^1.0.0-beta.1",
|
|
53
|
+
"@mcp-native/react-native": "^1.0.0-beta.1",
|
|
54
|
+
"@mcp-native/webview": "^1.0.0-beta.1"
|
|
51
55
|
},
|
|
52
56
|
"peerDependencies": {
|
|
53
57
|
"react": ">=18.1.0"
|