Add examples and bundler
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target/
|
||||
18
LICENSE
Normal file
18
LICENSE
Normal file
@@ -0,0 +1,18 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 shahondin1624
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
### Building the project
|
||||
|
||||
To build the project and generate the fat JAR and binaries, run:
|
||||
```bash
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
### Generated Artifacts
|
||||
|
||||
After a successful build, you can find the following artifacts in the `target/` directory:
|
||||
- `mcp-server-app-all.jar`: Executable fat JAR containing all dependencies.
|
||||
- `mcp-server-app`: Linux executable wrapper script.
|
||||
- `mcp-server-app.exe`: Windows executable (console application).
|
||||
|
||||
### Running the server
|
||||
|
||||
Using the fat JAR:
|
||||
```bash
|
||||
java -jar target/mcp-server-app-all.jar
|
||||
```
|
||||
|
||||
Using the Linux executable:
|
||||
```bash
|
||||
./target/mcp-server-app
|
||||
```
|
||||
|
||||
The server will start on port `8080`.
|
||||
|
||||
### MCP Configuration
|
||||
This server is available using
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"test": {
|
||||
"command": "java",
|
||||
"args": ["-jar", "/path/to/mcp-server-app-all.jar"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
or via HTTP:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"test": {
|
||||
"url": "http://127.0.0.1:8080/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
as mcp config.
|
||||
144
pom.xml
Normal file
144
pom.xml
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>mcp.app</groupId>
|
||||
<artifactId>mcp-server-app</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.github.mcp-java</groupId>
|
||||
<artifactId>mcp-server-lib</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging implementation -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.objecthunter</groupId>
|
||||
<artifactId>exp4j</artifactId>
|
||||
<version>0.4.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.shahondin1624</groupId>
|
||||
<artifactId>knowledge-graph</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<mainClass>mcp.app.McpLauncher</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<finalName>mcp-server-app-all</finalName>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>mcp.app.McpLauncher</mainClass>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.akathist.maven.plugins.launch4j</groupId>
|
||||
<artifactId>launch4j-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>l4j-clui</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>launch4j</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<headerType>console</headerType>
|
||||
<jar>${project.build.directory}/mcp-server-app-all.jar</jar>
|
||||
<outfile>${project.build.directory}/mcp-server-app.exe</outfile>
|
||||
<downloadUrl>http://java.com/download</downloadUrl>
|
||||
<classPath>
|
||||
<mainClass>mcp.app.McpLauncher</mainClass>
|
||||
</classPath>
|
||||
<jre>
|
||||
<minVersion>21</minVersion>
|
||||
<runtimeBits>64</runtimeBits>
|
||||
</jre>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<echo file="${project.build.directory}/mcp-server-app">#!/bin/sh
|
||||
# Linux wrapper script for mcp-server-app
|
||||
java -jar "$(dirname "$0")/mcp-server-app-all.jar" "$@"
|
||||
</echo>
|
||||
<chmod file="${project.build.directory}/mcp-server-app" perm="755" />
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
49
src/main/java/mcp/app/McpLauncher.java
Normal file
49
src/main/java/mcp/app/McpLauncher.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package mcp.app;
|
||||
|
||||
import de.shahondin1624.knowledgegraph.DatabaseLauncher;
|
||||
import mcp.server.McpServlet;
|
||||
import mcp.server.ToolRegistrationServlet;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class McpLauncher {
|
||||
private static final Logger logger = LoggerFactory.getLogger(McpLauncher.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
logger.info("Starting MCP App Launcher...");
|
||||
new DatabaseLauncher().start();
|
||||
|
||||
// Scan both library tools and app tools
|
||||
Set<String> classpaths = Stream.concat(
|
||||
Stream.of("mcp.tools", "mcp.app.tools", "de.shahondin1624.knowledgegraph.tooling"),
|
||||
args.length > 0 ? Stream.of(args[0].split(",")) : Stream.empty()
|
||||
).collect(Collectors.toSet());
|
||||
|
||||
logger.debug("Configured classpaths: {}", classpaths);
|
||||
|
||||
McpServlet mcpServlet = new McpServlet(classpaths);
|
||||
mcpServlet.setServerName("mcp-app-server");
|
||||
|
||||
Server server = new Server(8080);
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
|
||||
ServletHolder mcpHolder = new ServletHolder(mcpServlet);
|
||||
context.addServlet(mcpHolder, "/mcp/*");
|
||||
|
||||
ServletHolder registrationHolder = new ServletHolder(new ToolRegistrationServlet(mcpServlet.getToolRegistry()));
|
||||
context.addServlet(registrationHolder, "/mcp/register");
|
||||
|
||||
server.start();
|
||||
logger.info("MCP App Server started on port 8080");
|
||||
server.join();
|
||||
}
|
||||
}
|
||||
57
src/main/java/mcp/app/tools/CalculatorTool.java
Normal file
57
src/main/java/mcp/app/tools/CalculatorTool.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package mcp.app.tools;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import mcp.tools.DefaultMcpTool;
|
||||
import mcp.tools.McpValidatedTool;
|
||||
import mcp.tools.helper.SchemaBuilder;
|
||||
import net.objecthunter.exp4j.Expression;
|
||||
import net.objecthunter.exp4j.ExpressionBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@DefaultMcpTool
|
||||
public class CalculatorTool extends McpValidatedTool {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CalculatorTool.class);
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "calculator";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String title() {
|
||||
return "Calculator Tool";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Evaluates a mathematical expression. Supports basic operators (+, -, *, /), functions (sin, cos, tan, log, exp), and parentheses.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public McpSchema.JsonSchema inputSchema() {
|
||||
return new SchemaBuilder()
|
||||
.addProperty("expression", "string", "The mathematical expression to evaluate")
|
||||
.required("expression")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> outputSchema() {
|
||||
return new SchemaBuilder()
|
||||
.returns("number", "The result of the evaluation")
|
||||
.buildMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public McpSchema.CallToolResult callValidated(McpSchema.CallToolRequest request, Map<String, Object> arguments) {
|
||||
String expressionStr = (String) arguments.get("expression");
|
||||
logger.debug("Evaluating expression: {}", expressionStr);
|
||||
|
||||
Expression expression = new ExpressionBuilder(expressionStr).build();
|
||||
double result = expression.evaluate();
|
||||
return success(String.valueOf(result));
|
||||
}
|
||||
}
|
||||
60
src/main/java/mcp/app/tools/CurrentDateTimeTool.java
Normal file
60
src/main/java/mcp/app/tools/CurrentDateTimeTool.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package mcp.app.tools;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import mcp.tools.DefaultMcpTool;
|
||||
import mcp.tools.McpValidatedTool;
|
||||
import mcp.tools.helper.SchemaBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple tool that returns the current date and time.
|
||||
*/
|
||||
@DefaultMcpTool
|
||||
public class CurrentDateTimeTool extends McpValidatedTool {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CurrentDateTimeTool.class);
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "current_date_time";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String title() {
|
||||
return "Current Date and Time Tool";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Returns the current date and time on the server";
|
||||
}
|
||||
|
||||
@Override
|
||||
public McpSchema.JsonSchema inputSchema() {
|
||||
return new SchemaBuilder()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> outputSchema() {
|
||||
return new SchemaBuilder()
|
||||
.returns("string", "The current date and time in ISO-8601 format")
|
||||
.buildMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIdempotent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public McpSchema.CallToolResult callValidated(McpSchema.CallToolRequest request, Map<String, Object> arguments) {
|
||||
String now = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
||||
logger.info("CurrentDateTimeTool called, returning: {}", now);
|
||||
return success(now);
|
||||
}
|
||||
}
|
||||
55
src/main/java/mcp/app/tools/EchoTool.java
Normal file
55
src/main/java/mcp/app/tools/EchoTool.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package mcp.app.tools;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import mcp.tools.DefaultMcpTool;
|
||||
import mcp.tools.McpValidatedTool;
|
||||
import mcp.tools.helper.SchemaBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple tool that echoes back the input message.
|
||||
*/
|
||||
@DefaultMcpTool()
|
||||
public class EchoTool extends McpValidatedTool {
|
||||
private static final Logger logger = LoggerFactory.getLogger(EchoTool.class);
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "echo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String title() {
|
||||
return "Echo Tool";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Echoes back the input message";
|
||||
}
|
||||
|
||||
@Override
|
||||
public McpSchema.JsonSchema inputSchema() {
|
||||
return new SchemaBuilder()
|
||||
.addProperty("message", "string", "The message to echo")
|
||||
.required("message")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> outputSchema() {
|
||||
return new SchemaBuilder()
|
||||
.returns("string", "The echoed message")
|
||||
.buildMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public McpSchema.CallToolResult callValidated(McpSchema.CallToolRequest request, Map<String, Object> arguments) {
|
||||
String message = (String) arguments.get("message");
|
||||
logger.debug("EchoTool called with message: {}", message);
|
||||
return success(message);
|
||||
}
|
||||
}
|
||||
1
src/main/resources/simplelogger.properties
Normal file
1
src/main/resources/simplelogger.properties
Normal file
@@ -0,0 +1 @@
|
||||
org.slf4j.simpleLogger.defaultLogLevel=info
|
||||
Reference in New Issue
Block a user