Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,15 @@ function guideGroups(prefix: string) {
],
},
{
text: 'Recipes & Advanced',
text: 'Agent-Native',
items: [
{ text: 'Agent-Native', link: `${prefix}/guide/agent-native` },
],
},
{
text: 'Recipes',
items: [
{ text: 'Standalone CLI', link: `${prefix}/guide/standalone-cli` },
{ text: 'Agent-Native (experimental)', link: `${prefix}/guide/agent-native` },
],
},
] satisfies { text: string, items: DefaultTheme.NavItemWithLink[] }[]
Expand Down
2 changes: 1 addition & 1 deletion docs/adapters/cac.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ my-devframe # dev server at http://localhost:9999/
my-devframe --port 8080
my-devframe build --out-dir dist-static
my-devframe build --out-dir dist-static --base /devframe/
my-devframe mcp # stdio MCP server (experimental)
my-devframe mcp # stdio MCP server
```

Standalone CLI serves the SPA at `/` by default. The `/__devframe/` prefix is for *hosted* adapters where devframe mounts alongside an existing app — see [Mount paths](./#mount-paths).
Expand Down
3 changes: 0 additions & 3 deletions docs/adapters/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ outline: deep

# MCP

> [!WARNING] Experimental
> The agent-native surface is experimental and may change without a major version bump.

Translates a devframe's agent host into a [Model Context Protocol](https://modelcontextprotocol.io) server so coding agents (Claude Desktop, Cursor, Zed, Claude Code) can call flagged RPCs and read exposed resources.

```ts
Expand Down
4 changes: 0 additions & 4 deletions docs/errors/DF0014.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ outline: deep

# DF0014: Invalid Agent Field

::: warning Experimental
The agent-native surface is experimental and may change without a major version bump until it stabilizes.
:::

## Message

> RPC function "`{name}`" has an invalid `agent` field — `description` must be a non-empty string.
Expand Down
4 changes: 0 additions & 4 deletions docs/errors/DF0015.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ outline: deep

# DF0015: Agent Tool Already Registered

::: warning Experimental
The agent-native surface is experimental and may change without a major version bump until it stabilizes.
:::

## Message

> Agent tool "`{id}`" is already registered.
Expand Down
4 changes: 0 additions & 4 deletions docs/errors/DF0016.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ outline: deep

# DF0016: Agent Resource Already Registered

::: warning Experimental
The agent-native surface is experimental and may change without a major version bump until it stabilizes.
:::

## Message

> Agent resource "`{id}`" is already registered.
Expand Down
4 changes: 0 additions & 4 deletions docs/errors/DF0017.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ outline: deep

# DF0017: MCP Server Start Failure

::: warning Experimental
The agent-native surface is experimental and may change without a major version bump until it stabilizes.
:::

## Message

> Failed to start MCP server (`{transport}`): `{reason}`
Expand Down
4 changes: 0 additions & 4 deletions docs/guide/agent-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ outline: deep

# Agent-Native Devframe

::: warning Experimental
The agent-native surface (`agent` field on `defineRpcFunction`, `DevframeAgentHost`, and the `devframe/adapters/mcp` adapter) is experimental and may change without a major version bump until it stabilizes.
:::

Devframe can expose the same surface a browser UI consumes — RPC functions, resources, and shared state — to coding agents (Claude Desktop / Cursor / Zed / Claude Code, or any MCP-speaking client). Agent exposure is opt-in per function; functions stay private by default.

## How it works
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/devframe-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ interface DevframeNodeContext {
rpc: RpcFunctionsHost // register + broadcast + sharedState
views: DevframeViewHost // static file hosting (`hostStatic`)
diagnostics: DevframeDiagnosticsHost
agent: DevframeAgentHost // experimental
agent: DevframeAgentHost // expose tools + resources to coding agents
services: DevframeServicesHost // typed cross-plugin service registry

scope: (id) => DevframeScopedNodeContext // namespaced view (preferred)
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Run it:
```sh
node ./my-devframe.js # dev server on http://localhost:9999/
node ./my-devframe.js build # self-contained static deploy in dist-static/
node ./my-devframe.js mcp # stdio MCP server (experimental)
node ./my-devframe.js mcp # stdio MCP server
```

The CLI adapter serves the SPA at `/` by default. When the same devframe is embedded inside a host (`vite`, `embedded`), the default becomes `/.my-devframe/`. Override either side via `defineDevframe({ basePath })`.
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/standalone-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ my-tool --config ./my.config.mjs
my-tool --port 8080 --no-open
my-tool build --out-dir dist-static # self-contained static deploy
my-tool build --out-dir dist-static --base /tool/ # …under a custom base
my-tool mcp # agent exposure (experimental)
my-tool mcp # agent exposure
```

## Nuxt SPA setup
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/adapters/_shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ function resolveMcpConfig(mcp: boolean | McpRouteOptions | undefined): McpRouteO
* and the client dials `<page-host>:<port><path>`. Without `port` the path
* stays relative, resolved against `__connection.json`'s own location (the
* same-server default).
*
* @experimental
*/
export function resolveMcpConnectionMeta(
def: DevframeDefinition,
Expand Down
4 changes: 2 additions & 2 deletions packages/devframe/src/adapters/cac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function createCac(d: DevframeDefinition, options: CreateCacOptions = {})
// `true` default, silently enabling MCP. Declaring just `--mcp` yields the
// opt-in tri-state — absent → `undefined` (falls through to `cli.mcp`),
// `--mcp` → `true`, `--no-mcp` → `false` (handled by CAC's `--no-` prefix).
.option('--mcp', 'Expose an MCP server over HTTP at /__mcp (use --no-mcp to disable) [experimental]')
.option('--mcp', 'Expose an MCP server over HTTP at /__mcp (use --no-mcp to disable)')

// Register typed flags from the definition ahead of `cli.configure`
// so authors can still override or augment via the escape hatch.
Expand Down Expand Up @@ -120,7 +120,7 @@ export function createCac(d: DevframeDefinition, options: CreateCacOptions = {})
}

cli
.command('mcp', 'Start an MCP server exposing agent-facing tools (stdio) [experimental]')
.command('mcp', 'Start an MCP server exposing agent-facing tools (stdio)')
.action(async () => {
// MCP clients expect JSON-RPC on stdout — route welcome/logging
// noise out of the way. Logs-SDK diagnostics land on stderr by
Expand Down
3 changes: 0 additions & 3 deletions packages/devframe/src/adapters/mcp/build-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ export function buildMcpServerFromContext(
/**
* Build an MCP server over the agent surface of a devframe definition.
* Currently supports `stdio` transport only.
*
* @experimental The agent-native surface is experimental and may change
* without a major version bump until it stabilizes.
*/
export async function createMcpServer(
definition: DevframeDefinition,
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/adapters/mcp/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ interface McpSession {
* loopback-default DNS-rebinding protection that — unlike the WS upgrade's
* `isAllowedOrigin` — also rejects `Origin`-less requests, so a route-based
* endpoint isn't reachable by an arbitrary local process.
*
* @experimental
*/
export function createMcpFetchHandler(
ctx: DevframeNodeContext,
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/adapters/mcp/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export interface MountedMcpHttp {
* legitimate MCP 404 (unknown session) isn't swallowed by h3's
* "Response-with-404 falls through to the next handler" rule (which would
* otherwise hand the request to the SPA static catch-all).
*
* @experimental
*/
export function mountMcpHttp(
app: H3,
Expand Down
3 changes: 0 additions & 3 deletions packages/devframe/src/adapters/mcp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
// Requires `@modelcontextprotocol/server` to be installed as a peer
// dependency. Importing this entry without the SDK throws at load time
// with the usual Node module-not-found error.
//
// @experimental The agent-native surface is experimental and may change
// without a major version bump until it stabilizes.

export {
createMcpServer,
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/cli/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ const GATEWAY_TOOLS: Tool[] = [
* the instance registry and list each one's MCP tools) and
* `devframe_connect_call-tool` (invoke one tool on one instance over its
* Streamable-HTTP endpoint) — and holds no domain knowledge of its own.
*
* @experimental
*/
export async function startConnectServer(options: ConnectServerOptions = {}): Promise<ConnectServerHandle> {
const sdk = await importSdk()
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { keepAlive, parsePortsFlag, startConnectServer } from './connect'
* The `devframe` bin — the framework's own CLI, distinct from the per-app
* CLI shells authors build with `createCac(definition)`. It hosts the
* app-independent commands; today that is `connect`, the MCP connector.
*
* @experimental
*/
export async function runDevframeCli(argv: string[] = process.argv): Promise<void> {
const cli = cac('devframe')
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/node/agent-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export type AgentArgsFallback = 'wrap' | 'drop'
* - without schemas, `arg0`/`arg1`/… keys are collected when present
* - an empty object becomes a zero-argument call
* - anything else follows the {@link AgentArgsFallback}
*
* @experimental
*/
export function coerceAgentPositionalArgs(
args: unknown,
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/node/host-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ interface RegisteredResource {
* devframe. Auto-discovers RPC functions with an `agent` field from
* `ctx.rpc.definitions`, and accepts plugin-registered tools /
* resources via `registerTool` / `registerResource`.
*
* @experimental
*/
export class DevframeAgentHost implements DevframeAgentHostType {
public readonly events: EventEmitter<DevframeAgentHostEvents> = createEventEmitter()
Expand Down
11 changes: 0 additions & 11 deletions packages/devframe/src/node/instance-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import { diagnostics } from './diagnostics'
/**
* One running devframe instance, as recorded in the instance registry.
* Records are self-describing JSON — additive fields are safe.
*
* @experimental The agent-native surface is experimental and may change
* without a major version bump until it stabilizes.
*/
export interface DevframeInstanceRecord {
/** Process id of the dev server. */
Expand Down Expand Up @@ -37,8 +34,6 @@ export interface DevframeInstanceRecord {

/**
* Handle returned by {@link registerDevframeInstance}.
*
* @experimental
*/
export interface DevframeInstanceRegistration {
/** The registry file backing this registration. */
Expand Down Expand Up @@ -89,8 +84,6 @@ function isRegistryDisabled(): boolean {
* crash are pruned by readers whose liveness probe fails. Registration never
* throws — a write failure degrades to a coded warning (`DF0045`), since a
* dev server must not die over discovery metadata.
*
* @experimental
*/
export function registerDevframeInstance(
record: DevframeInstanceRecord,
Expand Down Expand Up @@ -130,8 +123,6 @@ export function registerDevframeInstance(
/**
* Read every record in the registry directory, dropping unparseable files.
* Liveness is the caller's concern — see {@link probeDevframeInstance}.
*
* @experimental
*/
export function readDevframeInstances(options: { instancesDir?: string } = {}): DevframeInstanceRecord[] {
const dir = resolveInstancesDir(options.instancesDir)
Expand Down Expand Up @@ -248,8 +239,6 @@ async function probeDevframeInstance(
* records left behind by killed processes shadow the server currently bound
* there: per `(port, basePath)` only the newest record survives, older
* ghosts are pruned with the dead.
*
* @experimental
*/
export async function listLiveDevframeInstances(
options: { instancesDir?: string, timeoutMs?: number } = {},
Expand Down
2 changes: 0 additions & 2 deletions packages/devframe/src/node/rpc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { agentReadResource } from './agent-read-resource'
* Built-in agent introspection RPC functions. Registered automatically
* by `createHostContext`. Not themselves agent-exposed (no `agent`
* field) — they power the MCP adapter and any future agent CLI.
*
* @experimental
*/
export const BUILTIN_AGENT_RPC = [
agentListTools,
Expand Down
7 changes: 0 additions & 7 deletions packages/devframe/src/rpc/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ export type RpcFunctionType = 'static' | 'action' | 'event' | 'query'
* the function is surfaced to agents (e.g. via the devframe MCP adapter)
* as a callable tool. Functions without an `agent` field are not exposed —
* default-deny.
*
* @experimental The agent-native surface is experimental and may change
* without a major version bump until it stabilizes.
*/
export interface RpcFunctionAgentOptions {
/**
Expand Down Expand Up @@ -260,8 +257,6 @@ export type RpcFunctionDefinition<
/**
* Expose this function to agents (e.g. via the MCP adapter).
* When omitted, the function is not agent-exposed (default-deny).
*
* @experimental
*/
agent?: RpcFunctionAgentOptions
/** Setup function called with context to initialize handler and dump */
Expand Down Expand Up @@ -308,8 +303,6 @@ export type RpcFunctionDefinition<
/**
* Expose this function to agents (e.g. via the MCP adapter).
* When omitted, the function is not agent-exposed (default-deny).
*
* @experimental
*/
agent?: RpcFunctionAgentOptions
/** Setup function called with context to initialize handler and dump */
Expand Down
Loading
Loading