Separating server files
This commit is contained in:
14
README.md
14
README.md
@@ -1,6 +1,18 @@
|
||||
# TSMCP
|
||||
|
||||
|
||||
## Config file must be a json in format:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"serverName": {
|
||||
"command": "node",
|
||||
"args": [
|
||||
"C:\\PATH\\TO\\PARENT\\FOLDER\\servername\\build\\index.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## use inspector to test mcp server
|
||||
https://www.npmjs.com/package/@modelcontextprotocol/inspector
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"type": "module",
|
||||
|
||||
"scripts": {
|
||||
"inspector": "npx @modelcontextprotocol/inspector tsx src/main.ts"
|
||||
},
|
||||
@@ -8,6 +9,8 @@
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsx": "^4.19.3"
|
||||
"@types/node": "^22.14.0",
|
||||
"tsx": "^4.19.3",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
5
src/config/servers.json
Normal file
5
src/config/servers.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
|
||||
}
|
||||
}
|
||||
63
src/main.ts
63
src/main.ts
@@ -1,5 +1,7 @@
|
||||
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import { MCPTools } from "@tools/MCPTools.js";
|
||||
import { ollamaTool } from "@tools/ollama.tool.js";
|
||||
import { z } from "zod";
|
||||
|
||||
// Create an MCP server
|
||||
@@ -8,6 +10,8 @@ const server = new McpServer({
|
||||
version: "1.0.0"
|
||||
});
|
||||
|
||||
const serverTools = new MCPTools(server);
|
||||
|
||||
// Add an addition tool
|
||||
server.tool("add",
|
||||
{ a: z.number(), b: z.number() },
|
||||
@@ -16,66 +20,9 @@ server.tool("add",
|
||||
})
|
||||
);
|
||||
|
||||
// Adiciona uma ferramenta que se comunica com o Ollama
|
||||
server.tool("ollama",
|
||||
{
|
||||
prompt: z.string(),
|
||||
model: z.string().default("llama3"),
|
||||
options: z.object({
|
||||
temperature: z.number().min(0).max(2).optional().default(0.7),
|
||||
max_tokens: z.number().optional().default(500)
|
||||
}).optional().default({})
|
||||
},
|
||||
async ({ prompt, model, options }) => {
|
||||
try {
|
||||
console.log(`Enviando para Ollama: modelo=${model}, prompt="${prompt.substring(0, 30)}..."`);
|
||||
serverTools.registerTool(ollamaTool)
|
||||
|
||||
// A API do Ollama espera os parâmetros no corpo da solicitação
|
||||
// e não dentro de um objeto options separado
|
||||
const response = await fetch("http://localhost:11434/api/generate", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model,
|
||||
prompt: prompt,
|
||||
stream: false,
|
||||
temperature: options.temperature,
|
||||
num_predict: options.max_tokens
|
||||
// Remova o objeto options aninhado
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
console.error(`Erro na resposta do Ollama: ${error}`);
|
||||
return {
|
||||
content: [{ type: "text", text: `Erro ao chamar Ollama: ${error}` }]
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log("Resposta recebida do Ollama");
|
||||
|
||||
if (!data.response) {
|
||||
console.error("Formato de resposta inesperado:", data);
|
||||
return {
|
||||
content: [{ type: "text", text: `Erro: formato de resposta inesperado do Ollama` }]
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: data.response }]
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Erro na comunicação com Ollama:`, error);
|
||||
return {
|
||||
content: [{ type: "text", text: `Erro ao conectar com Ollama: ${error.message}` }]
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Add a dynamic greeting resource
|
||||
server.resource(
|
||||
|
||||
19
src/server/mcpServer.ts
Normal file
19
src/server/mcpServer.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import { version } from "os";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
const server = new McpServer({
|
||||
name: "DatabaseServer",
|
||||
version: "0.0.1",
|
||||
capabilities: {
|
||||
resources: {},
|
||||
tools: {}
|
||||
}
|
||||
})
|
||||
|
||||
async function main() {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.co
|
||||
}
|
||||
20
src/tools/MCPTools.ts
Normal file
20
src/tools/MCPTools.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
|
||||
export class MCPTools {
|
||||
|
||||
constructor(private readonly server: McpServer) {
|
||||
|
||||
}
|
||||
|
||||
registerTool(toolFactory: () => { name: string, schema: any, handler: any }) {
|
||||
const tool = toolFactory();
|
||||
this.server.tool(tool.name, tool.schema, tool.handler);
|
||||
}
|
||||
|
||||
removeTool() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
0
src/tools/add.ts
Normal file
0
src/tools/add.ts
Normal file
64
src/tools/ollama.tool.ts
Normal file
64
src/tools/ollama.tool.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import {z} from "zod"
|
||||
|
||||
export function ollamaTool() {
|
||||
return {
|
||||
name: "ollama",
|
||||
schema: {
|
||||
prompt: z.string(),
|
||||
model: z.string().default("gemma3:4b"),
|
||||
options: z.object({
|
||||
temperature: z.number().min(0).max(2).optional().default(0.7),
|
||||
max_tokens: z.number().optional().default(4000)
|
||||
}).optional().default({})
|
||||
},
|
||||
handler: async ({ prompt, model, options }, extra) => {
|
||||
try {
|
||||
console.log(`Enviando para Ollama: modelo=${model}, prompt="${prompt.substring(0, 30)}..."`);
|
||||
|
||||
const response = await fetch("http://localhost:11434/api/generate", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model,
|
||||
prompt: prompt,
|
||||
stream: false,
|
||||
temperature: options.temperature,
|
||||
num_predict: options.max_tokens
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
console.error(`Erro na resposta do Ollama: ${error}`);
|
||||
return {
|
||||
content: [{ type: "text" as const, text: `Erro ao chamar Ollama: ${error}` }]
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log("Resposta recebida do Ollama");
|
||||
|
||||
if (!data.response) {
|
||||
console.error("Formato de resposta inesperado:", data);
|
||||
return {
|
||||
content: [{ type: "text" as const, text: `Erro: formato de resposta inesperado do Ollama` }]
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{
|
||||
type: "text" as const,
|
||||
text: data.response
|
||||
}]
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Erro na comunicação com Ollama:`, error);
|
||||
return {
|
||||
content: [{ type: "text" as const, text: `Erro ao conectar com Ollama: ${error.message}` }]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
src/tools/remove.ts
Normal file
0
src/tools/remove.ts
Normal file
@@ -1,5 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "ESNext"
|
||||
"target": "ES2022",
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"baseUrl": ".",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./build",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"@tools/*": ["src/tools/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user