Repository navigation
Expand file tree
/
Copy pathnative-tool-plugin.mjs
More file actions
114 lines (100 loc) · 2.59 KB
/
Copy pathnative-tool-plugin.mjs
File metadata and controls
114 lines (100 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Minimal WebCodex Native Tool Plugin. No MCP SDK and no third-party package.
// Protocol: one JSON-RPC 2.0 request/response per line on stdin/stdout.
import readline from "node:readline";
const PROTOCOL_VERSION = "webcodex-plugin-v1";
const tools = [
{
name: "echo",
description: "Echo one string",
inputSchema: {
type: "object",
properties: { text: { type: "string" } },
required: ["text"],
additionalProperties: false,
},
},
{
name: "add",
description: "Add two numbers",
inputSchema: {
type: "object",
properties: {
a: { type: "number" },
b: { type: "number" },
},
required: ["a", "b"],
additionalProperties: false,
},
},
];
function send(message) {
process.stdout.write(`${JSON.stringify(message)}\n`);
}
function result(id, value) {
send({ jsonrpc: "2.0", id, result: value });
}
function rpcError(id, code, message) {
send({ jsonrpc: "2.0", id, error: { code, message } });
}
function textResult(text, structuredContent) {
return {
content: [{ type: "text", text }],
structuredContent,
isError: false,
};
}
const input = readline.createInterface({
input: process.stdin,
crlfDelay: Infinity,
terminal: false,
});
input.on("line", (line) => {
let request;
try {
request = JSON.parse(line);
} catch {
// stdout is protocol-only. Local diagnostics belong on stderr.
console.error("received malformed JSON");
return;
}
const { id, method, params = {} } = request;
if (request.jsonrpc !== "2.0" || id === undefined) {
rpcError(id ?? null, -32600, "invalid request");
return;
}
if (method === "initialize") {
if (params.protocolVersion !== PROTOCOL_VERSION) {
rpcError(id, -32602, "unsupported protocol version");
return;
}
result(id, { protocolVersion: PROTOCOL_VERSION });
return;
}
if (method === "tools/list") {
result(id, { tools });
return;
}
if (method === "tools/call") {
const args = params.arguments ?? {};
if (params.name === "echo" && typeof args.text === "string") {
result(id, textResult(args.text, { text: args.text }));
return;
}
if (
params.name === "add" &&
typeof args.a === "number" &&
typeof args.b === "number"
) {
const sum = args.a + args.b;
result(id, textResult(String(sum), { sum }));
return;
}
result(id, {
content: [{ type: "text", text: "unknown tool or invalid arguments" }],
structuredContent: {},
isError: true,
});
return;
}
rpcError(id, -32601, "method not found");
});