Compare commits

..

19 Commits

Author SHA1 Message Date
Ashwin Bhat
6b05ffa7b1 add a way to clear error 2024-10-18 16:44:10 -07:00
Ashwin Bhat
dcdcfd284f add missing import 2024-10-18 14:37:16 -07:00
ashwin-ant
567c15a1cf Merge pull request #20 from modelcontextprotocol/ashwin/ping
Add ping tab
2024-10-18 10:14:10 -07:00
ashwin-ant
dca7c7766b Merge pull request #21 from modelcontextprotocol/ashwin/update
Update sdk
2024-10-18 10:14:04 -07:00
Ashwin Bhat
7680d5272a updates for sdk 2024-10-18 10:00:13 -07:00
Ashwin Bhat
827ee4a283 Merge commit '0e60829bcc832248f803aba85afb8b02e6eedd54' into ashwin/update 2024-10-18 09:58:38 -07:00
Ashwin Bhat
0e60829bcc Squashed 'packages/mcp-typescript/' changes from 7d70db8..cc2a168
cc2a168 Merge pull request #22 from modelcontextprotocol/justin/revert-urls
209f8eb Revert string -> URL transformations

git-subtree-dir: packages/mcp-typescript
git-subtree-split: cc2a1682bb18f0d48d0ad42fe375b22d9b23a3f4
2024-10-18 09:58:38 -07:00
ashwin-ant
9f5366c49c Update PingTab.tsx 2024-10-18 09:46:17 -07:00
Ashwin Bhat
7bb40c188f add ping tab 2024-10-18 08:41:27 -07:00
ashwin-ant
9ff362dd85 Merge pull request #19 from modelcontextprotocol/ashwin/pagination
add pagination handling for lists
2024-10-18 08:29:49 -07:00
Ashwin Bhat
24d005ac84 add pagination handling for lists 2024-10-17 17:11:30 -07:00
ashwin-ant
5f9d11b3a9 Merge pull request #18 from modelcontextprotocol/ashwin/progress
Visualize progress notifications
2024-10-17 12:05:07 -07:00
Ashwin Bhat
cc1bf029fa Squashed 'packages/mcp-typescript/' changes from e665be0..7d70db8
7d70db8 Merge pull request #20 from modelcontextprotocol/ashwin/progress
65a8613 fix schema definitions for RequestSchema

git-subtree-dir: packages/mcp-typescript
git-subtree-split: 7d70db805740c53f21153d72be6f34d70818a9da
2024-10-17 08:10:26 -07:00
Ashwin Bhat
247dae54b3 Merge commit 'cc1bf029facd2e0ecfafdef5ea8ad304fc1ab8a6' into ashwin/progress 2024-10-17 08:10:26 -07:00
Ashwin Bhat
48355e9cb2 receive and display server notifications 2024-10-17 08:08:09 -07:00
ashwin-ant
3b4d8136b2 Merge pull request #17 from modelcontextprotocol/ashwin/updatesdk
Update SDK
2024-10-17 08:02:40 -07:00
Ashwin Bhat
23ca80ed66 Squashed 'packages/mcp-typescript/' changes from dcc30be..e665be0
e665be0 Merge pull request #14 from modelcontextprotocol/justin/fix-race-condition
be9c1fe Merge branch 'main' into justin/fix-race-condition
36ba802 Merge pull request #17 from modelcontextprotocol/ashwin/capabilities
a1b8886 yarn build
7b718de Report errors when start() is called multiple times
83a43fd Protocol.connect() can automatically call Transport.start()
8d80cc5 Merge branch 'main' into justin/fix-race-condition
bcb4b21 add server capabilities derivation
e9c64fb Update tests and CLI
2b0599e Update server SSE transport
c39f808 Update client transports
87ae7ff Add start() to Transport interface

git-subtree-dir: packages/mcp-typescript
git-subtree-split: e665be068b9d2baa65f37fd7c2f69f68f77e57b9
2024-10-16 16:22:14 -07:00
Ashwin Bhat
0ffedbf8fa fix type errors 2024-10-16 16:22:14 -07:00
Ashwin Bhat
c6a11422f4 updates for sdk update 2024-10-16 16:22:14 -07:00
62 changed files with 3244 additions and 662 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ node_modules
server/build
client/dist
client/tsconfig.app.tsbuildinfo
client/tsconfig.node.tsbuildinfo

View File

@@ -22,7 +22,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tailwind-merge": "^2.5.3",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
},
"devDependencies": {
"@eslint/js": "^9.11.1",

View File

@@ -1,8 +1,5 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {

View File

@@ -10,16 +10,20 @@ import {
Resource,
Tool,
ClientRequest,
ProgressNotificationSchema,
ServerNotification,
EmptyResultSchema,
} from "mcp-typescript/types.js";
import { useState } from "react";
import { useState, useRef } from "react";
import {
Send,
Bell,
Terminal,
Files,
Bell,
MessageSquare,
Hammer,
Play,
X,
} from "lucide-react";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Input } from "@/components/ui/input";
@@ -36,11 +40,12 @@ import ConsoleTab from "./components/ConsoleTab";
import Sidebar from "./components/Sidebar";
import RequestsTab from "./components/RequestsTabs";
import ResourcesTab from "./components/ResourcesTab";
import NotificationsTab from "./components/NotificationsTab";
import PromptsTab, { Prompt } from "./components/PromptsTab";
import ToolsTab from "./components/ToolsTab";
import History from "./components/History";
import { AnyZodObject } from "node_modules/zod/lib";
import { AnyZodObject } from "zod";
import HistoryAndNotifications from "./components/History";
import "./App.css";
import PingTab from "./components/PingTab";
const App = () => {
const [connectionStatus, setConnectionStatus] = useState<
@@ -57,7 +62,7 @@ const App = () => {
"/Users/ashwin/.nvm/versions/node/v18.20.4/bin/node",
);
const [args, setArgs] = useState<string>(
"/Users/ashwin/code/example-servers/build/everything/stdio.js",
"/Users/ashwin/code/mcp/example-servers/build/everything/stdio.js",
);
const [url, setUrl] = useState<string>("http://localhost:3001/sse");
const [transportType, setTransportType] = useState<"stdio" | "sse">("stdio");
@@ -65,12 +70,21 @@ const App = () => {
{ request: string; response: string }[]
>([]);
const [mcpClient, setMcpClient] = useState<Client | null>(null);
const [notifications, setNotifications] = useState<ServerNotification[]>([]);
const [selectedResource, setSelectedResource] = useState<Resource | null>(
null,
);
const [selectedPrompt, setSelectedPrompt] = useState<Prompt | null>(null);
const [selectedTool, setSelectedTool] = useState<Tool | null>(null);
const [nextResourceCursor, setNextResourceCursor] = useState<
string | undefined
>();
const [nextPromptCursor, setNextPromptCursor] = useState<
string | undefined
>();
const [nextToolCursor, setNextToolCursor] = useState<string | undefined>();
const progressTokenRef = useRef(0);
const pushHistory = (request: object, response: object) => {
setRequestHistory((prev) => [
@@ -101,15 +115,15 @@ const App = () => {
const response = await makeRequest(
{
method: "resources/list" as const,
params: nextResourceCursor ? { cursor: nextResourceCursor } : {},
},
ListResourcesResultSchema,
);
if (response.resources) {
setResources(response.resources);
}
setResources(resources.concat(response.resources ?? []));
setNextResourceCursor(response.nextCursor);
};
const readResource = async (uri: URL) => {
const readResource = async (uri: string) => {
const response = await makeRequest(
{
method: "resources/read" as const,
@@ -124,10 +138,12 @@ const App = () => {
const response = await makeRequest(
{
method: "prompts/list" as const,
params: nextPromptCursor ? { cursor: nextPromptCursor } : {},
},
ListPromptsResultSchema,
);
setPrompts(response.prompts);
setNextPromptCursor(response.nextCursor);
};
const getPrompt = async (name: string, args: Record<string, string> = {}) => {
@@ -145,17 +161,25 @@ const App = () => {
const response = await makeRequest(
{
method: "tools/list" as const,
params: nextToolCursor ? { cursor: nextToolCursor } : {},
},
ListToolsResultSchema,
);
setTools(response.tools);
setNextToolCursor(response.nextCursor);
};
const callTool = async (name: string, params: Record<string, unknown>) => {
const response = await makeRequest(
{
method: "tools/call" as const,
params: { name, arguments: params },
params: {
name,
arguments: params,
_meta: {
progressToken: progressTokenRef.current++,
},
},
},
CallToolResultSchema,
);
@@ -169,7 +193,6 @@ const App = () => {
version: "0.0.1",
});
const clientTransport = new SSEClientTransport();
const backendUrl = new URL("http://localhost:3000/sse");
backendUrl.searchParams.append("transportType", transportType);
@@ -180,9 +203,19 @@ const App = () => {
backendUrl.searchParams.append("url", url);
}
await clientTransport.connect(backendUrl);
const clientTransport = new SSEClientTransport(backendUrl);
await client.connect(clientTransport);
client.setNotificationHandler(
ProgressNotificationSchema,
(notification) => {
setNotifications((prevNotifications) => [
...prevNotifications,
notification,
]);
},
);
setMcpClient(client);
setConnectionStatus("connected");
} catch (e) {
@@ -191,6 +224,10 @@ const App = () => {
}
};
const clearError = () => {
setError(null);
};
return (
<div className="flex h-screen bg-gray-100">
<Sidebar connectionStatus={connectionStatus} />
@@ -240,6 +277,15 @@ const App = () => {
Connect
</Button>
</div>
{error && (
<div className="mt-2 flex items-center">
<p className="text-red-500 mr-2">{error}</p>
<Button onClick={clearError} variant="outline" size="sm">
<X className="w-4 h-4" />
Clear Error
</Button>
</div>
)}
</div>
{mcpClient ? (
<Tabs defaultValue="resources" className="w-full p-4">
@@ -256,10 +302,6 @@ const App = () => {
<Send className="w-4 h-4 mr-2" />
Requests
</TabsTrigger>
<TabsTrigger value="notifications" disabled>
<Bell className="w-4 h-4 mr-2" />
Notifications
</TabsTrigger>
<TabsTrigger value="tools">
<Hammer className="w-4 h-4 mr-2" />
Tools
@@ -268,6 +310,10 @@ const App = () => {
<Terminal className="w-4 h-4 mr-2" />
Console
</TabsTrigger>
<TabsTrigger value="ping">
<Bell className="w-4 h-4 mr-2" />
Ping
</TabsTrigger>
</TabsList>
<div className="w-full">
@@ -278,9 +324,9 @@ const App = () => {
selectedResource={selectedResource}
setSelectedResource={setSelectedResource}
resourceContent={resourceContent}
nextCursor={nextResourceCursor}
error={error}
/>
<NotificationsTab />
<PromptsTab
prompts={prompts}
listPrompts={listPrompts}
@@ -288,6 +334,7 @@ const App = () => {
selectedPrompt={selectedPrompt}
setSelectedPrompt={setSelectedPrompt}
promptContent={promptContent}
nextCursor={nextPromptCursor}
error={error}
/>
<RequestsTab />
@@ -301,9 +348,20 @@ const App = () => {
setToolResult("");
}}
toolResult={toolResult}
nextCursor={nextToolCursor}
error={error}
/>
<ConsoleTab />
<PingTab
onPingClick={() => {
void makeRequest(
{
method: "ping" as const,
},
EmptyResultSchema,
);
}}
/>
</div>
</Tabs>
) : (
@@ -316,7 +374,10 @@ const App = () => {
</div>
</div>
</div>
<History requestHistory={requestHistory} />
<HistoryAndNotifications
requestHistory={requestHistory}
serverNotifications={notifications}
/>
</div>
);
};

View File

@@ -1,94 +1,163 @@
import { useState } from "react";
import { Copy } from "lucide-react";
import { ServerNotification } from "mcp-typescript/types.js";
const History = ({
const HistoryAndNotifications = ({
requestHistory,
serverNotifications,
}: {
requestHistory: Array<{ request: string; response: string | null }>;
serverNotifications: ServerNotification[];
}) => {
const [expandedRequests, setExpandedRequests] = useState<{
[key: number]: boolean;
}>({});
const [expandedNotifications, setExpandedNotifications] = useState<{
[key: number]: boolean;
}>({});
const toggleRequestExpansion = (index: number) => {
setExpandedRequests((prev) => ({ ...prev, [index]: !prev[index] }));
};
const toggleNotificationExpansion = (index: number) => {
setExpandedNotifications((prev) => ({ ...prev, [index]: !prev[index] }));
};
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
};
return (
<div className="w-64 bg-white shadow-md p-4 overflow-y-auto">
<h2 className="text-lg font-semibold mb-4">History</h2>
<ul className="space-y-3">
{requestHistory
.slice()
.reverse()
.map((request, index) => (
<li
key={index}
className="text-sm text-gray-600 bg-gray-100 p-2 rounded"
>
<div
className="flex justify-between items-center cursor-pointer"
onClick={() =>
toggleRequestExpansion(requestHistory.length - 1 - index)
}
>
<span className="font-mono">
{requestHistory.length - index}.{" "}
{JSON.parse(request.request).method}
</span>
<span>
{expandedRequests[requestHistory.length - 1 - index]
? "▼"
: "▶"}
</span>
</div>
{expandedRequests[requestHistory.length - 1 - index] && (
<>
<div className="mt-2">
<div className="flex justify-between items-center mb-1">
<span className="font-semibold text-blue-600">
Request:
</span>
<button
onClick={() => copyToClipboard(request.request)}
className="text-blue-500 hover:text-blue-700"
>
<Copy size={16} />
</button>
</div>
<pre className="whitespace-pre-wrap break-words bg-blue-50 p-2 rounded">
{JSON.stringify(JSON.parse(request.request), null, 2)}
</pre>
<div className="w-64 bg-white shadow-md p-4 overflow-hidden flex flex-col h-full">
<div className="flex-1 overflow-y-auto mb-4 border-b pb-4">
<h2 className="text-lg font-semibold mb-4">History</h2>
{requestHistory.length === 0 ? (
<p className="text-sm text-gray-500 italic">No history yet</p>
) : (
<ul className="space-y-3">
{requestHistory
.slice()
.reverse()
.map((request, index) => (
<li
key={index}
className="text-sm text-gray-600 bg-gray-100 p-2 rounded"
>
<div
className="flex justify-between items-center cursor-pointer"
onClick={() =>
toggleRequestExpansion(requestHistory.length - 1 - index)
}
>
<span className="font-mono">
{requestHistory.length - index}.{" "}
{JSON.parse(request.request).method}
</span>
<span>
{expandedRequests[requestHistory.length - 1 - index]
? "▼"
: "▶"}
</span>
</div>
{request.response && (
{expandedRequests[requestHistory.length - 1 - index] && (
<>
<div className="mt-2">
<div className="flex justify-between items-center mb-1">
<span className="font-semibold text-blue-600">
Request:
</span>
<button
onClick={() => copyToClipboard(request.request)}
className="text-blue-500 hover:text-blue-700"
>
<Copy size={16} />
</button>
</div>
<pre className="whitespace-pre-wrap break-words bg-blue-50 p-2 rounded">
{JSON.stringify(JSON.parse(request.request), null, 2)}
</pre>
</div>
{request.response && (
<div className="mt-2">
<div className="flex justify-between items-center mb-1">
<span className="font-semibold text-green-600">
Response:
</span>
<button
onClick={() => copyToClipboard(request.response!)}
className="text-blue-500 hover:text-blue-700"
>
<Copy size={16} />
</button>
</div>
<pre className="whitespace-pre-wrap break-words bg-green-50 p-2 rounded">
{JSON.stringify(
JSON.parse(request.response),
null,
2,
)}
</pre>
</div>
)}
</>
)}
</li>
))}
</ul>
)}
</div>
<div className="flex-1 overflow-y-auto">
<h2 className="text-lg font-semibold mb-4">Server Notifications</h2>
{serverNotifications.length === 0 ? (
<p className="text-sm text-gray-500 italic">No notifications yet</p>
) : (
<ul className="space-y-3">
{serverNotifications
.slice()
.reverse()
.map((notification, index) => (
<li
key={index}
className="text-sm text-gray-600 bg-gray-100 p-2 rounded"
>
<div
className="flex justify-between items-center cursor-pointer"
onClick={() => toggleNotificationExpansion(index)}
>
<span className="font-mono">
{serverNotifications.length - index}.{" "}
{notification.method}
</span>
<span>{expandedNotifications[index] ? "▼" : "▶"}</span>
</div>
{expandedNotifications[index] && (
<div className="mt-2">
<div className="flex justify-between items-center mb-1">
<span className="font-semibold text-green-600">
Response:
<span className="font-semibold text-purple-600">
Details:
</span>
<button
onClick={() => copyToClipboard(request.response!)}
onClick={() =>
copyToClipboard(JSON.stringify(notification))
}
className="text-blue-500 hover:text-blue-700"
>
<Copy size={16} />
</button>
</div>
<pre className="whitespace-pre-wrap break-words bg-green-50 p-2 rounded">
{JSON.stringify(JSON.parse(request.response), null, 2)}
<pre className="whitespace-pre-wrap break-words bg-purple-50 p-2 rounded">
{JSON.stringify(notification, null, 2)}
</pre>
</div>
)}
</>
)}
</li>
))}
</ul>
</li>
))}
</ul>
)}
</div>
</div>
);
};
export default History;
export default HistoryAndNotifications;

View File

@@ -7,6 +7,7 @@ type ListPaneProps<T> = {
renderItem: (item: T) => React.ReactNode;
title: string;
buttonText: string;
isButtonDisabled?: boolean;
};
const ListPane = <T extends object>({
@@ -16,16 +17,22 @@ const ListPane = <T extends object>({
renderItem,
title,
buttonText,
isButtonDisabled,
}: ListPaneProps<T>) => (
<div className="bg-white rounded-lg shadow">
<div className="p-4 border-b border-gray-200">
<h3 className="font-semibold">{title}</h3>
</div>
<div className="p-4">
<Button variant="outline" className="w-full mb-4" onClick={listItems}>
<Button
variant="outline"
className="w-full mb-4"
onClick={listItems}
disabled={isButtonDisabled}
>
{buttonText}
</Button>
<div className="space-y-2">
<div className="space-y-2 overflow-y-auto max-h-96">
{items.map((item, index) => (
<div
key={index}

View File

@@ -1,33 +0,0 @@
import { Bell } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { TabsContent } from "@/components/ui/tabs";
const NotificationsTab = () => (
<TabsContent value="notifications" className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-4">
<div className="flex space-x-2">
<Input placeholder="Notification method" />
<Button>
<Bell className="w-4 h-4 mr-2" />
Send
</Button>
</div>
<Textarea
placeholder="Notification parameters (JSON)"
className="h-64 font-mono"
/>
</div>
<div className="bg-white rounded-lg shadow p-4">
<h3 className="font-semibold mb-4">Recent Notifications</h3>
<div className="space-y-2">
{/* Notification history would go here */}
</div>
</div>
</div>
</TabsContent>
);
export default NotificationsTab;

View File

@@ -0,0 +1,21 @@
import { TabsContent } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
const PingTab = ({ onPingClick }: { onPingClick: () => void }) => {
return (
<TabsContent value="ping" className="grid grid-cols-2 gap-4">
<div className="col-span-2 flex justify-center items-center">
<Button
onClick={onPingClick}
className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white font-bold py-6 px-12 rounded-full shadow-lg transform transition duration-300 hover:scale-110 focus:outline-none focus:ring-4 focus:ring-purple-300 animate-pulse"
>
<span className="text-3xl mr-2">🚀</span>
MEGA PING
<span className="text-3xl ml-2">💥</span>
</Button>
</div>
</TabsContent>
);
};
export default PingTab;

View File

@@ -7,6 +7,7 @@ import { Textarea } from "@/components/ui/textarea";
import { useState } from "react";
import { Label } from "@/components/ui/label";
import ListPane from "./ListPane";
import { ListPromptsResult } from "mcp-typescript/types.js";
export type Prompt = {
name: string;
@@ -25,6 +26,7 @@ const PromptsTab = ({
selectedPrompt,
setSelectedPrompt,
promptContent,
nextCursor,
error,
}: {
prompts: Prompt[];
@@ -33,6 +35,7 @@ const PromptsTab = ({
selectedPrompt: Prompt | null;
setSelectedPrompt: (prompt: Prompt) => void;
promptContent: string;
nextCursor: ListPromptsResult["nextCursor"];
error: string | null;
}) => {
const [promptArgs, setPromptArgs] = useState<Record<string, string>>({});
@@ -63,7 +66,8 @@ const PromptsTab = ({
</>
)}
title="Prompts"
buttonText="List Prompts"
buttonText={nextCursor ? "List More Prompts" : "List Prompts"}
isButtonDisabled={!nextCursor && prompts.length > 0}
/>
<div className="bg-white rounded-lg shadow">

View File

@@ -2,7 +2,7 @@ import { FileText, ChevronRight, AlertCircle, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { TabsContent } from "@/components/ui/tabs";
import { Resource } from "mcp-typescript/types.js";
import { ListResourcesResult, Resource } from "mcp-typescript/types.js";
import ListPane from "./ListPane";
const ResourcesTab = ({
@@ -12,14 +12,16 @@ const ResourcesTab = ({
selectedResource,
setSelectedResource,
resourceContent,
nextCursor,
error,
}: {
resources: Resource[];
listResources: () => void;
readResource: (uri: URL) => void;
readResource: (uri: string) => void;
selectedResource: Resource | null;
setSelectedResource: (resource: Resource) => void;
resourceContent: string;
nextCursor: ListResourcesResult["nextCursor"];
error: string | null;
}) => (
<TabsContent value="resources" className="grid grid-cols-2 gap-4">
@@ -40,7 +42,8 @@ const ResourcesTab = ({
</div>
)}
title="Resources"
buttonText="List Resources"
buttonText={nextCursor ? "List More Resources" : "List Resources"}
isButtonDisabled={!nextCursor && resources.length > 0}
/>
<div className="bg-white rounded-lg shadow">

View File

@@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Send, AlertCircle } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Tool } from "mcp-typescript/types.js";
import { ListToolsResult, Tool } from "mcp-typescript/types.js";
import { useState } from "react";
import { Label } from "@/components/ui/label";
import ListPane from "./ListPane";
@@ -15,6 +15,7 @@ const ToolsTab = ({
selectedTool,
setSelectedTool,
toolResult,
nextCursor,
error,
}: {
tools: Tool[];
@@ -23,6 +24,7 @@ const ToolsTab = ({
selectedTool: Tool | null;
setSelectedTool: (tool: Tool) => void;
toolResult: string;
nextCursor: ListToolsResult["nextCursor"];
error: string | null;
}) => {
const [params, setParams] = useState<Record<string, unknown>>({});
@@ -36,11 +38,14 @@ const ToolsTab = ({
renderItem={(tool) => (
<>
<span className="flex-1">{tool.name}</span>
<span className="text-sm text-gray-500">{tool.description}</span>
<span className="text-sm text-gray-500 text-right">
{tool.description}
</span>
</>
)}
title="Tools"
buttonText="List Tools"
buttonText={nextCursor ? "List More Tools" : "List Tools"}
isButtonDisabled={!nextCursor && tools.length > 0}
/>
<div className="bg-white rounded-lg shadow">
@@ -61,7 +66,7 @@ const ToolsTab = ({
<p className="text-sm text-gray-600">
{selectedTool.description}
</p>
{Object.entries(selectedTool.inputSchema.properties).map(
{Object.entries(selectedTool.inputSchema.properties ?? []).map(
([key, value]) => (
<div key={key}>
<Label
@@ -71,14 +76,17 @@ const ToolsTab = ({
{key}
</Label>
<Input
// @ts-expect-error value type is currently unknown
type={value.type === "number" ? "number" : "text"}
id={key}
name={key}
// @ts-expect-error value type is currently unknown
placeholder={value.description}
onChange={(e) =>
setParams({
...params,
[key]:
// @ts-expect-error value type is currently unknown
value.type === "number"
? Number(e.target.value)
: e.target.value,

View File

@@ -1 +0,0 @@
{"root":["./vite.config.ts"],"version":"5.6.2"}

13
packages/mcp-typescript/dist/cli.js generated vendored
View File

@@ -26,16 +26,13 @@ async function runClient(url_or_command, args) {
// Ignore
}
if ((url === null || url === void 0 ? void 0 : url.protocol) === "http:" || (url === null || url === void 0 ? void 0 : url.protocol) === "https:") {
clientTransport = new SSEClientTransport();
await clientTransport.connect(new URL(url_or_command));
clientTransport = new SSEClientTransport(new URL(url_or_command));
}
else if ((url === null || url === void 0 ? void 0 : url.protocol) === "ws:" || (url === null || url === void 0 ? void 0 : url.protocol) === "wss:") {
clientTransport = new WebSocketClientTransport();
await clientTransport.connect(new URL(url_or_command));
clientTransport = new WebSocketClientTransport(new URL(url_or_command));
}
else {
clientTransport = new StdioClientTransport();
await clientTransport.spawn({
clientTransport = new StdioClientTransport({
command: url_or_command,
args,
});
@@ -52,7 +49,7 @@ async function runServer(port) {
let servers = [];
app.get("/sse", async (req, res) => {
console.log("Got new SSE connection");
const transport = new SSEServerTransport("/message");
const transport = new SSEServerTransport("/message", res);
const server = new Server({
name: "mcp-typescript test server",
version: "0.1.0",
@@ -62,7 +59,6 @@ async function runServer(port) {
console.log("SSE connection closed");
servers = servers.filter((s) => s !== server);
};
await transport.connectSSE(req, res);
await server.connect(transport);
});
app.post("/message", async (req, res) => {
@@ -87,7 +83,6 @@ async function runServer(port) {
version: "0.1.0",
});
const transport = new StdioServerTransport();
await transport.start();
await server.connect(transport);
console.log("Server running on stdio");
}

View File

@@ -1 +1 @@
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}

View File

@@ -10,10 +10,12 @@ export declare class SSEClientTransport implements Transport {
private _eventSource?;
private _endpoint?;
private _abortController?;
private _url;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
connect(url: URL): Promise<void>;
constructor(url: URL);
start(): Promise<void>;
close(): Promise<void>;
send(message: JSONRPCMessage): Promise<void>;
}

View File

@@ -1 +1 @@
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/client/sse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAEnE;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,SAAS;IAClD,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,SAAS,CAAC,CAAM;IACxB,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAE3C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAE9C,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA0BnD"}
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/client/sse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAEnE;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,SAAS;IAClD,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,SAAS,CAAC,CAAM;IACxB,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAC3C,OAAO,CAAC,IAAI,CAAM;IAElB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;gBAElC,GAAG,EAAE,GAAG;IAIpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyDhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA0BnD"}

View File

@@ -6,9 +6,15 @@ import { JSONRPCMessageSchema } from "../types.js";
* This uses the EventSource API in browsers. You can install the `eventsource` package for Node.js.
*/
export class SSEClientTransport {
connect(url) {
constructor(url) {
this._url = url;
}
start() {
if (this._eventSource) {
throw new Error("SSEClientTransport already started! If using Client class, note that connect() calls start() automatically.");
}
return new Promise((resolve, reject) => {
this._eventSource = new EventSource(url.href);
this._eventSource = new EventSource(this._url.href);
this._abortController = new AbortController();
this._eventSource.onerror = (event) => {
var _a;
@@ -23,8 +29,8 @@ export class SSEClientTransport {
var _a;
const messageEvent = event;
try {
this._endpoint = new URL(messageEvent.data, url);
if (this._endpoint.origin !== url.origin) {
this._endpoint = new URL(messageEvent.data, this._url);
if (this._endpoint.origin !== this._url.origin) {
throw new Error(`Endpoint origin does not match connection origin: ${this._endpoint.origin}`);
}
}

View File

@@ -1 +1 @@
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/client/sse.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/client/sse.ts"],"names":[],"mappings":"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"}

View File

@@ -25,13 +25,15 @@ export declare class StdioClientTransport implements Transport {
private _process?;
private _abortController;
private _readBuffer;
private _serverParams;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
constructor(server: StdioServerParameters);
/**
* Spawns the server process and prepare to communicate with it.
* Starts the server process and prepares to communicate with it.
*/
spawn(server: StdioServerParameters): Promise<void>;
start(): Promise<void>;
private processReadBuffer;
close(): Promise<void>;
send(message: JSONRPCMessage): Promise<void>;

View File

@@ -1 +1 @@
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/client/stdio.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IACpD,OAAO,CAAC,QAAQ,CAAC,CAAe;IAChC,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,WAAW,CAAgC;IAEnD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAE9C;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CnD,OAAO,CAAC,iBAAiB;IAenB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAc7C"}
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/client/stdio.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IACpD,OAAO,CAAC,QAAQ,CAAC,CAAe;IAChC,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,aAAa,CAAwB;IAE7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;gBAElC,MAAM,EAAE,qBAAqB;IAIzC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyD5B,OAAO,CAAC,iBAAiB;IAenB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAc7C"}

View File

@@ -6,19 +6,25 @@ import { ReadBuffer, serializeMessage } from "../shared/stdio.js";
* This transport is only available in Node.js environments.
*/
export class StdioClientTransport {
constructor() {
constructor(server) {
this._abortController = new AbortController();
this._readBuffer = new ReadBuffer();
this._serverParams = server;
}
/**
* Spawns the server process and prepare to communicate with it.
* Starts the server process and prepares to communicate with it.
*/
spawn(server) {
async start() {
if (this._process) {
throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
}
return new Promise((resolve, reject) => {
var _a, _b, _c, _d;
this._process = spawn(server.command, (_a = server.args) !== null && _a !== void 0 ? _a : [], {
this._process = spawn(this._serverParams.command, (_a = this._serverParams.args) !== null && _a !== void 0 ? _a : [], {
// The parent process may have sensitive secrets in its env, so don't inherit it automatically.
env: server.env === undefined ? {} : { ...server.env },
env: this._serverParams.env === undefined
? {}
: { ...this._serverParams.env },
stdio: ["pipe", "pipe", "inherit"],
signal: this._abortController.signal,
});

View File

@@ -1 +1 @@
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/client/stdio.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/client/stdio.ts"],"names":[],"mappings":"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"}

View File

@@ -3,7 +3,7 @@ const serverParameters = {
command: "/usr/bin/tee",
};
test("should start then close cleanly", async () => {
const client = new StdioClientTransport();
const client = new StdioClientTransport(serverParameters);
client.onerror = (error) => {
throw error;
};
@@ -11,13 +11,13 @@ test("should start then close cleanly", async () => {
client.onclose = () => {
didClose = true;
};
await client.spawn(serverParameters);
await client.start();
expect(didClose).toBeFalsy();
await client.close();
expect(didClose).toBeTruthy();
});
test("should read messages", async () => {
const client = new StdioClientTransport();
const client = new StdioClientTransport(serverParameters);
client.onerror = (error) => {
throw error;
};
@@ -41,7 +41,7 @@ test("should read messages", async () => {
}
};
});
await client.spawn(serverParameters);
await client.start();
await client.send(messages[0]);
await client.send(messages[1]);
await finished;

View File

@@ -1 +1 @@
{"version":3,"file":"stdio.test.js","sourceRoot":"","sources":["../../src/client/stdio.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,YAAY,CAAC;AAEzE,MAAM,gBAAgB,GAA0B;IAC9C,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;IACjD,MAAM,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC1C,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,KAAK,CAAC;IACd,CAAC,CAAC;IAEF,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACrC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IACtC,MAAM,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC1C,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,KAAK,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAqB;QACjC;YACE,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,MAAM;SACf;QACD;YACE,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,2BAA2B;SACpC;KACF,CAAC;IAEF,MAAM,YAAY,GAAqB,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC7C,MAAM,CAAC,SAAS,GAAG,CAAC,OAAO,EAAE,EAAE;YAC7B,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE3B,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACrC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,QAAQ,CAAC;IACf,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC"}
{"version":3,"file":"stdio.test.js","sourceRoot":"","sources":["../../src/client/stdio.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,YAAY,CAAC;AAEzE,MAAM,gBAAgB,GAA0B;IAC9C,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;IACjD,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IAC1D,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,KAAK,CAAC;IACd,CAAC,CAAC;IAEF,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IACtC,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IAC1D,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,KAAK,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAqB;QACjC;YACE,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,MAAM;SACf;QACD;YACE,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,2BAA2B;SACpC;KACF,CAAC;IAEF,MAAM,YAAY,GAAqB,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC7C,MAAM,CAAC,SAAS,GAAG,CAAC,OAAO,EAAE,EAAE;YAC7B,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE3B,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,QAAQ,CAAC;IACf,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC"}

View File

@@ -5,10 +5,12 @@ import { JSONRPCMessage } from "../types.js";
*/
export declare class WebSocketClientTransport implements Transport {
private _socket?;
private _url;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
connect(url: URL): Promise<void>;
constructor(url: URL);
start(): Promise<void>;
close(): Promise<void>;
send(message: JSONRPCMessage): Promise<void>;
}

View File

@@ -1 +1 @@
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAInE;;GAEG;AACH,qBAAa,wBAAyB,YAAW,SAAS;IACxD,OAAO,CAAC,OAAO,CAAC,CAAY;IAE5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAE9C,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAW7C"}
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAInE;;GAEG;AACH,qBAAa,wBAAyB,YAAW,SAAS;IACxD,OAAO,CAAC,OAAO,CAAC,CAAY;IAC5B,OAAO,CAAC,IAAI,CAAM;IAElB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;gBAElC,GAAG,EAAE,GAAG;IAIpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyChB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAW7C"}

View File

@@ -4,9 +4,15 @@ const SUBPROTOCOL = "mcp";
* Client transport for WebSocket: this will connect to a server over the WebSocket protocol.
*/
export class WebSocketClientTransport {
connect(url) {
constructor(url) {
this._url = url;
}
start() {
if (this._socket) {
throw new Error("WebSocketClientTransport already started! If using Client class, note that connect() calls start() automatically.");
}
return new Promise((resolve, reject) => {
this._socket = new WebSocket(url, SUBPROTOCOL);
this._socket = new WebSocket(this._url, SUBPROTOCOL);
this._socket.onerror = (event) => {
var _a;
const error = "error" in event

View File

@@ -1 +1 @@
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B;;GAEG;AACH,MAAM,OAAO,wBAAwB;IAOnC,OAAO,CAAC,GAAQ;QACd,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,OAAO,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YAE/C,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;;gBAC/B,MAAM,KAAK,GACT,OAAO,IAAI,KAAK;oBACd,CAAC,CAAE,KAAK,CAAC,KAAe;oBACxB,CAAC,CAAC,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC7D,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAK,CAAC,CAAC;YACxB,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE;gBACzB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE;;gBAC1B,MAAA,IAAI,CAAC,OAAO,oDAAI,CAAC;YACnB,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;;gBAC/C,IAAI,OAAuB,CAAC;gBAC5B,IAAI,CAAC;oBACH,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC/D,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAc,CAAC,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBAED,MAAA,IAAI,CAAC,SAAS,qDAAG,OAAO,CAAC,CAAC;YAC5B,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;;QACT,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,OAAuB;QAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;;YACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5C,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B;;GAEG;AACH,MAAM,OAAO,wBAAwB;IAQnC,YAAY,GAAQ;QAClB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAClB,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,OAAO,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAErD,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;;gBAC/B,MAAM,KAAK,GACT,OAAO,IAAI,KAAK;oBACd,CAAC,CAAE,KAAK,CAAC,KAAe;oBACxB,CAAC,CAAC,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC7D,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAK,CAAC,CAAC;YACxB,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE;gBACzB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE;;gBAC1B,MAAA,IAAI,CAAC,OAAO,oDAAI,CAAC;YACnB,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;;gBAC/C,IAAI,OAAuB,CAAC;gBAC5B,IAAI,CAAC;oBACH,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC/D,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAc,CAAC,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBAED,MAAA,IAAI,CAAC,SAAS,qDAAG,OAAO,CAAC,CAAC;YAC5B,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;;QACT,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,OAAuB;QAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;;YACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5C,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}

View File

@@ -26,5 +26,7 @@ export declare class Server extends Protocol<ServerRequest, ServerNotification,
* After initialization has completed, this will be populated with information about the client's name and version.
*/
getClientVersion(): Implementation | undefined;
private getCapability;
private getCapabilities;
}
//# sourceMappingURL=index.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,cAAc,EAMd,kBAAkB,EAClB,aAAa,EACb,YAAY,EACb,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,qBAAa,MAAO,SAAQ,QAAQ,CAClC,aAAa,EACb,kBAAkB,EAClB,YAAY,CACb;IAYa,OAAO,CAAC,WAAW;IAX/B,OAAO,CAAC,mBAAmB,CAAC,CAAqB;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAE3B;;OAEG;gBACiB,WAAW,EAAE,cAAc;YAWjC,aAAa;IAmB3B;;OAEG;IACH,qBAAqB,IAAI,kBAAkB,GAAG,SAAS;IAIvD;;OAEG;IACH,gBAAgB,IAAI,cAAc,GAAG,SAAS;CAG/C"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,kBAAkB,EAElB,cAAc,EAMd,kBAAkB,EAClB,aAAa,EACb,YAAY,EAMb,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,qBAAa,MAAO,SAAQ,QAAQ,CAClC,aAAa,EACb,kBAAkB,EAClB,YAAY,CACb;IAYa,OAAO,CAAC,WAAW;IAX/B,OAAO,CAAC,mBAAmB,CAAC,CAAqB;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAE3B;;OAEG;gBACiB,WAAW,EAAE,cAAc;YAWjC,aAAa;IAmB3B;;OAEG;IACH,qBAAqB,IAAI,kBAAkB,GAAG,SAAS;IAIvD;;OAEG;IACH,gBAAgB,IAAI,cAAc,GAAG,SAAS;IAI9C,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,eAAe;CAUxB"}

View File

@@ -1,5 +1,5 @@
import { Protocol } from "../shared/protocol.js";
import { InitializedNotificationSchema, InitializeRequestSchema, PROTOCOL_VERSION, } from "../types.js";
import { InitializedNotificationSchema, InitializeRequestSchema, PROTOCOL_VERSION, ListResourcesRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, SetLevelRequestSchema, } from "../types.js";
/**
* An MCP server on top of a pluggable transport.
*
@@ -23,7 +23,7 @@ export class Server extends Protocol {
this._clientVersion = request.params.clientInfo;
return {
protocolVersion: PROTOCOL_VERSION,
capabilities: {},
capabilities: this.getCapabilities(),
serverInfo: this._serverInfo,
};
}
@@ -39,5 +39,16 @@ export class Server extends Protocol {
getClientVersion() {
return this._clientVersion;
}
getCapability(reqType) {
return this._requestHandlers.has(reqType) ? {} : undefined;
}
getCapabilities() {
return {
prompts: this.getCapability(ListPromptsRequestSchema.shape.method.value),
resources: this.getCapability(ListResourcesRequestSchema.shape.method.value),
tools: this.getCapability(ListToolsRequestSchema.shape.method.value),
logging: this.getCapability(SetLevelRequestSchema.shape.method.value),
};
}
}
//# sourceMappingURL=index.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAGL,6BAA6B,EAE7B,uBAAuB,EAEvB,gBAAgB,GAIjB,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,MAAM,OAAO,MAAO,SAAQ,QAI3B;IASC;;OAEG;IACH,YAAoB,WAA2B;QAC7C,KAAK,EAAE,CAAC;QADU,gBAAW,GAAX,WAAW,CAAgB;QAG7C,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,CAC1D,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAC5B,CAAC;QACF,IAAI,CAAC,sBAAsB,CAAC,6BAA6B,EAAE,GAAG,EAAE,WAC9D,OAAA,MAAA,IAAI,CAAC,aAAa,oDAAI,CAAA,EAAA,CACvB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,OAA0B;QAE1B,IAAI,OAAO,CAAC,MAAM,CAAC,eAAe,KAAK,gBAAgB,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CACb,+CAA+C,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAChF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;QAEhD,OAAO;YACL,eAAe,EAAE,gBAAgB;YACjC,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE,IAAI,CAAC,WAAW;SAC7B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAIL,6BAA6B,EAE7B,uBAAuB,EAEvB,gBAAgB,EAKhB,0BAA0B,EAC1B,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,MAAM,OAAO,MAAO,SAAQ,QAI3B;IASC;;OAEG;IACH,YAAoB,WAA2B;QAC7C,KAAK,EAAE,CAAC;QADU,gBAAW,GAAX,WAAW,CAAgB;QAG7C,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,CAC1D,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAC5B,CAAC;QACF,IAAI,CAAC,sBAAsB,CAAC,6BAA6B,EAAE,GAAG,EAAE,WAC9D,OAAA,MAAA,IAAI,CAAC,aAAa,oDAAI,CAAA,EAAA,CACvB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,OAA0B;QAE1B,IAAI,OAAO,CAAC,MAAM,CAAC,eAAe,KAAK,gBAAgB,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CACb,+CAA+C,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAChF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;QAEhD,OAAO;YACL,eAAe,EAAE,gBAAgB;YACjC,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE;YACpC,UAAU,EAAE,IAAI,CAAC,WAAW;SAC7B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAEO,aAAa,CACnB,OAAgC;QAEhC,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,CAAC;IAEO,eAAe;QACrB,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;YACxE,SAAS,EAAE,IAAI,CAAC,aAAa,CAC3B,0BAA0B,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAC9C;YACD,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;YACpE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;SACtE,CAAC;IACJ,CAAC;CACF"}

View File

@@ -8,6 +8,7 @@ import { JSONRPCMessage } from "../types.js";
*/
export declare class SSEServerTransport implements Transport {
private _endpoint;
private res;
private _sseResponse?;
private _sessionId;
onclose?: () => void;
@@ -16,13 +17,13 @@ export declare class SSEServerTransport implements Transport {
/**
* Creates a new SSE server transport, which will direct the client to POST messages to the relative or absolute URL identified by `_endpoint`.
*/
constructor(_endpoint: string);
constructor(_endpoint: string, res: ServerResponse);
/**
* Handles the initial SSE connection request.
*
* This should be called when a GET request is made to establish the SSE stream.
*/
connectSSE(req: IncomingMessage, res: ServerResponse): Promise<void>;
start(): Promise<void>;
/**
* Handles incoming POST messages.
*

View File

@@ -1 +1 @@
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAMnE;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,SAAS;IAWtC,OAAO,CAAC,SAAS;IAV7B,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAE9C;;OAEG;gBACiB,SAAS,EAAE,MAAM;IAIrC;;;;OAIG;IACG,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB1E;;;;OAIG;IACG,iBAAiB,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC;IAkChB;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlD;;;;OAIG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAMnE;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,SAAS;IAYhD,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,GAAG;IAZb,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAE9C;;OAEG;gBAEO,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,cAAc;IAK7B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB5B;;;;OAIG;IACG,iBAAiB,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC;IAkChB;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlD;;;;OAIG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}

View File

@@ -12,8 +12,9 @@ export class SSEServerTransport {
/**
* Creates a new SSE server transport, which will direct the client to POST messages to the relative or absolute URL identified by `_endpoint`.
*/
constructor(_endpoint) {
constructor(_endpoint, res) {
this._endpoint = _endpoint;
this.res = res;
this._sessionId = randomUUID();
}
/**
@@ -21,19 +22,19 @@ export class SSEServerTransport {
*
* This should be called when a GET request is made to establish the SSE stream.
*/
async connectSSE(req, res) {
async start() {
if (this._sseResponse) {
throw new Error("Already connected!");
throw new Error("SSEServerTransport already started! If using Server class, note that connect() calls start() automatically.");
}
res.writeHead(200, {
this.res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
// Send the endpoint event
res.write(`event: endpoint\ndata: ${encodeURI(this._endpoint)}?sessionId=${this._sessionId}\n\n`);
this._sseResponse = res;
res.on("close", () => {
this.res.write(`event: endpoint\ndata: ${encodeURI(this._endpoint)}?sessionId=${this._sessionId}\n\n`);
this._sseResponse = this.res;
this.res.on("close", () => {
var _a;
this._sseResponse = undefined;
(_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this);

View File

@@ -1 +1 @@
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"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"}

View File

@@ -10,6 +10,7 @@ export declare class StdioServerTransport implements Transport {
private _stdin;
private _stdout;
private _readBuffer;
private _started;
constructor(_stdin?: Readable, _stdout?: Writable);
onclose?: () => void;
onerror?: (error: Error) => void;

View File

@@ -1 +1 @@
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/server/stdio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IAIlD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IAJjB,OAAO,CAAC,WAAW,CAAgC;gBAGzC,MAAM,GAAE,QAAwB,EAChC,OAAO,GAAE,QAAyB;IAG5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAG9C,OAAO,UAAW,MAAM,UAGtB;IACF,QAAQ,UAAW,KAAK,UAEtB;IAEF;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,OAAO,CAAC,iBAAiB;IAenB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAU7C"}
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/server/stdio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IAKlD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IALjB,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,QAAQ,CAAS;gBAGf,MAAM,GAAE,QAAwB,EAChC,OAAO,GAAE,QAAyB;IAG5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAG9C,OAAO,UAAW,MAAM,UAGtB;IACF,QAAQ,UAAW,KAAK,UAEtB;IAEF;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,OAAO,CAAC,iBAAiB;IAenB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAU7C"}

View File

@@ -10,6 +10,7 @@ export class StdioServerTransport {
this._stdin = _stdin;
this._stdout = _stdout;
this._readBuffer = new ReadBuffer();
this._started = false;
// Arrow functions to bind `this` properly, while maintaining function identity.
this._ondata = (chunk) => {
this._readBuffer.append(chunk);
@@ -24,6 +25,10 @@ export class StdioServerTransport {
* Starts listening for messages on stdin.
*/
async start() {
if (this._started) {
throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
}
this._started = true;
this._stdin.on("data", this._ondata);
this._stdin.on("error", this._onerror);
}

View File

@@ -1 +1 @@
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/server/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAIlE;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAG/B,YACU,SAAmB,OAAO,CAAC,KAAK,EAChC,UAAoB,OAAO,CAAC,MAAM;QADlC,WAAM,GAAN,MAAM,CAA0B;QAChC,YAAO,GAAP,OAAO,CAA2B;QAJpC,gBAAW,GAAe,IAAI,UAAU,EAAE,CAAC;QAWnD,gFAAgF;QAChF,YAAO,GAAG,CAAC,KAAa,EAAE,EAAE;YAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC,CAAC;QACF,aAAQ,GAAG,CAAC,KAAY,EAAE,EAAE;;YAC1B,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC;IAbC,CAAC;IAeJ;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,iBAAiB;;QACvB,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;gBAC/C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACrB,MAAM;gBACR,CAAC;gBAED,MAAA,IAAI,CAAC,SAAS,qDAAG,OAAO,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAc,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;;QACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,MAAA,IAAI,CAAC,OAAO,oDAAI,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,OAAuB;QAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/server/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAIlE;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAI/B,YACU,SAAmB,OAAO,CAAC,KAAK,EAChC,UAAoB,OAAO,CAAC,MAAM;QADlC,WAAM,GAAN,MAAM,CAA0B;QAChC,YAAO,GAAP,OAAO,CAA2B;QALpC,gBAAW,GAAe,IAAI,UAAU,EAAE,CAAC;QAC3C,aAAQ,GAAG,KAAK,CAAC;QAWzB,gFAAgF;QAChF,YAAO,GAAG,CAAC,KAAa,EAAE,EAAE;YAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC,CAAC;QACF,aAAQ,GAAG,CAAC,KAAY,EAAE,EAAE;;YAC1B,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC;IAbC,CAAC;IAeJ;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,iBAAiB;;QACvB,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;gBAC/C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACrB,MAAM;gBACR,CAAC;gBAED,MAAA,IAAI,CAAC,SAAS,qDAAG,OAAO,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAA,IAAI,CAAC,OAAO,qDAAG,KAAc,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;;QACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,MAAA,IAAI,CAAC,OAAO,oDAAI,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,OAAuB;QAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}

View File

@@ -1,5 +1,5 @@
import { AnyZodObject, ZodLiteral, ZodObject, z } from "zod";
import { Notification, Progress, Request, Result } from "../types.js";
import { JSONRPCRequest, Notification, Progress, Request, Result } from "../types.js";
import { Transport } from "./transport.js";
/**
* Callback for progress notifications.
@@ -12,7 +12,7 @@ export type ProgressCallback = (progress: Progress) => void;
export declare class Protocol<SendRequestT extends Request, SendNotificationT extends Notification, SendResultT extends Result> {
private _transport?;
private _requestMessageId;
private _requestHandlers;
protected _requestHandlers: Map<string, (request: JSONRPCRequest) => Promise<SendResultT>>;
private _notificationHandlers;
private _responseHandlers;
private _progressHandlers;
@@ -38,7 +38,7 @@ export declare class Protocol<SendRequestT extends Request, SendNotificationT ex
fallbackNotificationHandler?: (notification: Notification) => Promise<void>;
constructor();
/**
* Attaches to the given transport and starts listening for messages.
* Attaches to the given transport, starts it, and starts listening for messages.
*
* The Protocol object assumes ownership of the Transport, replacing any callbacks that have already been set, and expects that it is the only user of the Transport instance going forward.
*/

View File

@@ -1 +1 @@
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7D,OAAO,EAOL,YAAY,EAEZ,QAAQ,EAGR,OAAO,EACP,MAAM,EACP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE5D;;;GAGG;AACH,qBAAa,QAAQ,CACnB,YAAY,SAAS,OAAO,EAC5B,iBAAiB,SAAS,YAAY,EACtC,WAAW,SAAS,MAAM;IAE1B,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,gBAAgB,CAGV;IACd,OAAO,CAAC,qBAAqB,CAGf;IACd,OAAO,CAAC,iBAAiB,CAGX;IACd,OAAO,CAAC,iBAAiB,CAA4C;IAErE;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAEpE;;OAEG;IACH,2BAA2B,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;;IAc5E;;;;OAIG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBlD,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,UAAU;IAiDlB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,WAAW;IA0BnB,IAAI,SAAS,IAAI,SAAS,GAAG,SAAS,CAErC;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;;OAIG;IACH,OAAO,CAAC,CAAC,SAAS,YAAY,EAC5B,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,CAAC,EACf,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAuCtB;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAalE;;;;OAIG;IACH,iBAAiB,CACf,CAAC,SAAS,SAAS,CAAC;QAClB,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;KAC5B,CAAC,EAEF,aAAa,EAAE,CAAC,EAChB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,GACnE,IAAI;IAMP;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI1C;;;;OAIG;IACH,sBAAsB,CACpB,CAAC,SAAS,SAAS,CAAC;QAClB,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;KAC5B,CAAC,EAEF,kBAAkB,EAAE,CAAC,EACrB,OAAO,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1D,IAAI;IAQP;;OAEG;IACH,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGhD"}
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7D,OAAO,EAIL,cAAc,EAGd,YAAY,EAEZ,QAAQ,EAGR,OAAO,EACP,MAAM,EACP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE5D;;;GAGG;AACH,qBAAa,QAAQ,CACnB,YAAY,SAAS,OAAO,EAC5B,iBAAiB,SAAS,YAAY,EACtC,WAAW,SAAS,MAAM;IAE1B,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,SAAS,CAAC,gBAAgB,EAAE,GAAG,CAC7B,MAAM,EACN,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,WAAW,CAAC,CAClD,CAAa;IACd,OAAO,CAAC,qBAAqB,CAGf;IACd,OAAO,CAAC,iBAAiB,CAGX;IACd,OAAO,CAAC,iBAAiB,CAA4C;IAErE;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAEpE;;OAEG;IACH,2BAA2B,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;;IAc5E;;;;OAIG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBlD,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,UAAU;IAiDlB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,WAAW;IA0BnB,IAAI,SAAS,IAAI,SAAS,GAAG,SAAS,CAErC;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;;OAIG;IACH,OAAO,CAAC,CAAC,SAAS,YAAY,EAC5B,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,CAAC,EACf,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAuCtB;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAalE;;;;OAIG;IACH,iBAAiB,CACf,CAAC,SAAS,SAAS,CAAC;QAClB,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;KAC5B,CAAC,EAEF,aAAa,EAAE,CAAC,EAChB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,GACnE,IAAI;IAMP;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI1C;;;;OAIG;IACH,sBAAsB,CACpB,CAAC,SAAS,SAAS,CAAC;QAClB,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;KAC5B,CAAC,EAEF,kBAAkB,EAAE,CAAC,EACrB,OAAO,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1D,IAAI;IAQP;;OAEG;IACH,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGhD"}

View File

@@ -18,7 +18,7 @@ export class Protocol {
(_request) => ({}));
}
/**
* Attaches to the given transport and starts listening for messages.
* Attaches to the given transport, starts it, and starts listening for messages.
*
* The Protocol object assumes ownership of the Transport, replacing any callbacks that have already been set, and expects that it is the only user of the Transport instance going forward.
*/
@@ -41,6 +41,7 @@ export class Protocol {
this._onnotification(message);
}
};
await this._transport.start();
}
_onclose() {
var _a;

File diff suppressed because one or more lines are too long

View File

@@ -3,6 +3,14 @@ import { JSONRPCMessage } from "../types.js";
* Describes the minimal contract for a MCP transport that a client or server can communicate over.
*/
export interface Transport {
/**
* Starts processing messages on the transport, including any connection steps that might need to be taken.
*
* This method should only be called after callbacks are installed, or else messages may be lost.
*
* NOTE: This method should not be called explicitly when using Client, Server, or Protocol classes, as they will implicitly call start().
*/
start(): Promise<void>;
/**
* Sends a JSON-RPC message (request or response).
*/

View File

@@ -1 +1 @@
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/shared/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CAC/C"}
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/shared/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;OAMG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CAC/C"}

3040
packages/mcp-typescript/dist/types.d.ts generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -10,20 +10,21 @@ export const ProgressTokenSchema = z.union([z.string(), z.number().int()]);
* An opaque token used to represent a cursor for pagination.
*/
export const CursorSchema = z.string();
export const RequestSchema = z.object({
method: z.string(),
params: z.optional(z
const BaseRequestParamsSchema = z
.object({
_meta: z.optional(z
.object({
_meta: z.optional(z
.object({
/**
* If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications.
*/
progressToken: z.optional(ProgressTokenSchema),
})
.passthrough()),
/**
* If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications.
*/
progressToken: z.optional(ProgressTokenSchema),
})
.passthrough()),
})
.passthrough();
export const RequestSchema = z.object({
method: z.string(),
params: z.optional(BaseRequestParamsSchema),
});
export const NotificationSchema = z.object({
method: z.string(),
@@ -182,7 +183,7 @@ export const ClientCapabilitiesSchema = z.object({
*/
export const InitializeRequestSchema = RequestSchema.extend({
method: z.literal("initialize"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The latest version of the Model Context Protocol that the client supports. The client MAY decide to support older versions as well.
*/
@@ -285,18 +286,18 @@ export const ProgressNotificationSchema = NotificationSchema.extend({
/**
* The progress token which was given in the initial request, used to associate this notification with the request that is proceeding.
*/
progressToken: ProgressTokenSchema,
progressToken: z.optional(ProgressTokenSchema),
}),
});
/* Pagination */
export const PaginatedRequestSchema = RequestSchema.extend({
params: z.optional(z.object({
params: BaseRequestParamsSchema.extend({
/**
* An opaque token representing the current pagination position.
* If provided, the server should return results starting after this cursor.
*/
cursor: z.optional(CursorSchema),
})),
}),
});
export const PaginatedResultSchema = ResultSchema.extend({
/**
@@ -313,7 +314,7 @@ export const ResourceContentsSchema = z.object({
/**
* The URI of this resource.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
/**
* The MIME type of this resource, if known.
*/
@@ -338,7 +339,7 @@ export const ResourceSchema = z.object({
/**
* The URI of this resource.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
/**
* A human-readable name for this resource.
*
@@ -410,11 +411,11 @@ export const ListResourceTemplatesResultSchema = PaginatedResultSchema.extend({
*/
export const ReadResourceRequestSchema = RequestSchema.extend({
method: z.literal("resources/read"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The URI of the resource to read. The URI can use any protocol; it is up to the server how to interpret it.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
/**
@@ -434,11 +435,11 @@ export const ResourceListChangedNotificationSchema = NotificationSchema.extend({
*/
export const SubscribeRequestSchema = RequestSchema.extend({
method: z.literal("resources/subscribe"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The URI of the resource to subscribe to. The URI can use any protocol; it is up to the server how to interpret it.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
/**
@@ -446,11 +447,11 @@ export const SubscribeRequestSchema = RequestSchema.extend({
*/
export const UnsubscribeRequestSchema = RequestSchema.extend({
method: z.literal("resources/unsubscribe"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The URI of the resource to unsubscribe from.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
/**
@@ -462,7 +463,7 @@ export const ResourceUpdatedNotificationSchema = NotificationSchema.extend({
/**
* The URI of the resource that has been updated. This might be a sub-resource of the one that the client actually subscribed to.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
/* Prompts */
@@ -517,7 +518,7 @@ export const ListPromptsResultSchema = PaginatedResultSchema.extend({
*/
export const GetPromptRequestSchema = RequestSchema.extend({
method: z.literal("prompts/get"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The name of the prompt or prompt template.
*/
@@ -588,7 +589,7 @@ export const CallToolResultSchema = ResultSchema.extend({
*/
export const CallToolRequestSchema = RequestSchema.extend({
method: z.literal("tools/call"),
params: z.object({
params: BaseRequestParamsSchema.extend({
name: z.string(),
arguments: z.optional(z.record(z.unknown())),
}),
@@ -609,7 +610,7 @@ export const LoggingLevelSchema = z.enum(["debug", "info", "warning", "error"]);
*/
export const SetLevelRequestSchema = RequestSchema.extend({
method: z.literal("logging/setLevel"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The level of logging that the client wants to receive from the server. The server should send all logs at this level and higher (i.e., more severe) to the client as notifications/logging/message.
*/
@@ -642,7 +643,7 @@ export const LoggingMessageNotificationSchema = NotificationSchema.extend({
*/
export const CreateMessageRequestSchema = RequestSchema.extend({
method: z.literal("sampling/createMessage"),
params: z.object({
params: BaseRequestParamsSchema.extend({
messages: z.array(SamplingMessageSchema),
/**
* An optional system prompt the server wants to use for sampling. The client MAY modify or omit this prompt.
@@ -708,7 +709,7 @@ export const PromptReferenceSchema = z.object({
*/
export const CompleteRequestSchema = RequestSchema.extend({
method: z.literal("completion/complete"),
params: z.object({
params: BaseRequestParamsSchema.extend({
ref: z.union([PromptReferenceSchema, ResourceReferenceSchema]),
/**
* The argument's information

File diff suppressed because one or more lines are too long

View File

@@ -31,14 +31,11 @@ async function runClient(url_or_command: string, args: string[]) {
}
if (url?.protocol === "http:" || url?.protocol === "https:") {
clientTransport = new SSEClientTransport();
await clientTransport.connect(new URL(url_or_command));
clientTransport = new SSEClientTransport(new URL(url_or_command));
} else if (url?.protocol === "ws:" || url?.protocol === "wss:") {
clientTransport = new WebSocketClientTransport();
await clientTransport.connect(new URL(url_or_command));
clientTransport = new WebSocketClientTransport(new URL(url_or_command));
} else {
clientTransport = new StdioClientTransport();
await clientTransport.spawn({
clientTransport = new StdioClientTransport({
command: url_or_command,
args,
});
@@ -62,7 +59,7 @@ async function runServer(port: number | null) {
app.get("/sse", async (req, res) => {
console.log("Got new SSE connection");
const transport = new SSEServerTransport("/message");
const transport = new SSEServerTransport("/message", res);
const server = new Server({
name: "mcp-typescript test server",
version: "0.1.0",
@@ -75,7 +72,6 @@ async function runServer(port: number | null) {
servers = servers.filter((s) => s !== server);
};
await transport.connectSSE(req, res);
await server.connect(transport);
});
@@ -104,7 +100,6 @@ async function runServer(port: number | null) {
});
const transport = new StdioServerTransport();
await transport.start();
await server.connect(transport);
console.log("Server running on stdio");

View File

@@ -11,14 +11,25 @@ export class SSEClientTransport implements Transport {
private _eventSource?: EventSource;
private _endpoint?: URL;
private _abortController?: AbortController;
private _url: URL;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
connect(url: URL): Promise<void> {
constructor(url: URL) {
this._url = url;
}
start(): Promise<void> {
if (this._eventSource) {
throw new Error(
"SSEClientTransport already started! If using Client class, note that connect() calls start() automatically.",
);
}
return new Promise((resolve, reject) => {
this._eventSource = new EventSource(url.href);
this._eventSource = new EventSource(this._url.href);
this._abortController = new AbortController();
this._eventSource.onerror = (event) => {
@@ -35,8 +46,8 @@ export class SSEClientTransport implements Transport {
const messageEvent = event as MessageEvent;
try {
this._endpoint = new URL(messageEvent.data, url);
if (this._endpoint.origin !== url.origin) {
this._endpoint = new URL(messageEvent.data, this._url);
if (this._endpoint.origin !== this._url.origin) {
throw new Error(
`Endpoint origin does not match connection origin: ${this._endpoint.origin}`,
);

View File

@@ -6,7 +6,7 @@ const serverParameters: StdioServerParameters = {
};
test("should start then close cleanly", async () => {
const client = new StdioClientTransport();
const client = new StdioClientTransport(serverParameters);
client.onerror = (error) => {
throw error;
};
@@ -16,14 +16,14 @@ test("should start then close cleanly", async () => {
didClose = true;
};
await client.spawn(serverParameters);
await client.start();
expect(didClose).toBeFalsy();
await client.close();
expect(didClose).toBeTruthy();
});
test("should read messages", async () => {
const client = new StdioClientTransport();
const client = new StdioClientTransport(serverParameters);
client.onerror = (error) => {
throw error;
};
@@ -51,7 +51,7 @@ test("should read messages", async () => {
};
});
await client.spawn(serverParameters);
await client.start();
await client.send(messages[0]);
await client.send(messages[1]);
await finished;

View File

@@ -31,22 +31,40 @@ export class StdioClientTransport implements Transport {
private _process?: ChildProcess;
private _abortController: AbortController = new AbortController();
private _readBuffer: ReadBuffer = new ReadBuffer();
private _serverParams: StdioServerParameters;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
constructor(server: StdioServerParameters) {
this._serverParams = server;
}
/**
* Spawns the server process and prepare to communicate with it.
* Starts the server process and prepares to communicate with it.
*/
spawn(server: StdioServerParameters): Promise<void> {
async start(): Promise<void> {
if (this._process) {
throw new Error(
"StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.",
);
}
return new Promise((resolve, reject) => {
this._process = spawn(server.command, server.args ?? [], {
// The parent process may have sensitive secrets in its env, so don't inherit it automatically.
env: server.env === undefined ? {} : { ...server.env },
stdio: ["pipe", "pipe", "inherit"],
signal: this._abortController.signal,
});
this._process = spawn(
this._serverParams.command,
this._serverParams.args ?? [],
{
// The parent process may have sensitive secrets in its env, so don't inherit it automatically.
env:
this._serverParams.env === undefined
? {}
: { ...this._serverParams.env },
stdio: ["pipe", "pipe", "inherit"],
signal: this._abortController.signal,
},
);
this._process.on("error", (error) => {
if (error.name === "AbortError") {

View File

@@ -8,14 +8,25 @@ const SUBPROTOCOL = "mcp";
*/
export class WebSocketClientTransport implements Transport {
private _socket?: WebSocket;
private _url: URL;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
connect(url: URL): Promise<void> {
constructor(url: URL) {
this._url = url;
}
start(): Promise<void> {
if (this._socket) {
throw new Error(
"WebSocketClientTransport already started! If using Client class, note that connect() calls start() automatically.",
);
}
return new Promise((resolve, reject) => {
this._socket = new WebSocket(url, SUBPROTOCOL);
this._socket = new WebSocket(this._url, SUBPROTOCOL);
this._socket.onerror = (event) => {
const error =

View File

@@ -1,6 +1,7 @@
import { Protocol } from "../shared/protocol.js";
import {
ClientCapabilities,
ClientRequest,
Implementation,
InitializedNotificationSchema,
InitializeRequest,
@@ -10,6 +11,11 @@ import {
ServerNotification,
ServerRequest,
ServerResult,
ServerCapabilities,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ListPromptsRequestSchema,
SetLevelRequestSchema,
} from "../types.js";
/**
@@ -58,7 +64,7 @@ export class Server extends Protocol<
return {
protocolVersion: PROTOCOL_VERSION,
capabilities: {},
capabilities: this.getCapabilities(),
serverInfo: this._serverInfo,
};
}
@@ -76,4 +82,21 @@ export class Server extends Protocol<
getClientVersion(): Implementation | undefined {
return this._clientVersion;
}
private getCapability(
reqType: ClientRequest["method"],
): ServerCapabilities[keyof ServerCapabilities] {
return this._requestHandlers.has(reqType as string) ? {} : undefined;
}
private getCapabilities(): ServerCapabilities {
return {
prompts: this.getCapability(ListPromptsRequestSchema.shape.method.value),
resources: this.getCapability(
ListResourcesRequestSchema.shape.method.value,
),
tools: this.getCapability(ListToolsRequestSchema.shape.method.value),
logging: this.getCapability(SetLevelRequestSchema.shape.method.value),
};
}
}

View File

@@ -23,7 +23,10 @@ export class SSEServerTransport implements Transport {
/**
* Creates a new SSE server transport, which will direct the client to POST messages to the relative or absolute URL identified by `_endpoint`.
*/
constructor(private _endpoint: string) {
constructor(
private _endpoint: string,
private res: ServerResponse,
) {
this._sessionId = randomUUID();
}
@@ -32,24 +35,26 @@ export class SSEServerTransport implements Transport {
*
* This should be called when a GET request is made to establish the SSE stream.
*/
async connectSSE(req: IncomingMessage, res: ServerResponse): Promise<void> {
async start(): Promise<void> {
if (this._sseResponse) {
throw new Error("Already connected!");
throw new Error(
"SSEServerTransport already started! If using Server class, note that connect() calls start() automatically.",
);
}
res.writeHead(200, {
this.res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
// Send the endpoint event
res.write(
this.res.write(
`event: endpoint\ndata: ${encodeURI(this._endpoint)}?sessionId=${this._sessionId}\n\n`,
);
this._sseResponse = res;
res.on("close", () => {
this._sseResponse = this.res;
this.res.on("close", () => {
this._sseResponse = undefined;
this.onclose?.();
});

View File

@@ -11,6 +11,7 @@ import { Transport } from "../shared/transport.js";
*/
export class StdioServerTransport implements Transport {
private _readBuffer: ReadBuffer = new ReadBuffer();
private _started = false;
constructor(
private _stdin: Readable = process.stdin,
@@ -34,6 +35,13 @@ export class StdioServerTransport implements Transport {
* Starts listening for messages on stdin.
*/
async start(): Promise<void> {
if (this._started) {
throw new Error(
"StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.",
);
}
this._started = true;
this._stdin.on("data", this._ondata);
this._stdin.on("error", this._onerror);
}

View File

@@ -32,7 +32,7 @@ export class Protocol<
> {
private _transport?: Transport;
private _requestMessageId = 0;
private _requestHandlers: Map<
protected _requestHandlers: Map<
string,
(request: JSONRPCRequest) => Promise<SendResultT>
> = new Map();
@@ -83,7 +83,7 @@ export class Protocol<
}
/**
* Attaches to the given transport and starts listening for messages.
* Attaches to the given transport, starts it, and starts listening for messages.
*
* The Protocol object assumes ownership of the Transport, replacing any callbacks that have already been set, and expects that it is the only user of the Transport instance going forward.
*/
@@ -106,6 +106,8 @@ export class Protocol<
this._onnotification(message);
}
};
await this._transport.start();
}
private _onclose(): void {

View File

@@ -4,6 +4,15 @@ import { JSONRPCMessage } from "../types.js";
* Describes the minimal contract for a MCP transport that a client or server can communicate over.
*/
export interface Transport {
/**
* Starts processing messages on the transport, including any connection steps that might need to be taken.
*
* This method should only be called after callbacks are installed, or else messages may be lost.
*
* NOTE: This method should not be called explicitly when using Client, Server, or Protocol classes, as they will implicitly call start().
*/
start(): Promise<void>;
/**
* Sends a JSON-RPC message (request or response).
*/

View File

@@ -15,24 +15,24 @@ export const ProgressTokenSchema = z.union([z.string(), z.number().int()]);
*/
export const CursorSchema = z.string();
const BaseRequestParamsSchema = z
.object({
_meta: z.optional(
z
.object({
/**
* If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications.
*/
progressToken: z.optional(ProgressTokenSchema),
})
.passthrough(),
),
})
.passthrough();
export const RequestSchema = z.object({
method: z.string(),
params: z.optional(
z
.object({
_meta: z.optional(
z
.object({
/**
* If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications.
*/
progressToken: z.optional(ProgressTokenSchema),
})
.passthrough(),
),
})
.passthrough(),
),
params: z.optional(BaseRequestParamsSchema),
});
export const NotificationSchema = z.object({
@@ -209,7 +209,7 @@ export const ClientCapabilitiesSchema = z.object({
*/
export const InitializeRequestSchema = RequestSchema.extend({
method: z.literal("initialize"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The latest version of the Model Context Protocol that the client supports. The client MAY decide to support older versions as well.
*/
@@ -324,21 +324,19 @@ export const ProgressNotificationSchema = NotificationSchema.extend({
/**
* The progress token which was given in the initial request, used to associate this notification with the request that is proceeding.
*/
progressToken: ProgressTokenSchema,
progressToken: z.optional(ProgressTokenSchema),
}),
});
/* Pagination */
export const PaginatedRequestSchema = RequestSchema.extend({
params: z.optional(
z.object({
/**
* An opaque token representing the current pagination position.
* If provided, the server should return results starting after this cursor.
*/
cursor: z.optional(CursorSchema),
}),
),
params: BaseRequestParamsSchema.extend({
/**
* An opaque token representing the current pagination position.
* If provided, the server should return results starting after this cursor.
*/
cursor: z.optional(CursorSchema),
}),
});
export const PaginatedResultSchema = ResultSchema.extend({
@@ -357,7 +355,7 @@ export const ResourceContentsSchema = z.object({
/**
* The URI of this resource.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
/**
* The MIME type of this resource, if known.
*/
@@ -385,7 +383,7 @@ export const ResourceSchema = z.object({
/**
* The URI of this resource.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
/**
* A human-readable name for this resource.
@@ -471,11 +469,11 @@ export const ListResourceTemplatesResultSchema = PaginatedResultSchema.extend({
*/
export const ReadResourceRequestSchema = RequestSchema.extend({
method: z.literal("resources/read"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The URI of the resource to read. The URI can use any protocol; it is up to the server how to interpret it.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
@@ -500,11 +498,11 @@ export const ResourceListChangedNotificationSchema = NotificationSchema.extend({
*/
export const SubscribeRequestSchema = RequestSchema.extend({
method: z.literal("resources/subscribe"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The URI of the resource to subscribe to. The URI can use any protocol; it is up to the server how to interpret it.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
@@ -513,11 +511,11 @@ export const SubscribeRequestSchema = RequestSchema.extend({
*/
export const UnsubscribeRequestSchema = RequestSchema.extend({
method: z.literal("resources/unsubscribe"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The URI of the resource to unsubscribe from.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
@@ -530,7 +528,7 @@ export const ResourceUpdatedNotificationSchema = NotificationSchema.extend({
/**
* The URI of the resource that has been updated. This might be a sub-resource of the one that the client actually subscribed to.
*/
uri: z.string().transform((s) => new URL(s)),
uri: z.string(),
}),
});
@@ -590,7 +588,7 @@ export const ListPromptsResultSchema = PaginatedResultSchema.extend({
*/
export const GetPromptRequestSchema = RequestSchema.extend({
method: z.literal("prompts/get"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The name of the prompt or prompt template.
*/
@@ -668,7 +666,7 @@ export const CallToolResultSchema = ResultSchema.extend({
*/
export const CallToolRequestSchema = RequestSchema.extend({
method: z.literal("tools/call"),
params: z.object({
params: BaseRequestParamsSchema.extend({
name: z.string(),
arguments: z.optional(z.record(z.unknown())),
}),
@@ -692,7 +690,7 @@ export const LoggingLevelSchema = z.enum(["debug", "info", "warning", "error"]);
*/
export const SetLevelRequestSchema = RequestSchema.extend({
method: z.literal("logging/setLevel"),
params: z.object({
params: BaseRequestParamsSchema.extend({
/**
* The level of logging that the client wants to receive from the server. The server should send all logs at this level and higher (i.e., more severe) to the client as notifications/logging/message.
*/
@@ -727,7 +725,7 @@ export const LoggingMessageNotificationSchema = NotificationSchema.extend({
*/
export const CreateMessageRequestSchema = RequestSchema.extend({
method: z.literal("sampling/createMessage"),
params: z.object({
params: BaseRequestParamsSchema.extend({
messages: z.array(SamplingMessageSchema),
/**
* An optional system prompt the server wants to use for sampling. The client MAY modify or omit this prompt.
@@ -797,7 +795,7 @@ export const PromptReferenceSchema = z.object({
*/
export const CompleteRequestSchema = RequestSchema.extend({
method: z.literal("completion/complete"),
params: z.object({
params: BaseRequestParamsSchema.extend({
ref: z.union([PromptReferenceSchema, ResourceReferenceSchema]),
/**
* The argument's information

View File

@@ -25,15 +25,15 @@ const createTransport = async (query: express.Request["query"]) => {
const command = query.command as string;
const args = (query.args as string).split(",");
console.log(`Stdio transport: command=${command}, args=${args}`);
const transport = new StdioClientTransport();
await transport.spawn({ command, args });
const transport = new StdioClientTransport({ command, args });
await transport.start();
console.log("Spawned stdio transport");
return transport;
} else if (transportType === "sse") {
const url = query.url as string;
console.log(`SSE transport: url=${url}`);
const transport = new SSEClientTransport();
await transport.connect(new URL(url));
const transport = new SSEClientTransport(new URL(url));
await transport.start();
console.log("Connected to SSE transport");
return transport;
} else {
@@ -49,13 +49,13 @@ app.get("/sse", async (req, res) => {
console.log("Connected MCP client to backing server transport");
const webAppTransport = new SSEServerTransport("/message");
const webAppTransport = new SSEServerTransport("/message", res);
console.log("Created web app transport");
webAppTransports.push(webAppTransport);
console.log("Created web app transport");
await webAppTransport.connectSSE(req, res);
await webAppTransport.start();
mcpProxy({
transportToClient: webAppTransport,