Skip to content

Instantly share code, notes, and snippets.

@teggr
Created July 9, 2025 22:18
Show Gist options
  • Save teggr/971be3acbc97f17769c20a93e127abc9 to your computer and use it in GitHub Desktop.
Save teggr/971be3acbc97f17769c20a93e127abc9 to your computer and use it in GitHub Desktop.
JBang and MCP stdio
{
"inputs": [
{
"type": "promptString",
"id": "perplexity-key",
"description": "Perplexity API Key",
"password": true
}
],
"servers": {
"underpants": {
"type": "stdio",
"command": "jbang",
"args": [
"C:\\Users\\robin\\IdeaProjects\\mcp-api-sdk\\mcp.java"
]
}
}
}
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS io.modelcontextprotocol.sdk:mcp:0.10.0
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.server.transport.StdioServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
import io.modelcontextprotocol.spec.McpSchema.Prompt;
import io.modelcontextprotocol.spec.McpSchema.PromptArgument;
import io.modelcontextprotocol.spec.McpSchema.PromptMessage;
import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
import io.modelcontextprotocol.spec.McpSchema.Resource;
import io.modelcontextprotocol.spec.McpSchema.ResourceContents;
import io.modelcontextprotocol.spec.McpSchema.Role;
import io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;
import io.modelcontextprotocol.spec.McpSchema.TextContent;
import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
import io.modelcontextprotocol.spec.McpSchema.Tool;
/**
* https://code.visualstudio.com/docs/copilot/chat/mcp-servers
* https://code.visualstudio.com/mcp
*/
public class mcp {
private static final Logger log = LoggerFactory.getLogger(mcp.class);
public static void main(String... args) {
log.info("starting my mcp service");
StdioServerTransportProvider transportProvider
= new StdioServerTransportProvider(new ObjectMapper());
McpSyncServer syncServer = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(false, true)
.tools(true)
.prompts(true)
// .logging()
// .completions()
.build())
.build();
String schema = """
{
"type" : "object",
"id" : "urn:jsonschema:Operation",
"properties" : {}
}
""";;
var syncToolSpecification = new McpServerFeatures.SyncToolSpecification(
new Tool("funny", "captain underpants facts.", schema),
(exchange,arguments) -> {
log.info("my tool has been called");
// tool impl
return new CallToolResult("he is really mr krupps", false);
});
syncServer.addTool(syncToolSpecification);
// Sync resource specification
var syncResourceSpecification = new McpServerFeatures.SyncResourceSpecification(
new Resource("jokes", "captain underpants jokes", "a list of captain underpants jokes", "text/plain", null),
(exchange, request) -> {
log.info("my resource has been accessedd");
List<ResourceContents> contents = new ArrayList<>();
contents.add(new TextResourceContents("joke1", "text/plain", "knock knock"));
contents.add(new TextResourceContents("joke2", "text/plain", "waitier watier"));
// Resource read implementation
return new ReadResourceResult(contents);
}
);
syncServer.addResource(syncResourceSpecification);
// Sync prompt specification
var syncPromptSpecification = new McpServerFeatures.SyncPromptSpecification(
new Prompt("greeting", "a prompt for sending greetings", List.of(
new PromptArgument("name", "name of the person to send greetings to", true)
)),
(exchange, request) -> {
log.info("my rpomt has been accessedd");
List<PromptMessage> messages = new ArrayList<>();
messages.add(new PromptMessage(
Role.USER,
new TextContent( "talk about flowers")
));
// Prompt implementation
return new GetPromptResult("prompt for another greeting", messages);
}
);
syncServer.addPrompt(syncPromptSpecification);
log.info("Hello World");
// Add shutdown hook to close the server gracefully
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
syncServer.close();
log.info("Server stopped.");
}));
log.info("waiting for requests");
// Block main thread to keep the server running as a daemon
Object lock = new Object();
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e) {
// Exit on interrupt
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment