first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
module github.com/maximhq/bifrost/examples/mcps/parallel-test-server
go 1.26.2
require github.com/mark3labs/mcp-go v0.43.2
require (
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/invopop/jsonschema v0.13.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@@ -0,0 +1,39 @@
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mark3labs/mcp-go v0.43.2 h1:21PUSlWWiSbUPQwXIJ5WKlETixpFpq+WBpbMGDSVy/I=
github.com/mark3labs/mcp-go v0.43.2/go.mod h1:YnJfOL382MIWDx1kMY+2zsRHU/q78dBg9aFb8W6Thdw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -0,0 +1,172 @@
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"time"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
// Create MCP server
s := server.NewMCPServer(
"parallel-test-server",
"1.0.0",
server.WithToolCapabilities(true),
)
// Register all tools
registerFastOperationTool(s)
registerMediumOperationTool(s)
registerSlowOperationTool(s)
registerVerySlowOperationTool(s)
registerReturnTimestampTool(s)
// Start STDIO server
if err := server.ServeStdio(s); err != nil {
fmt.Fprintf(os.Stderr, "Server error: %v\n", err)
os.Exit(1)
}
}
// ============================================================================
// TOOL 1: fast_operation
// ============================================================================
func registerFastOperationTool(s *server.MCPServer) {
tool := mcp.NewTool("fast_operation",
mcp.WithDescription("Returns immediately (< 10ms)"),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
start := time.Now()
response := map[string]interface{}{
"operation": "fast",
"timestamp": start.UnixNano(),
"message": "Fast operation completed",
}
elapsed := time.Since(start)
response["elapsed_ms"] = float64(elapsed.Nanoseconds()) / 1e6
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 2: medium_operation
// ============================================================================
func registerMediumOperationTool(s *server.MCPServer) {
tool := mcp.NewTool("medium_operation",
mcp.WithDescription("Takes 100-200ms to complete"),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
start := time.Now()
// Sleep for 150ms
time.Sleep(150 * time.Millisecond)
response := map[string]interface{}{
"operation": "medium",
"timestamp": start.UnixNano(),
"message": "Medium operation completed",
}
elapsed := time.Since(start)
response["elapsed_ms"] = float64(elapsed.Nanoseconds()) / 1e6
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 3: slow_operation
// ============================================================================
func registerSlowOperationTool(s *server.MCPServer) {
tool := mcp.NewTool("slow_operation",
mcp.WithDescription("Takes 500-1000ms to complete"),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
start := time.Now()
// Sleep for 750ms
time.Sleep(750 * time.Millisecond)
response := map[string]interface{}{
"operation": "slow",
"timestamp": start.UnixNano(),
"message": "Slow operation completed",
}
elapsed := time.Since(start)
response["elapsed_ms"] = float64(elapsed.Nanoseconds()) / 1e6
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 4: very_slow_operation
// ============================================================================
func registerVerySlowOperationTool(s *server.MCPServer) {
tool := mcp.NewTool("very_slow_operation",
mcp.WithDescription("Takes 2-3 seconds to complete"),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
start := time.Now()
// Sleep for 2.5 seconds
time.Sleep(2500 * time.Millisecond)
response := map[string]interface{}{
"operation": "very_slow",
"timestamp": start.UnixNano(),
"message": "Very slow operation completed",
}
elapsed := time.Since(start)
response["elapsed_ms"] = float64(elapsed.Nanoseconds()) / 1e6
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 5: return_timestamp
// ============================================================================
func registerReturnTimestampTool(s *server.MCPServer) {
tool := mcp.NewTool("return_timestamp",
mcp.WithDescription("Returns high-precision timestamp immediately"),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
now := time.Now()
response := map[string]interface{}{
"timestamp_unix": now.Unix(),
"timestamp_unix_nano": now.UnixNano(),
"timestamp_unix_micro": now.UnixMicro(),
"timestamp_iso8601": now.Format(time.RFC3339Nano),
"message": "Timestamp captured",
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
{
"name": "parallel-test-server",
"version": "1.0.0",
"description": "MCP STDIO server optimized for testing parallel tool execution",
"type": "module",
"bin": {
"parallel-test-server": "./dist/index.js"
},
"scripts": {
"build": "tsc && chmod +x dist/index.js",
"prepare": "npm run build"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.4",
"zod": "^3.24.1"
},
"devDependencies": {
"@types/node": "^20.10.0",
"typescript": "^5.3.3"
},
"overrides": {
"hono": "4.12.14"
}
}

View File

@@ -0,0 +1,177 @@
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
// Schemas for parallel test tools
const FastToolSchema = z.object({
id: z.string().describe("Tool invocation ID"),
});
const SlowToolSchema = z.object({
id: z.string().describe("Tool invocation ID"),
delay_ms: z.number().optional().describe("Delay in milliseconds (default 100)"),
});
const server = new Server(
{ name: "parallel-test-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "fast_tool_1",
description: "Fast tool (10ms delay)",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
},
{
name: "fast_tool_2",
description: "Fast tool (20ms delay)",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
},
{
name: "medium_tool_1",
description: "Medium tool (50ms delay)",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
},
{
name: "medium_tool_2",
description: "Medium tool (75ms delay)",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
},
{
name: "slow_tool_1",
description: "Slow tool (100ms delay)",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
},
{
name: "slow_tool_2",
description: "Slow tool (150ms delay)",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
},
{
name: "variable_delay",
description: "Tool with configurable delay",
inputSchema: {
type: "object",
properties: {
id: { type: "string" },
delay_ms: { type: "number", description: "Delay in milliseconds" },
},
required: ["id"],
},
},
],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const toolName = request.params.name;
const startTime = Date.now();
try {
let delay = 0;
let args: any;
switch (toolName) {
case "fast_tool_1":
args = FastToolSchema.parse(request.params.arguments);
delay = 10;
break;
case "fast_tool_2":
args = FastToolSchema.parse(request.params.arguments);
delay = 20;
break;
case "medium_tool_1":
args = FastToolSchema.parse(request.params.arguments);
delay = 50;
break;
case "medium_tool_2":
args = FastToolSchema.parse(request.params.arguments);
delay = 75;
break;
case "slow_tool_1":
args = FastToolSchema.parse(request.params.arguments);
delay = 100;
break;
case "slow_tool_2":
args = FastToolSchema.parse(request.params.arguments);
delay = 150;
break;
case "variable_delay":
args = SlowToolSchema.parse(request.params.arguments);
delay = args.delay_ms || 100;
break;
default:
throw new Error(`Unknown tool: ${toolName}`);
}
await new Promise((resolve) => setTimeout(resolve, delay));
const elapsed = Date.now() - startTime;
return {
content: [
{
type: "text",
text: JSON.stringify({
tool: toolName,
id: args.id,
delay_ms: delay,
actual_elapsed_ms: elapsed,
completed_at: new Date().toISOString(),
}),
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
});
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Parallel Test MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});

View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}