源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)

This commit is contained in:
agent-radar
2026-09-02 01:05:41 +08:00
commit 04bac1f6e2
2200 changed files with 489415 additions and 0 deletions
+138
View File
@@ -0,0 +1,138 @@
# Native MCP Apps
OpenWork supports MCP Apps delivered by standard MCP servers connected through
OpenWork Connect. A server advertises the stable
`io.modelcontextprotocol/ui` extension, a tool binds an exact UI resource with
`_meta.ui.resourceUri`, the host reads that resource with `resources/read`, and
tool inputs and results move over the standard MCP Apps bridge.
This unit of value does **not** include installing a standalone App from an
HTML URL. URL-imported MCP Apps are deferred future work with a separate
product, security, lifecycle, and rollout contract.
Workflows remain executable `workflow` config objects. A Workflow's generated
views can be MCP resources, but that does not turn Workflow execution into
resource loading or a standalone URL-App installation path.
## Standard MCP server path
Connect continues to own server configuration, authentication, access grants,
per-member credentials, and tool policy. The OpenWork Cloud control server
publishes a member-scoped resource at:
```text
openwork://connect/mcp-servers/index.json
```
The signed-in Desktop session mints a separate short-lived App-host credential
with a non-public `mcp:app-host` scope. Desktop stores that credential and the
endpoint descriptors only in private App-host state; neither is projected into
OpenCode. It reads the index with that credential and advertises the
`mcp-app-host-v1` client capability. Den returns a non-empty provider index only
when the server-verified scope, client capability, and both rollout gates are
present. A normal model or legacy MCP token cannot unlock the index by spoofing
an audience or capability header. Desktop never writes `openwork-connect-*`
entries to the OpenCode runtime or any model-visible MCP registry. A connection
is proxied at:
```text
/mcp/agent/connections/{connectionId}
```
Current Desktop clients never register these provider descriptors in OpenCode;
the model discovers and invokes ordinary provider operations only through the
central `openwork-cloud` `search_capabilities` and `execute_capability` tools.
For stale published clients that still retain an old per-connection entry, the
proxy exposes only a compatibility pair named `search_capabilities` and
`execute_capability`. It never returns the provider catalog, MCP App launch
tools or metadata, resources, or templates, and it rejects every direct
provider call. This keeps ordinary operations bounded while old entries are
removed during reconciliation.
Desktop's local App host authenticates with the private scoped credential. Only
that transport receives tools with a valid `_meta.ui.resourceUri` whose
provider-declared visibility includes `app`, plus app-visible `search_capabilities` and
`execute_capability` scoped to the originating server. A native MCP App can
therefore render and use authorized tools from its regular MCP server without
placing the provider catalog in the model request.
The app-host view preserves:
- the App tool's exact name, input/output schemas, annotations, and UI binding;
- concrete descriptors and `resources/read` content only for resources bound
by exposed App tools;
- `content`, `structuredContent`, `_meta`, and `isError` from `tools/call`;
- the stable MCP Apps extension and `text/html;profile=mcp-app` resources;
- one server identity per Connect connection, preserving the same-server
tool-call boundary.
OpenWork access grants, disabled-tool policy, and approval rules still apply at
the proxy boundary. The App-host credential authorizes only this bounded proxy
surface; it is not a provider credential and grants no direct cross-server
access.
## Rollout
Native MCP Apps are enabled for every deployment and organization. The former
deployment gate (`DEN_REMOTE_MCP_APPS_ENABLED`) and the per-organization
**Native MCP Apps (preview)** capability were removed once the feature
stabilized; stale stored organization overrides are ignored. App launch
metadata (`kind: mcp_app`, `mcpApp.resourceUri`, `openwork/mcpApp` meta) is an
opaque binding published on every bounded search/execute result; clients that
do not host Apps ignore it and keep the normal tool result. The private
App-host index and per-connection provider proxy remain gated on the
client-advertised App-host capability header, so older Desktop clients keep
their bounded search/execute surface. Reconciliation also removes and
disconnects stale
`openwork-connect-*` OpenCode entries while preserving user-authored MCPs and
all durable Connect records.
The provider proxy advertises `listChanged: false` because the current
enterprise connector opens bounded request sessions rather than a durable
downstream notification stream. Catalog refresh happens on Connect
reconciliation, Desktop startup, engine refresh, or an explicit Cloud MCP
refresh. Forwarding downstream list-change notifications remains follow-up
interoperability work.
## Deferred: standalone URL-imported Apps
Installing a self-contained HTML App from a URL is intentionally outside this
change. In the current product:
- Den Web has no Add MCP App button, URL form, installed-App detail page, or
URL-App lifecycle entry point;
- the central MCP server does not register `import_remote_mcp_app` or any
standalone-App launch tool;
- capability search returns no standalone URL-App matches;
- model and App-host catalogs contain no standalone URL-App tools;
- no `ui://openwork/library-apps/...` resources are registered;
- member server indexes and launch metadata contain no standalone URL Apps;
- REST calls under `/v1/remote-mcp-apps` are not registered and are therefore
unavailable.
Existing database rows and cached revisions from earlier development remain
stored non-destructively. They are inactive and unreachable through the UI,
MCP catalogs, capability search, resources, launch metadata, and HTTP API. This
change performs no deletion and introduces no destructive migration.
The retained storage and validation implementation is not a supported runtime
surface. A future standalone URL-App unit of value must deliberately restore
its own API, UI, security review, lifecycle, testing, and rollout contract.
## Host security and compatibility
Desktop negotiates the stable extension, resolves the current tool definition,
reads the exact `ui://` resource even when it is absent from `resources/list`,
accepts text or base64 HTML, enforces MIME and size limits, validates CSP
origins, and loads the document through the isolated sandbox proxy. It sends
tool input and the preserved tool result after initialization, bounds size
changes, tears the bridge down on unmount, and contains resolution, handshake,
document, and runtime failures without hiding the normal tool result.
App-requested tools are resolved only on the originating regular MCP server
and must be visible to the app. When a tool carries `_meta.ui.resourceUri`,
Desktop also requires it to match the exact resource loaded in the calling
iframe. Workspace denies apply. Read-only capability search runs directly;
capability execution uses conservative mutation annotations and requires user
confirmation while provider authorization and audit still run server-side.
Cross-server iframe calls are not allowed.
@@ -0,0 +1,110 @@
# Native MCP Apps local demo
This runbook proves the native MCP Apps path with a deterministic local fixture.
It does not depend on a hosted gallery, production rollout flags, customer
connectors, or personal credentials.
The required fixture is Project Atlas from
`evals/specs/remote-mcp-apps.e2e.test.ts`. It runs as a local Streamable HTTP MCP
server, exposes `ui://project-atlas/view.html`, and has a same-server
`search_projects` operation. The tape starts real local Den API and Web
processes, a real Electron Desktop/local-server process, MySQL, Redis, and a
synthetic model server.
## Prerequisites
- Node.js 24 and pnpm 11.4.0 (the versions declared by the repository)
- Bun, Docker, and an available local MySQL port (`3306`)
- no real model/provider credentials in the shell
From a clean checkout of the exact branch under test:
```bash
pnpm install --frozen-lockfile
pnpm --dir evals install --frozen-lockfile
pnpm --filter @openwork/types build
pnpm --filter @openwork-ee/den-db build
pnpm --filter @openwork/email build
pnpm dev:den:mysql
```
## Run the exact-head demo tape
```bash
OPENWORK_EVAL_E2E_TESTS=1 pnpm evals:e2e remote-mcp-apps
```
A valid required proof ends with one passing test, zero failed tests, zero
skips, and `"verdict":"passed"`. Keep the JSON report path printed by the
runner with the local verification record.
The tape performs this demo sequence:
1. Starts an isolated Den organization, synthetic member, local Project Atlas
MCP server, and Desktop profile.
2. Adds Project Atlas as an organization Connect MCP server and waits for it to
become ready.
3. Confirms the model-visible surface contains only the central
`search_capabilities` and `execute_capability` tools.
4. Confirms stale per-connection compatibility exposes only that same bounded
pair, no resources/templates/App metadata, and no direct provider tools.
5. Confirms the private App host receives only the originating server's
app-visible tools and exact `ui://project-atlas/view.html` resource.
6. Searches and executes `search_projects` through the originating server's
App-host capability pair and observes the synthetic Atlas migration result.
7. Prompts the synthetic model to return the bound tool result, renders the App
in Desktop, reloads it, and confirms it renders again.
8. Restarts Desktop with the same isolated profile, revisits the session, and
confirms the App recovers.
Native MCP Apps are enabled for every deployment and organization; no
deployment or organization gate needs to be flipped for this demo.
## Focused security and compatibility checks
```bash
cd apps/server
bun --conditions=development test \
src/connect-mcp-server-catalog.test.ts \
src/mcp-app-host.test.ts \
src/mcp-app-sandbox.test.ts \
src/cloud-mcp-reconcile.e2e.test.ts
cd ../app
bun test \
tests/den-mcp-url.test.ts \
tests/mcp-app-frame.test.ts \
tests/session-mcp-maintenance.test.ts \
tests/cloud-mcp-maintenance-gate.test.ts
cd ../../ee/apps/den-api
bun test \
test/remote-mcp-app-rollout.test.ts \
test/external-connection-proxy.test.ts \
test/admin-organization-capabilities.test.ts \
test/organization-capabilities.test.ts
```
These checks cover exact trusted-origin matching, cross-origin rejection,
origin-bound App-host credentials, App-host credential privacy, sandbox/CSP
enforcement, same-server binding, rollout defaults, older responses without an
App-host credential, bounded stale-client compatibility, and preservation of
ordinary Connect when Apps are disabled.
## Expected failure categories
- A skipped tape is incomplete proof. Check the consent environment variable,
local placement, and MySQL availability.
- `missing local server credentials` is a Desktop startup/readiness problem.
- A resource error names the exact URI, MIME, size, or CSP validation failure.
- An origin error indicates that the Den/App-host endpoint pair is not an exact
trusted-origin match.
- A tool denial indicates wrong-server routing, app visibility, workspace
policy, provider authorization, or required mutation confirmation.
- A client that does not advertise the private App-host capability keeps the
bounded search/execute surface; that is expected, not a resource-loading
failure.
The hosted SOL gallery may be checked separately as an external observation,
but its reachability is not OpenWork compatibility proof and it is not part of
this required demo.