File size: 2,621 Bytes
e1cc3bc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import type {
CallToolResult,
ReadResourceResult,
} from "@modelcontextprotocol/sdk/types.js";
import fs from "node:fs/promises";
import path from "node:path";
import {
registerAppTool,
registerAppResource,
RESOURCE_MIME_TYPE,
RESOURCE_URI_META_KEY,
} from "@modelcontextprotocol/ext-apps/server";
import { startServer } from "./server-utils.js";
const DIST_DIR = path.join(import.meta.dirname, "dist");
const RESOURCE_URI = "ui://transcript/mcp-app.html";
/**
* Creates a new MCP server instance with tools and resources registered.
*/
export function createServer(): McpServer {
const server = new McpServer({
name: "Transcript Server",
version: "1.0.0",
});
// Register the transcribe tool - opens a UI for live speech transcription
registerAppTool(
server,
"transcribe",
{
title: "Transcribe Speech",
description:
"Opens a live speech transcription interface using the Web Speech API.",
inputSchema: {},
_meta: { [RESOURCE_URI_META_KEY]: RESOURCE_URI },
},
async (): Promise<CallToolResult> => {
return {
content: [
{
type: "text",
text: JSON.stringify({
status: "ready",
message: "Transcription UI opened. Speak into your microphone.",
}),
},
],
};
},
);
// Register the UI resource
registerAppResource(
server,
RESOURCE_URI,
RESOURCE_URI,
{ mimeType: RESOURCE_MIME_TYPE, description: "Transcript UI" },
async (): Promise<ReadResourceResult> => {
const html = await fs.readFile(
path.join(DIST_DIR, "mcp-app.html"),
"utf-8",
);
return {
contents: [
{
uri: RESOURCE_URI,
mimeType: RESOURCE_MIME_TYPE,
text: html,
_meta: {
ui: {
// Request microphone for Web Speech API, clipboard for copy button
permissions: { microphone: {}, clipboardWrite: {} },
},
},
},
],
};
},
);
return server;
}
async function main() {
if (process.argv.includes("--stdio")) {
await createServer().connect(new StdioServerTransport());
} else {
const port = parseInt(process.env.PORT ?? "3109", 10);
await startServer(createServer, { port, name: "Transcript Server" });
}
}
main().catch((e) => {
console.error(e);
process.exit(1);
});
|