import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
GetPromptRequestSchema,
ListPromptsRequestSchema,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{
name: "violett-mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
prompts: {},
resources: {},
},
}
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "fetch_url",
description: "Fetch content from a URL via HTTP GET request",
inputSchema: {
type: "object",
properties: {
url: {
type: "string",
description: "URL to fetch",
},
},
required: ["url"],
},
},
{
name: "post_data",
description: "Send data via HTTP POST request",
inputSchema: {
type: "object",
properties: {
url: {
type: "string",
description: "URL to send POST request to",
},
data: {
type: "object",
description: "Data to send in POST body",
},
},
required: ["url", "data"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
switch (request.params.name) {
case "fetch_url": {
const url = request.params.arguments?.url as string;
if (!url) {
throw new Error("URL is required");
}
try {
const response = await fetch(url);
const content = await response.text();
const headers = Object.fromEntries(response.headers.entries());
return {
content: [
{
type: "text",
text: `HTTP ${response.status} ${response.statusText}\n\nHeaders:\n${JSON.stringify(headers, null, 2)}\n\nBody:\n${content}`,
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error fetching URL: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
}
case "post_data": {
const url = request.params.arguments?.url as string;
const data = request.params.arguments?.data;
if (!url || !data) {
throw new Error("URL and data are required");
}
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
const responseText = await response.text();
const headers = Object.fromEntries(response.headers.entries());
return {
content: [
{
type: "text",
text: `HTTP ${response.status} ${response.statusText}\n\nHeaders:\n${JSON.stringify(headers, null, 2)}\n\nResponse:\n${responseText}`,
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error posting data: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}
});
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: [
{
name: "summarize_url",
description: "Summarize content from a URL",
arguments: [
{
name: "url",
description: "URL to summarize",
required: true,
},
],
},
{
name: "analyze_api",
description: "Analyze API response structure",
arguments: [
{
name: "endpoint",
description: "API endpoint to analyze",
required: true,
},
],
},
],
};
});
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
switch (request.params.name) {
case "summarize_url":
const url = request.params.arguments?.url as string;
return {
description: `Summarize content from ${url}`,
messages: [
{
role: "user",
content: {
type: "text",
text: `Please fetch and summarize the content from this URL: ${url}\n\nUse the fetch_url tool to get the content, then provide a concise summary highlighting the key points.`,
},
},
],
};
case "analyze_api":
const endpoint = request.params.arguments?.endpoint as string;
return {
description: `Analyze API response structure from ${endpoint}`,
messages: [
{
role: "user",
content: {
type: "text",
text: `Please analyze the API response structure from this endpoint: ${endpoint}\n\nUse the fetch_url tool to get the response, then describe the JSON structure, data types, and any patterns you observe.`,
},
},
],
};
default:
throw new Error(`Unknown prompt: ${request.params.name}`);
}
});
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "stream://violett",
name: "Violett Stream",
description: "A streaming resource for Violett server",
mimeType: "text/plain",
},
{
uri: "http://api.violett.com/data",
name: "Violett API Data",
description: "Data from Violett API",
mimeType: "application/json",
},
],
};
});
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri === "stream://violett") {
const data = Array.from({ length: 10 }, (_, i) => `Line ${i + 1}: Streaming data from Violett\n`);
return {
contents: [
{
uri,
mimeType: "text/plain",
text: data.join(""),
},
],
};
}
if (uri.startsWith("http://") || uri.startsWith("https://")) {
try {
const response = await fetch(uri);
const content = await response.text();
return {
contents: [
{
uri,
mimeType: response.headers.get("content-type") || "text/plain",
text: content,
},
],
};
} catch (error) {
throw new Error(`Failed to fetch resource: ${error instanceof Error ? error.message : String(error)}`);
}
}
throw new Error(`Unsupported resource URI: ${uri}`);
});
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Violett MCP Server started successfully");
}
main().catch((error) => {
console.error("Violett MCP Server failed to start:", error);
console.error("Stack trace:", error.stack);
process.exit(1);
});