Skip to content

Commit af7bd0c

Browse files
committed
Update README.md
1 parent 31fc412 commit af7bd0c

File tree

3 files changed

+208
-73
lines changed

3 files changed

+208
-73
lines changed

DEVELOPING_TOOLS.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Developing MCP Tools for tinystruct-mcp
2+
3+
This guide explains how to extend the tinystruct-mcp server by developing your own MCP tools using the modern `@Action` annotation pattern.
4+
5+
---
6+
7+
## 1. Create a Custom Tool
8+
9+
To add new functionality, create a class that extends `MCPTool` and use `@Action` annotations for each operation:
10+
11+
```java
12+
import org.tinystruct.mcp.MCPTool;
13+
import org.tinystruct.data.component.Builder;
14+
import org.tinystruct.system.annotation.Action;
15+
import org.tinystruct.system.annotation.Argument;
16+
17+
public class EchoTool extends MCPTool {
18+
19+
/**
20+
* Constructs a new EchoTool with local execution support.
21+
*/
22+
public EchoTool() {
23+
// Note the true parameter at the end to enable local execution
24+
super("echo", "A tool that echoes back input");
25+
}
26+
27+
/**
28+
* Constructs a new EchoTool with a client.
29+
*
30+
* @param client The MCP client
31+
*/
32+
public EchoTool(MCPClient client) {
33+
// Note the true parameter at the end to enable local execution
34+
super("echo", "A tool that echoes back input", null, client, true);
35+
}
36+
37+
/**
38+
* Echoes back the input message.
39+
* @param message The message to echo
40+
* @return The echoed message
41+
*/
42+
@Action(value = "echo/message", description = "Echo back the input message", arguments = {
43+
@Argument(key = "message", description = "The message to echo", type = "string")
44+
})
45+
public String echoMessage(String message) {
46+
return message;
47+
}
48+
49+
/**
50+
* Echoes back the input with a prefix.
51+
* @param message The message to echo
52+
* @param prefix The prefix to add
53+
* @return The prefixed message
54+
*/
55+
@Action(value = "echo/with-prefix", description = "Echo back the input with a prefix", arguments = {
56+
@Argument(key = "message", description = "The message to echo", type = "string"),
57+
@Argument(key = "prefix", description = "The prefix to add", type = "string")
58+
})
59+
public String echoWithPrefix(String message, String prefix) {
60+
return prefix + ": " + message;
61+
}
62+
}
63+
```
64+
65+
---
66+
67+
## 2. Register Your Tool in the Server
68+
69+
In your server class (extending `MCPServerApplication`), register your tool in the `init()` method:
70+
71+
```java
72+
public class MyMCPServer extends MCPServerApplication {
73+
@Override
74+
public void init() {
75+
super.init();
76+
this.registerToolMethods(new EchoTool());
77+
// Register other tools or prompts as needed
78+
}
79+
}
80+
```
81+
82+
---
83+
84+
## 3. Key Features of Modern MCP Tools
85+
86+
### Constructor Pattern
87+
- **Default constructor**: `super("tool-name", "Tool description")` enables local execution
88+
- **Client constructor**: `super("tool-name", "Tool description", null, client, true)` for client-based execution
89+
90+
### @Action Annotations
91+
- **Automatic schema generation**: No need to manually build schemas
92+
- **Method-based operations**: Each `@Action` method becomes a separate tool operation
93+
- **Parameter validation**: `@Argument` annotations define parameter types and descriptions
94+
95+
### Automatic Features
96+
- **Name and description**: Set in constructor, no need to override `getName()` or `getDescription()`
97+
- **Schema generation**: Built automatically from `@Action` and `@Argument` annotations
98+
- **Local execution**: Enabled by default for better performance
99+
100+
---
101+
102+
## 4. Add Custom Prompts (Optional)
103+
104+
You can also register prompts for user interaction or automation:
105+
106+
```java
107+
Builder promptSchema = new Builder();
108+
Builder properties = new Builder();
109+
Builder nameParam = new Builder();
110+
nameParam.put("type", "string");
111+
nameParam.put("description", "The name to greet");
112+
properties.put("name", nameParam);
113+
promptSchema.put("type", "object");
114+
promptSchema.put("properties", properties);
115+
promptSchema.put("required", new String[]{"name"});
116+
117+
MCPPrompt greetingPrompt = new MCPPrompt(
118+
"greeting",
119+
"A greeting prompt",
120+
"Hello, {{name}}!",
121+
promptSchema,
122+
null
123+
) {
124+
@Override
125+
protected boolean supportsLocalExecution() { return true; }
126+
};
127+
this.registerPrompt(greetingPrompt);
128+
```
129+
130+
---
131+
132+
## 5. Best Practices
133+
134+
### Tool Design
135+
- **Single responsibility**: Each tool should focus on one domain (e.g., file operations, Git operations)
136+
- **Consistent naming**: Use `tool-name/operation` format for action values
137+
- **Clear descriptions**: Provide helpful descriptions for tools and arguments
138+
- **Error handling**: Wrap internal operations in try-catch blocks
139+
140+
### Method Structure
141+
```java
142+
@Action(value = "tool/operation", description = "What this operation does", arguments = {
143+
@Argument(key = "param1", description = "Description of param1", type = "string"),
144+
@Argument(key = "param2", description = "Description of param2", type = "number")
145+
})
146+
public ReturnType operationName(String param1, int param2) throws MCPException {
147+
try {
148+
// Implementation logic here
149+
return result;
150+
} catch (Exception e) {
151+
LOGGER.log(Level.SEVERE, "Error in operation: " + e.getMessage(), e);
152+
throw new MCPException("Error in operation: " + e.getMessage());
153+
}
154+
}
155+
```
156+
157+
### Parameter Types
158+
- **string**: Text values
159+
- **number**: Numeric values (int, double, etc.)
160+
- **boolean**: True/false values
161+
- **object**: Complex objects (use Builder)
162+
163+
---
164+
165+
## 6. Recommended Workflow
166+
167+
1. **Extend `MCPServerApplication`** and implement the `init()` method
168+
2. **Create tool class** extending `MCPTool` with proper constructors
169+
3. **Add `@Action` methods** for each operation with `@Argument` annotations
170+
4. **Register tools** using `registerToolMethods()` in `init()`
171+
5. **Optionally register prompts** for user interaction
172+
6. **Start the server** via Java or CLI
173+
7. **Configure** via properties or `Settings`
174+
175+
---
176+
177+
## 7. Example: Complete Calculator Tool
178+
179+
```java
180+
public class CalculatorTool extends MCPTool {
181+
182+
public CalculatorTool() {
183+
super("calculator", "A calculator that performs arithmetic operations");
184+
}
185+
186+
public CalculatorTool(MCPClient client) {
187+
super("calculator", "A calculator that performs arithmetic operations", null, client, true);
188+
}
189+
190+
@Action(value = "calculator/add", description = "Add two numbers", arguments = {
191+
@Argument(key = "a", description = "The first operand", type = "number"),
192+
@Argument(key = "b", description = "The second operand", type = "number")
193+
})
194+
public double add(double a, double b) {
195+
return a + b;
196+
}
197+
198+
@Action(value = "calculator/multiply", description = "Multiply two numbers", arguments = {
199+
@Argument(key = "a", description = "The first operand", type = "number"),
200+
@Argument(key = "b", description = "The second operand", type = "number")
201+
})
202+
public double multiply(double a, double b) {
203+
return a * b;
204+
}
205+
}
206+
```
207+
208+
**MCP stands for Model Context Protocol.**

README.md

5.37 KB

tinystruct-mcp

tinystruct-mcp is a modular Java server framework based on Tinystruct, providing built-in tools for file system and GitHub operations via the Model Context Protocol (MCP). It's designed for easy integration, automation, and extensibility in modern DevOps and AI-driven workflows.


Quick Start

1. Start the MCP Server

Java (Programmatic Startup)

import org.tinystruct.ApplicationContext;
import org.tinystruct.application.Context;
import org.tinystruct.system.ApplicationManager;
import org.tinystruct.system.Settings;
import org.tinystruct.system.TomcatServer;

public class Main {
    public static void main(String[] args) {
        Context ctx = new ApplicationContext();
        ctx.setAttribute("--server-port", "8080");
        ApplicationManager.install(new org.tinystruct.mcp.GitHub());
        ApplicationManager.install(new org.tinystruct.mcp.FileSystem());
        ApplicationManager.install(new TomcatServer());
        ApplicationManager.call("start", ctx);
    }
}

CLI (Recommended for Most Users)

If you have the bin/dispatcher script (from the Tinystruct distribution), you can start the server directly from the command line:

To start the server with the built-in GitHub and FileSystem modules:

bin/dispatcher start --import org.tinystruct.system.TomcatServer --import org.tinystruct.mcp.GitHub --import org.tinystruct.mcp.FileSystem --server-port 777 
  • You can add or remove imports to customize which modules and tools are loaded.

Built-in Tools

GitHub Tool

Provides Git and GitHub API operations:

  • Clone repositories: github/clone
  • Pull changes: github/pull
  • Push changes: github/push
  • Check status: github/status
  • Get issues: github/issues
  • Get pull requests: github/prs
  • Get workflows: github/actions

FileSystem Tool

Provides file system operations:

  • Get file info: filesystem/info
  • Check existence: filesystem/exists
  • Get file size: filesystem/size
  • List directory: filesystem/list
  • Read file: filesystem/read
  • Write file: filesystem/write
  • Copy file: filesystem/copy
  • Move file: filesystem/move
  • Delete file: filesystem/delete
  • Create directory: filesystem/mkdir

Configuration

Configure the server using a properties file or by setting values in the Settings object:

# Example: mcp.properties
mcp.auth.token=your-secret-token

More Advanced Usage

To learn how to develop your own MCP tools and extend the server, see DEVELOPING_TOOLS.md.

MCP stands for Model Context Protocol.

github/bin/dispatcher.cmd

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)