mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-07-09 04:00:24 +02:00
update dvmcp - fully working now
This commit is contained in:
@ -5,6 +5,7 @@ from config import load_config
|
|||||||
from messages.send_initialize_message import send_initialize
|
from messages.send_initialize_message import send_initialize
|
||||||
from messages.send_ping import send_ping
|
from messages.send_ping import send_ping
|
||||||
from messages.send_tools_list import send_tools_list
|
from messages.send_tools_list import send_tools_list
|
||||||
|
from messages.send_call_tool import send_call_tool
|
||||||
from transport.stdio.stdio_client import stdio_client
|
from transport.stdio.stdio_client import stdio_client
|
||||||
|
|
||||||
# Configure logging
|
# Configure logging
|
||||||
@ -18,7 +19,7 @@ async def main():
|
|||||||
"""Stripped-down script to initialize the server and send a ping."""
|
"""Stripped-down script to initialize the server and send a ping."""
|
||||||
# Configuration values
|
# Configuration values
|
||||||
config_path = "server_config.json"
|
config_path = "server_config.json"
|
||||||
server_name = "Echo"
|
server_name = "nostrdvmmcp"
|
||||||
|
|
||||||
# Load server configuration
|
# Load server configuration
|
||||||
server_params = await load_config(config_path, server_name)
|
server_params = await load_config(config_path, server_name)
|
||||||
@ -44,6 +45,10 @@ async def main():
|
|||||||
result = await send_tools_list(read_stream, write_stream)
|
result = await send_tools_list(read_stream, write_stream)
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
|
result = await send_call_tool("get-crypto-price", {"symbol":"BTC"}, read_stream, write_stream)
|
||||||
|
|
||||||
|
print(result)
|
||||||
|
|
||||||
# Run the script
|
# Run the script
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
anyio.run(main)
|
anyio.run(main)
|
||||||
|
@ -1,19 +1,8 @@
|
|||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"sqlite": {
|
"nostrdvmmcp": {
|
||||||
"command": "uvx",
|
"command": "node",
|
||||||
"args": ["mcp-server-sqlite", "--db-path", "test.db"]
|
"args": ["../../../tests/mcp/nostr_dvmcp_server.js"]
|
||||||
},
|
|
||||||
"Echo": {
|
|
||||||
"command": "uv",
|
|
||||||
"args": [
|
|
||||||
"run",
|
|
||||||
"--with",
|
|
||||||
"mcp[cli]",
|
|
||||||
"mcp",
|
|
||||||
"run",
|
|
||||||
"~/Documents/GitHub/nostrdvm/tests/mcp_server.py"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,7 @@ class MCPBridge(DVMTaskInterface):
|
|||||||
print(c)
|
print(c)
|
||||||
|
|
||||||
content = event.content()
|
content = event.content()
|
||||||
print(c)
|
|
||||||
print(content)
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
"command" : c,
|
"command" : c,
|
||||||
@ -112,9 +111,8 @@ class MCPBridge(DVMTaskInterface):
|
|||||||
return json.dumps(final_tools)
|
return json.dumps(final_tools)
|
||||||
|
|
||||||
|
|
||||||
else:
|
elif options["command"] == "execute-tool":
|
||||||
|
|
||||||
print(options["payload"])
|
|
||||||
ob = json.loads(options["payload"])
|
ob = json.loads(options["payload"])
|
||||||
|
|
||||||
tool_name = ob["name"]
|
tool_name = ob["name"]
|
||||||
@ -162,7 +160,6 @@ class MCPBridge(DVMTaskInterface):
|
|||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print("Ignore the error. We're good.")
|
|
||||||
return alltools
|
return alltools
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,17 +9,6 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"../../mcp-crypto-price/build/index.js"
|
"../../mcp-crypto-price/build/index.js"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"Echo": {
|
|
||||||
"command": "uv",
|
|
||||||
"args": [
|
|
||||||
"run",
|
|
||||||
"--with",
|
|
||||||
"mcp[cli]",
|
|
||||||
"mcp",
|
|
||||||
"run",
|
|
||||||
"tests/mcp/mcp_server.py"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ def playground(announce=False):
|
|||||||
|
|
||||||
# MCP CONFIG
|
# MCP CONFIG
|
||||||
config_path = str(Path.absolute(Path(__file__).parent / "mcp_server_config.json"))
|
config_path = str(Path.absolute(Path(__file__).parent / "mcp_server_config.json"))
|
||||||
server_names = ["Echo", "mcp-crypto-price"]
|
server_names = ["mcp-crypto-price"]
|
||||||
|
|
||||||
|
|
||||||
tools = asyncio.run(get_tools(config_path, server_names))
|
tools = asyncio.run(get_tools(config_path, server_names))
|
||||||
@ -74,7 +74,8 @@ def playground(announce=False):
|
|||||||
capabilities_tag = Tag.parse(["capabilities", "mcp-1.0"])
|
capabilities_tag = Tag.parse(["capabilities", "mcp-1.0"])
|
||||||
t1_tag = Tag.parse(["t","mcp"])
|
t1_tag = Tag.parse(["t","mcp"])
|
||||||
t2_tag = Tag.parse(["t", "bitcoin price"])
|
t2_tag = Tag.parse(["t", "bitcoin price"])
|
||||||
nip89config.EXTRA_TAGS =[capabilities_tag, t1_tag, t2_tag]
|
t3_tag = Tag.parse(["t", "bitcoin analysis"])
|
||||||
|
nip89config.EXTRA_TAGS =[capabilities_tag, t1_tag, t2_tag, t3_tag]
|
||||||
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
@ -62,6 +62,39 @@ const server = new McpServer(config);
|
|||||||
await getnip89s()
|
await getnip89s()
|
||||||
|
|
||||||
|
|
||||||
|
function convertSchemaDefinitionToZod(schemaDefinition) {
|
||||||
|
const zodSchema = {};
|
||||||
|
|
||||||
|
for (const key in schemaDefinition) {
|
||||||
|
const property = schemaDefinition[key];
|
||||||
|
|
||||||
|
let zodProperty;
|
||||||
|
switch (property.type) {
|
||||||
|
case 'string':
|
||||||
|
zodProperty = z.string();
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
zodProperty = z.number();
|
||||||
|
if (property.min !== undefined) zodProperty = zodProperty.min(property.min);
|
||||||
|
if (property.max !== undefined) zodProperty = zodProperty.max(property.max);
|
||||||
|
break;
|
||||||
|
case 'boolean':
|
||||||
|
zodProperty = z.boolean();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
zodProperty = z.any(); // Fallback for unknown types
|
||||||
|
}
|
||||||
|
|
||||||
|
if (property.description) {
|
||||||
|
zodProperty = zodProperty.describe(property.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
zodSchema[key] = zodProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return z.object(zodSchema);
|
||||||
|
}
|
||||||
|
|
||||||
//define getNip89s. Fetch from Nostr and add as tools to server.
|
//define getNip89s. Fetch from Nostr and add as tools to server.
|
||||||
async function getnip89s() {
|
async function getnip89s() {
|
||||||
await loadWasmAsync();
|
await loadWasmAsync();
|
||||||
@ -90,11 +123,8 @@ async function getnip89s() {
|
|||||||
if (tool.inputSchema === undefined || tool.inputSchema.properties === undefined) {
|
if (tool.inputSchema === undefined || tool.inputSchema.properties === undefined) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
const zodSchema = convertSchemaDefinitionToZod(tool.inputSchema.properties);
|
||||||
//TODO convert inputSchema.properties? to zod schema or to any other way so it works.
|
server.tool(tool.name, tool.description, zodSchema.shape,
|
||||||
let inputSchema = {symbol: z.string()}
|
|
||||||
|
|
||||||
server.tool(tool.name, tool.description, inputSchema,
|
|
||||||
async (args) => {
|
async (args) => {
|
||||||
return await handle_dvm_request(args, tool.name, pubkey)
|
return await handle_dvm_request(args, tool.name, pubkey)
|
||||||
});
|
});
|
||||||
@ -123,7 +153,9 @@ async function handle_dvm_request(args, name, pubkey) {
|
|||||||
await client.addRelay(relay);
|
await client.addRelay(relay);
|
||||||
}
|
}
|
||||||
await client.connect();
|
await client.connect();
|
||||||
var relays_list = merge(["relays"], relays)
|
|
||||||
|
const relays_list = ["relays"].concat(relays)
|
||||||
|
|
||||||
|
|
||||||
let tags = [
|
let tags = [
|
||||||
Tag.parse(["c", "execute-tool"]),
|
Tag.parse(["c", "execute-tool"]),
|
||||||
@ -145,15 +177,25 @@ async function handle_dvm_request(args, name, pubkey) {
|
|||||||
|
|
||||||
var result = ""
|
var result = ""
|
||||||
const handle = {
|
const handle = {
|
||||||
handleEvent: async (relayUrl, subscriptionId, event) => {
|
handleEvent: async (relayUrl, subscriptionId, event) =>
|
||||||
//TODO More logic / safety checks
|
{
|
||||||
|
if(event.kind.asU16() === 6910){
|
||||||
|
try {
|
||||||
result = JSON.parse(event.content).content[0].text
|
result = JSON.parse(event.content).content[0].text
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
console.log("Error parsing JSON in event")
|
||||||
|
}
|
||||||
|
|
||||||
abortable.abort()
|
abortable.abort()
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMsg: async (relayUrl, message) => {
|
handleMsg: async (relayUrl, message) =>
|
||||||
//console.log("Received message from", relayUrl, message.asJson());
|
{
|
||||||
|
console.log("Received message from", relayUrl, message.asJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user