Gzuuus's avatar
Gzuuus
gzuuus@nostree.me
npub1gzuu...a5ds
Forever learning, continuously buidlingโšก cryptoanarchism student https://nostree.me/gzuuus #noderunner#Bitcoin | #technology | #art | #electronics
Gzuuus's avatar
Gzuuus 8 months ago
Doing crazy stuff ๐Ÿ‘€
Gzuuus's avatar
Gzuuus 8 months ago
A week or so ago, @Alex Gleason presented me with a challenge: how we can request user input using MCP servers, so that a chat client like Goose or any other could dynamically request that information from the user to proceed with the tool call and its result. This would be something like 'Question MCP', which allows the agent to prompt questions back to the user. This is a novel feature that few clients implement, as there was no clear way to do this without a custom client, which is undesirable due to vendor lock-in. The solution lies in a protocol-specific feature RooCode and Cline have this feature, but it is specific to their clients. It works by providing some built-in tools to the LLMs, along with prompt engineering in the system prompts that instruct the LLMs to eventually request input from the user. While this works, it is not an ideal solution because it is client-specific. To replicate the same behavior in a different client, you would need some sort of 'Feedback MCP' with tools like ask_user, ask_user_confirmation, etc. and you would need to tweak system prompts to make it work, which is not desirable neithe. The solution lies in a protocol-specific feature from MCP, a standardized way for servers to request additional information from users through the client during interactions. Fortunately, this is something that has already been thought about and proposed in different pull requests in the MCP spec repo. This feature is called 'Elicitation', and it is currently a draft in the MCP protocol spec. It was introduced as a draft just a few days before Alex and I started our conversation about this, making it a bleeding-edge feature with no current support and only a pull request in the MCP TypeScript SDK that has not been merged yet. The challenge was clear now: implement Elicitation in an MCP server and a client that handles it to demonstrate how it works. I did it, and as a result, I created a mcp-chat TUI program, which, to my knowledge, is the only chat MCP client implementing this feature. If you are interested in understanding how I made it, feel free to ask; I'll happily respond and comment on the challenges and obstacles I encountered and how I resolved them. However, I want to reflect more on the Elicitation feature and what it allows. This is very interesting: MCP servers can require information when executing tools, without the client needing to do anything other than handle it in their own ui. This opens up a plethora of possibilities for dynamic tools requiring data from their users. For example, tools that handle uncertainty, like a 'Book a Table' tool, where if the tool cannot find a suitable table, it can ask the user what to do, whether to take any available table or cancel the process. This has various implications: it makes the process more intuitive, robust, dynamic, and, importantly, more private. Since the LLM doesn't need to be aware of the details that the user inputs, in the previous example, the 'Book a Table' tool could request through Elicitation details like the user's name, email, phone, or any other required information to complete the process. This is a direct communication between the user and the MCP server. Once the Elicitation is complete, the tool returns the result, feeding it back to the LLM, omitting the personal details and simply saying, 'The table was successfully booked for 1 PM at The Awesome Restaurant.' Then, the LLM and the user can continue their chat if desired. At no point does the LLM need to know the details of the user to book the table, as those details are something between the user and the MCP server. The LLM is only present when the user requests in natural language to call the 'Book a Table' tool and when the 'Book a Table' tool returns its result. This is very cool. I could keep talking about this, but I'll stop here, as this is not supposed to be a long-form content piece. But if you are interested in any of this stuff, feel free to AMA! I'm going to drop some related links: MCP-chat: Elicitation spec: Introduce Elicitation capability PR: #mcp #llm #ai
Gzuuus's avatar
Gzuuus 8 months ago
GM! Let's go with the Saturday! ๐Ÿš€ I may have some interesting stuff to share with you today. My head is full of ideas, I could barely sleep last night ๐Ÿ˜…
Gzuuus's avatar
Gzuuus 8 months ago
Recently, I started implementing encryption in dvmcp using NIP-17, which utilizes NIP-59 (gift wraps). Gift wraps have always been criticized for being spammy, as there is no way to limit the spam factor by filtering or performing other spam prevention stuff. This is because gift wraps do not reveal any information; they can be anything, making them an unlimited spam attack vector. As a result, just a limited amount of relays accept them. This is why you need specialized relays to use NIP-17 successfully. As far as I know, there aren't many, with 0xchat relay being one of the most specialized. When considering how to integrate gift wraps into the relay behind dvmcp.fun (which is public and accessible to everyone but not a general use relay), I thought the best way to handle them, given the ephemeral nature of dvmcp messages, would be to use the same concept of ring buffer storage I created specifically to handle ephemeral events. This way, I could receive as many gift wrap events as needed without polluting the relay's database. The events would automatically and efficiently evict themselves when the ring buffer's limit is reached. Ring buffers are quite interesting. They have a limited capacity, and when they reach their maximum capacity, they start to overwrite entries, typically in a FIFO (First In, First Out) manner. The oldest entries are overwritten by the newest incoming ones. This means the first entry in a ring buffer will be overwritten when the limit is reached by the first entry that surpasses that limit. This is useful because, knowing the frequency of the messages you are receiving, you can roughly estimate how long an entry will stay in the buffer. You can ensure a time-to-live (TTL) by increasing or decreasing the size of the buffer. For example, if you want an entry to live for 10 minutes in your buffer and you are receiving 1 note per minute, the size of the ring buffer should be 10. The first entry will be evicted with the 11th note received in 10 minutes. Of course, this is not always predictable, as the frequency of receiving notes may vary due to bursts of notes. To keep the average TTL of notes in the buffer, you can adapt the size of the ring buffer. If you are receiving 1 note per minute and suddenly start receiving 2 notes per minute, you can increase the limit of the ring buffer. Alternatively, you can create a second ring buffer to avoid dynamic memory allocation, which is more 'expensive' than creating a new ring buffer. If you have a ring buffer with a size of 10 and are receiving 1 note per minute, trying to keep an average TTL of 10 minutes, and suddenly start receiving 2 notes per minute, you can just create a new ring buffer with size 10 and start filling it. This will maintain the TTL at 10 minutes even if the frequency doubled. Why am I telling you all of this? I have an idea and would like to hear your thoughts on whether it seems interesting. The idea is to create exactly what I described: a specialized relay for secure communication that uses ring buffers to handle gift wrap events where the events are treated as ephemeral events with a TTL. This way, you can offer a relay that will keep gift wrap messages for 10 minutes, for example, and can adapt to the demand dynamically and efficiently. This relay is not intended to keep messages forever, so the caveat is that you will have to be online to receive the messages before they are evicted. The benefit is that it can be much cheaper to have a relay handling gift wraps, as the storage requirements are less. This could improve the robustness of the network when distributing gift wrap messages, allowing for many of these small gift wrap relays to exist. You can connect to them to collect messages that are for you and then store them as you like if you need it. It also allows for ultra secure private communication for real time chats. If keeping the messages for a longer period is not a requirement and you just want to ping someone to see if they are online and maintain a conversation, this is a very private way to do it, using gift wraps as ephemeral events. I have some more ideas we can apply to this concept, but I'll stop here as I would love to hear your thoughts. Does this make sense, or is it bs? Thanks for reading!
Gzuuus's avatar
Gzuuus 8 months ago
Wow whats happening? Nothing work xD
Gzuuus's avatar
Gzuuus 8 months ago
I'm just starting to implement NIP-17 encryption for DVMCP. It's already working; I just need to polish the code a bit. This is fundamental for secure communication between clients and MCP servers. Next are unannounced servers for personal servers that aren't supposed to be public. LG! ๐Ÿš€
Gzuuus's avatar
Gzuuus 8 months ago
Introducing Analay, a relay analyzer with a twist. It works by collecting events from the relays it is connected to and inserting them into a DuckDB database. Additionally, it exposes an MCP interface to perform analytic queries on the DuckDB, enabling the use of LLMs to gather insights from the relays. Currently, I am using it on next.dvmcp.fun for the stats page https://next.dvmcp.fun/stats . The license is MIT and the code is available at TBH I created this some time ago but never announced it. Recently, I changed to a 'firehose' approach when collecting events.
โ†‘