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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ jobs:
cgr.dev/chainguard/minio:latest server /data --address :9000
trap 'docker stop artifacts-fleet-test-s3' EXIT
NATIVE_WORKER_FLEET=1 bun test scripts/native-worker/fleet.test.ts --timeout 240000
- name: Test the nine-tool MCP connection and inline previews
run: bun run test:mcp-discovery

executable:
strategy:
Expand Down
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,18 @@ For the local host, use `http://127.0.0.1:4786/mcp`. Remote clients use the
configured deployment's sign-in flow. Optional `workspace` and `library` query
parameters select a workspace or the team library.

Ask your agent to read `artifact_guide` for React apps or `script_guide` for
TypeScript scripts before authoring. For example:
The connection advertises nine model tools: `artifact_guide`, `artifact_list`,
`artifact_read`, `artifact_write`, `artifact_edit`, `artifact_open`,
`artifacts_discover`, `artifacts_query`, and `artifacts_execute`. All 48 hosted
operations remain available through that same connection. Use `artifacts_discover`
to find an operation and retrieve its exact argument schema and relevant guide;
call it through `artifacts_query` for reads or `artifacts_execute` for actions.
Local file connections expose their supported artifact operations through the
same interface. No configuration switch is needed.

Ask your agent to read `artifact_guide` before authoring React apps. For scripts,
inspect `script_write` through `artifacts_discover`, which also returns the script
guide. For example:

> Build a team lunch poll with a React UI and a SQLite backend.

Expand Down
2 changes: 1 addition & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions cloudflare/managed-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import { galleryAction, gallerySource } from "./gallery-tools";
import { ARTIFACTS_SETTINGS_TOOLS, settingsTool } from "../src/mcp/settings-contract";
import { parseProjectArchive } from "../src/project-archive";
import { ownershipName } from "./ownership";
import { callDiscoveryTool, isDiscoveryTool } from "../src/mcp/discovery";
import { validateToolArguments } from "../src/mcp/validation";
import { CLOUD_MCP_TOOLS } from "./tool-contract";
import * as toolValidators from "../dist/cloudflare/tool-validators.js";

const text = (value: unknown): CallToolResult => ({ content: [{ type: "text", text: JSON.stringify(value, null, 2) }] });
type Selection = { workspace?: string; name?: string; version_id?: string; event_id?: string };
Expand Down Expand Up @@ -75,6 +79,14 @@ export class ManagedArtifactService {
}

async callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult> {
if (isDiscoveryTool(name)) {
return callDiscoveryTool(CLOUD_MCP_TOOLS, name, args, async (operation, input) => {
validateToolArguments(toolValidators, operation, input);
// Re-enter management admission, not the physical storage service: moved
// revisions and native apps still resolve the authenticated owner here.
return this.callTool(operation, input);
});
}
if (ARTIFACTS_SETTINGS_TOOLS.some(tool => tool.name === name)) return settingsTool(this, name, args);
if (name === "artifacts_tool") return galleryAction(this, args);
if (name === "artifacts_source") return gallerySource(this, args);
Expand Down
15 changes: 15 additions & 0 deletions cloudflare/mcp-discovery-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { definePlugins } from "../src/plugins/config";

/** Installed only by test:mcp-discovery, never by the default build. */
export default definePlugins([{
name: "mcp-discovery-test", description: "Authenticated MCP dispatch fixture",
operations: {
echo: {
description: "Echo a validated value for the authorized fixture user.", readOnly: true,
inputSchema: { type: "object", properties: { value: { type: "string" } }, required: ["value"], additionalProperties: false },
outputSchema: { type: "object", properties: { value: { type: "string" } }, required: ["value"], additionalProperties: false },
authorize: user => user.subject === "local",
handler: (input: { value: string }) => ({ value: input.value }),
},
},
}]);
Loading
Loading