update dvmcp - fully working now

This commit is contained in:
dbth 2025-02-14 19:24:48 +01:00
parent 792e7ae5d1
commit 3ae8d018d2
6 changed files with 70 additions and 47 deletions

View File

@ -5,6 +5,7 @@ from config import load_config
from messages.send_initialize_message import send_initialize
from messages.send_ping import send_ping
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
# Configure logging
@ -18,7 +19,7 @@ async def main():
"""Stripped-down script to initialize the server and send a ping."""
# Configuration values
config_path = "server_config.json"
server_name = "Echo"
server_name = "nostrdvmmcp"
# Load server configuration
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)
print(result)
result = await send_call_tool("get-crypto-price", {"symbol":"BTC"}, read_stream, write_stream)
print(result)
# Run the script
if __name__ == "__main__":
anyio.run(main)

View File

@ -1,19 +1,8 @@
{
"mcpServers": {
"sqlite": {
"command": "uvx",
"args": ["mcp-server-sqlite", "--db-path", "test.db"]
},
"Echo": {
"command": "uv",
"args": [
"run",
"--with",
"mcp[cli]",
"mcp",
"run",
"~/Documents/GitHub/nostrdvm/tests/mcp_server.py"
]
"nostrdvmmcp": {
"command": "node",
"args": ["../../../tests/mcp/nostr_dvmcp_server.js"]
}
}
}

View File

@ -77,8 +77,7 @@ class MCPBridge(DVMTaskInterface):
print(c)
content = event.content()
print(c)
print(content)
options = {
"command" : c,
@ -112,9 +111,8 @@ class MCPBridge(DVMTaskInterface):
return json.dumps(final_tools)
else:
elif options["command"] == "execute-tool":
print(options["payload"])
ob = json.loads(options["payload"])
tool_name = ob["name"]
@ -162,7 +160,6 @@ class MCPBridge(DVMTaskInterface):
except BaseException as e:
pass
print("Ignore the error. We're good.")
return alltools

View File

@ -9,17 +9,6 @@
"args": [
"../../mcp-crypto-price/build/index.js"
]
},
"Echo": {
"command": "uv",
"args": [
"run",
"--with",
"mcp[cli]",
"mcp",
"run",
"tests/mcp/mcp_server.py"
]
}
}
}

View File

@ -35,7 +35,7 @@ def playground(announce=False):
# MCP CONFIG
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))
@ -74,7 +74,8 @@ def playground(announce=False):
capabilities_tag = Tag.parse(["capabilities", "mcp-1.0"])
t1_tag = Tag.parse(["t","mcp"])
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 = {

View File

@ -62,6 +62,39 @@ const server = new McpServer(config);
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.
async function getnip89s() {
await loadWasmAsync();
@ -90,12 +123,9 @@ async function getnip89s() {
if (tool.inputSchema === undefined || tool.inputSchema.properties === undefined) {
continue
}
//TODO convert inputSchema.properties? to zod schema or to any other way so it works.
let inputSchema = {symbol: z.string()}
server.tool(tool.name, tool.description, inputSchema,
async (args) => {
const zodSchema = convertSchemaDefinitionToZod(tool.inputSchema.properties);
server.tool(tool.name, tool.description, zodSchema.shape,
async (args) => {
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.connect();
var relays_list = merge(["relays"], relays)
const relays_list = ["relays"].concat(relays)
let tags = [
Tag.parse(["c", "execute-tool"]),
@ -145,15 +177,25 @@ async function handle_dvm_request(args, name, pubkey) {
var result = ""
const handle = {
handleEvent: async (relayUrl, subscriptionId, event) => {
//TODO More logic / safety checks
result = JSON.parse(event.content).content[0].text
abortable.abort()
return true
handleEvent: async (relayUrl, subscriptionId, event) =>
{
if(event.kind.asU16() === 6910){
try {
result = JSON.parse(event.content).content[0].text
}
catch {
console.log("Error parsing JSON in event")
}
abortable.abort()
return true
}
},
handleMsg: async (relayUrl, message) => {
//console.log("Received message from", relayUrl, message.asJson());
handleMsg: async (relayUrl, message) =>
{
console.log("Received message from", relayUrl, message.asJson());
}
};