-
Notifications
You must be signed in to change notification settings - Fork 448
SSE and Streaming Support POC #1422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
2d70c4f
simple sse/streamable http connectivity, backwards compatible
evalstate 98dd695
handle multipart responses
evalstate 09fa5f1
Merge remote-tracking branch 'upstream/main' into feat/mcp-cli-sse
evalstate bf0cee2
workaround for passing HF_TOKEN with the current TS SDK
evalstate 8d20256
Merge remote-tracking branch 'upstream/main' into feat/mcp-cli-sse
evalstate a8da021
Merge remote-tracking branch 'upstream/main' into feat/mcp-cli-sse
evalstate 061ec22
Update to InferenceProvider type, coercion for MCP type
evalstate 6c47cd6
move test to correct directory
evalstate bc5aba7
allow specification of (remote mcp) url on command line - include HF_…
evalstate 6e6e684
linter, recheck main, pin package.
evalstate 0a19216
Merge remote-tracking branch 'upstream/main' into feat/mcp-cli-sse
evalstate 8d287af
tweaks
julien-c f562ae8
Update pnpm-lock.yaml
julien-c 59c4b5b
Update packages/mcp-client/cli.ts
julien-c 383ffc7
`InferenceProvider` => `InferenceProviderOrPolicy`
julien-c 86085f6
"streamableHttp" => "http"
julien-c bb352be
use compatibility type rather than type assertion
evalstate 0ac2586
Update packages/mcp-client/src/utils.ts
evalstate 542cfa8
Update packages/mcp-client/src/utils.ts
evalstate File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import type { | ||
TextResourceContents, | ||
BlobResourceContents, | ||
CompatibilityCallToolResult, | ||
} from "@modelcontextprotocol/sdk/types"; | ||
|
||
/** | ||
* A utility class for formatting CallToolResult contents into human-readable text. | ||
* Processes different content types, extracts text, and summarizes binary data. | ||
*/ | ||
export class ResultFormatter { | ||
/** | ||
* Formats a CallToolResult's contents into a single string. | ||
* - Text content is included directly | ||
* - Binary content (images, audio, blobs) is summarized | ||
* | ||
* @param result The CallToolResult to format | ||
* @returns A human-readable string representation of the result contents | ||
*/ | ||
static format(result: CompatibilityCallToolResult): string { | ||
if (!result.content || !Array.isArray(result.content) || result.content.length === 0) { | ||
return "[No content]"; | ||
} | ||
|
||
const formattedParts: string[] = []; | ||
|
||
for (const item of result.content) { | ||
switch (item.type) { | ||
case "text": | ||
// Extract text content directly | ||
formattedParts.push(item.text); | ||
break; | ||
|
||
case "image": { | ||
// Summarize image content | ||
const imageSize = this.getBase64Size(item.data); | ||
formattedParts.push( | ||
`[Binary Content: Image ${item.mimeType}, ${imageSize} bytes]\nThe task is complete and the content accessible to the User` | ||
); | ||
break; | ||
} | ||
|
||
case "audio": { | ||
// Summarize audio content | ||
const audioSize = this.getBase64Size(item.data); | ||
formattedParts.push( | ||
`[Binary Content: Audio ${item.mimeType}, ${audioSize} bytes]\nThe task is complete and the content accessible to the User` | ||
); | ||
break; | ||
} | ||
|
||
case "resource": | ||
// Handle embedded resources - explicitly type the resource | ||
if ("text" in item.resource) { | ||
// It's a text resource with a text property | ||
const textResource = item.resource as TextResourceContents; | ||
formattedParts.push(textResource.text); | ||
} else if ("blob" in item.resource) { | ||
// It's a binary resource with a blob property | ||
const blobResource = item.resource as BlobResourceContents; | ||
const blobSize = this.getBase64Size(blobResource.blob); | ||
const uri = blobResource.uri ? ` (${blobResource.uri})` : ""; | ||
const mimeType = blobResource.mimeType ? blobResource.mimeType : "unknown type"; | ||
formattedParts.push( | ||
`[Binary Content${uri}: ${mimeType}, ${blobSize} bytes]\nThe task is complete and the content accessible to the User` | ||
); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
return formattedParts.join("\n"); | ||
} | ||
|
||
/** | ||
* Calculates the approximate size in bytes of base64-encoded data | ||
*/ | ||
private static getBase64Size(base64: string): number { | ||
// Remove base64 header if present (e.g., data:image/png;base64,) | ||
const cleanBase64 = base64.includes(",") ? base64.split(",")[1] : base64; | ||
|
||
// Calculate size: Base64 encodes 3 bytes into 4 characters | ||
const padding = cleanBase64.endsWith("==") ? 2 : cleanBase64.endsWith("=") ? 1 : 0; | ||
return Math.floor((cleanBase64.length * 3) / 4 - padding); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// src/types.ts | ||
import type { StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js"; | ||
import type { SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js"; | ||
import type { StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; | ||
|
||
/** StdioServerParameters is usable as-is */ | ||
|
||
/** | ||
* Configuration for an SSE MCP server | ||
*/ | ||
export interface SSEServerConfig { | ||
url: string | URL; | ||
options?: SSEClientTransportOptions; | ||
} | ||
|
||
/** | ||
* Configuration for a StreamableHTTP MCP server | ||
*/ | ||
export interface StreamableHTTPServerConfig { | ||
url: string | URL; | ||
options?: StreamableHTTPClientTransportOptions; | ||
} | ||
|
||
/** | ||
* Discriminated union type for different MCP server types | ||
*/ | ||
export type ServerConfig = | ||
| { type: "stdio"; config: StdioServerParameters } | ||
| { type: "sse"; config: SSEServerConfig } | ||
julien-c marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { type: "http"; config: StreamableHTTPServerConfig }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.