chore: import upstream snapshot with attribution
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Waiting to run
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<!doctype html>
|
||||
<title>Report</title>
|
||||
<p>Quarterly numbers render here.</p>
|
||||
@@ -0,0 +1,39 @@
|
||||
from mcp import Client
|
||||
from mcp.client import advertise
|
||||
from mcp.server.apps import APP_MIME_TYPE, EXTENSION_ID, Apps, client_supports_apps
|
||||
from mcp.server.mcpserver import MCPServer
|
||||
from mcp.server.mcpserver.context import Context
|
||||
|
||||
CLOCK_HTML = """\
|
||||
<!doctype html>
|
||||
<title>Clock</title>
|
||||
<h1 id="now">...</h1>
|
||||
<script>
|
||||
window.addEventListener("message", (event) => {
|
||||
const text = event.data?.result?.content?.[0]?.text;
|
||||
if (text) document.getElementById("now").textContent = text;
|
||||
});
|
||||
</script>
|
||||
"""
|
||||
|
||||
apps = Apps()
|
||||
|
||||
|
||||
@apps.tool(resource_uri="ui://clock/app.html", description="The current time.")
|
||||
def get_time(ctx: Context) -> str:
|
||||
now = "2026-06-26T12:00:00Z"
|
||||
if not client_supports_apps(ctx):
|
||||
return f"The time is {now}."
|
||||
return now
|
||||
|
||||
|
||||
apps.add_html_resource("ui://clock/app.html", CLOCK_HTML, title="Clock")
|
||||
|
||||
mcp = MCPServer("clock", extensions=[apps])
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async with Client(mcp, extensions=[advertise(EXTENSION_ID, {"mimeTypes": [APP_MIME_TYPE]})]) as client:
|
||||
result = await client.call_tool("get_time", {})
|
||||
print(result.content)
|
||||
# [TextContent(text='2026-06-26T12:00:00Z')]
|
||||
@@ -0,0 +1,25 @@
|
||||
from mcp.server.apps import Apps, ResourceCsp, ResourcePermissions
|
||||
from mcp.server.mcpserver import MCPServer
|
||||
|
||||
DASHBOARD_HTML = "<!doctype html><title>Dashboard</title><canvas id='chart'></canvas>"
|
||||
|
||||
apps = Apps()
|
||||
|
||||
|
||||
@apps.tool(resource_uri="ui://dashboard/app.html", visibility=["app"])
|
||||
def refresh_dashboard() -> str:
|
||||
"""Refresh the dashboard data."""
|
||||
return "refreshed"
|
||||
|
||||
|
||||
apps.add_html_resource(
|
||||
"ui://dashboard/app.html",
|
||||
DASHBOARD_HTML,
|
||||
title="Dashboard",
|
||||
csp=ResourceCsp(connect_domains=["https://api.example.com"]),
|
||||
permissions=ResourcePermissions(clipboard_write={}),
|
||||
domain="dashboard.example.com",
|
||||
prefers_border=True,
|
||||
)
|
||||
|
||||
mcp = MCPServer("dashboard", extensions=[apps])
|
||||
@@ -0,0 +1,20 @@
|
||||
from pathlib import Path
|
||||
|
||||
from mcp.server.apps import Apps
|
||||
from mcp.server.mcpserver import MCPServer
|
||||
from mcp.server.mcpserver.resources import FileResource
|
||||
|
||||
REPORT_HTML = Path(__file__).parent / "report.html"
|
||||
|
||||
apps = Apps()
|
||||
|
||||
|
||||
@apps.tool(resource_uri="ui://report/app.html")
|
||||
def refresh_report() -> str:
|
||||
"""Refresh the report data."""
|
||||
return "report refreshed"
|
||||
|
||||
|
||||
apps.add_resource(FileResource(uri="ui://report/app.html", name="report", path=REPORT_HTML))
|
||||
|
||||
mcp = MCPServer("report", extensions=[apps])
|
||||
Reference in New Issue
Block a user