-
Notifications
You must be signed in to change notification settings - Fork 304
Mcp #478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Mcp #478
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a first pass review!
package.json
Outdated
@@ -55,7 +55,8 @@ | |||
}, | |||
"dependencies": { | |||
"@ironclad/rivet-core": "workspace:^", | |||
"@ironclad/rivet-node": "workspace:^" | |||
"@ironclad/rivet-node": "workspace:^", | |||
"@modelcontextprotocol/sdk": "^1.5.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add this to the individual packages, not the root package.json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have a better node body? Maybe it's just the example, but a blank body doesn't seem very helpful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
packages/app/vite.config.ts
Outdated
alias: { | ||
'@ironclad/rivet-core': resolve('../core/src/index.ts'), | ||
'@ironclad/trivet': resolve('../trivet/src/index.ts'), | ||
// 'node:child_process': resolve('./src/mocks/node-polyfills.ts'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we don't need these any more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes this is removed
@@ -0,0 +1,116 @@ | |||
// Mock implementation for node:child_process | |||
export const spawn = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we don't need this file any more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it came back
packages/app/vite.config.ts
Outdated
@@ -34,6 +52,10 @@ export default defineConfig({ | |||
plugins: [visualizer()], | |||
}, | |||
}, | |||
// define: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
label: 'Configuration', | ||
dataKey: 'config', | ||
useInputToggleDataKey: 'useEndpointInput', | ||
helperMessage: 'Configuration for the MCP server' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please run prettier on this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prettier is done
@@ -0,0 +1,235 @@ | |||
# MCP Node for Rivet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move these docs into the docs project? And structure it like the existing per-node documentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved
ignores = [], | ||
} = options; | ||
|
||
const resolvedPath = await resolveBaseDir(baseDir, path); | ||
console.log('Reading directory from path:', resolvedPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to remove this and other console logs in the file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed console.log
): Promise<{ output: string; metadata: Record<string, unknown> }> { | ||
let configFile: object; | ||
try { | ||
configFile = this.data.useEndpointInput |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be behind a different data flag, not useEndpointInput
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes changed...
throw new MCPError(MCPErrorType.INVALID_RESPONSE, 'Invalid format for MCP configuration'); | ||
} | ||
|
||
const serverId = this.data.useEndpointInput |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use getInputOrData
for this pattern, getInputOrData(this.data, inputs, 'serverId')
This looks great! Quick question: Will this work in node integration using runGraphInFile? |
@@ -0,0 +1,116 @@ | |||
// Mock implementation for node:child_process | |||
export const spawn = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it came back
alias: { | ||
'@ironclad/rivet-core': resolve('../core/src/index.ts'), | ||
'@ironclad/trivet': resolve('../trivet/src/index.ts'), | ||
'node:child_process': resolve('./src/mocks/node-polyfills.ts'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why were these added back in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do need these, I tried an alternative https://www.npmjs.com/package/vite-plugin-node-polyfills
to get the polyfills but its a really buggy plugin at the moment. I'm not too happy with the mock implementations of these functions either but I don't see a better way of fulfilling the needs for the mcp sdk package
@@ -48,6 +48,8 @@ | |||
"@google-cloud/vertexai": "^0.1.3", | |||
"@google/generative-ai": "^0.21.0", | |||
"@huggingface/inference": "^2.6.4", | |||
"@modelcontextprotocol/sdk": "^1.5.0", | |||
"@tauri-apps/api": "^1.5.3", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Core cannot depend on tauri
@suhail-ak-s wanted to check in and see if its okay for me to pick this up in another branch and take this to finish line? |
Yes you can go ahead… pr will be remain same right??
Get Outlook for iOS<https://aka.ms/o0ukef>
…________________________________
From: Aryaman Agrawal ***@***.***>
Sent: Friday, April 4, 2025 10:31:53 PM
To: Ironclad/rivet ***@***.***>
Cc: An Suhail ***@***.***>; Mention ***@***.***>
Subject: Re: [Ironclad/rivet] Mcp (PR #478)
@suhail-ak-s<https://github.com/suhail-ak-s> wanted to check in and see if its okay for me to pick this up in another branch and take this to finish line?
—
Reply to this email directly, view it on GitHub<#478 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BFOQLV2YNZNY7S4EMPQ5DCT2X23IDAVCNFSM6AAAAABXQX4EDGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONZZGMYDANJVGA>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
[AryamanAgrawal]AryamanAgrawal left a comment (Ironclad/rivet#478)<#478 (comment)>
@suhail-ak-s<https://github.com/suhail-ak-s> wanted to check in and see if its okay for me to pick this up in another branch and take this to finish line?
—
Reply to this email directly, view it on GitHub<#478 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BFOQLV2YNZNY7S4EMPQ5DCT2X23IDAVCNFSM6AAAAABXQX4EDGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONZZGMYDANJVGA>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@suhail-ak-s Thanks a lot for the reply! Yes, this PR will remain as is. I'm thinking of creating a new branch off of this so that I don't mess up your branch directly. Rest assured, I'll keep the contribution history from your end. |
You are welcome… Great then go ahead 👍
Get Outlook for iOS<https://aka.ms/o0ukef>
…________________________________
From: Aryaman Agrawal ***@***.***>
Sent: Friday, April 4, 2025 10:41:01 PM
To: Ironclad/rivet ***@***.***>
Cc: An Suhail ***@***.***>; Mention ***@***.***>
Subject: Re: [Ironclad/rivet] Mcp (PR #478)
@suhail-ak-s<https://github.com/suhail-ak-s> Thanks a lot for the reply! Yes, this PR will remain as is. I'm thinking of creating a new branch off of this so that I don't mess up your branch directly. Rest assured, I'll keep the contribution history from your end.
—
Reply to this email directly, view it on GitHub<#478 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BFOQLVZ2V2XMMCKOFBO6GVD2X24KLAVCNFSM6AAAAABXQX4EDGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONZZGMYTOMZQGI>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
[AryamanAgrawal]AryamanAgrawal left a comment (Ironclad/rivet#478)<#478 (comment)>
@suhail-ak-s<https://github.com/suhail-ak-s> Thanks a lot for the reply! Yes, this PR will remain as is. I'm thinking of creating a new branch off of this so that I don't mess up your branch directly. Rest assured, I'll keep the contribution history from your end.
—
Reply to this email directly, view it on GitHub<#478 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BFOQLVZ2V2XMMCKOFBO6GVD2X24KLAVCNFSM6AAAAABXQX4EDGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONZZGMYTOMZQGI>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Apologies if I'm getting ahead of myself since this hasn't been fully implemented yet but I made a build of your fork and tried to test it with an mcp https://github.com/sooperset/mcp-atlassian/tree/main Despite the mcp-atlassian project working with cursor, it appears to be incompatible with this Rivet node implementation, and I thought it worth sharing if it might make the Rivet node more robust. Specifically this implementation appears to invoke a 'get_tools' tool, where are other mcp implementations such as mcp-atlassian rely on the standard MCP "tools/list" method. Please correct me if I'm wrong, or if there is a known work around. Many thanks for writing this implementation, I'm very much looking forward to using it in the official release. |
@Karlostavitch1 Thanks for testing this out and reporting the bug. I'm working on a different PR built on top of this one to complete the MCP implementation. I can figure out the change to make it compatible with existing servers. Is it possible to mention the steps you tested this in? |
I've only been testing tool discovery because its crucial for my specific project, and I've tested 2 builds with the same results: https://github.com/suhail-ak-s/rivet/tree/mcp and https://github.com/Ironclad/rivet/tree/aryamanagrawal-suhail/mcp according to: https://github.com/Ironclad/rivet/blob/aryamanagrawal-suhail/mcp/packages/docs/docs/node-reference/mcp.mdx Tool discovery: ![]() ![]() I also tried: And tested STDIO also (in addition to the required inputs): STDIO was not logging as verbosely but depending on the input it was either timing out or failing. Excuse me, but at this point I'm a bit out of my depth. MCP is still pretty new and a lot of information relates to getting mcps added to cursor / windsurf. I'll dump AI analysis below: Manus: Grok: Key Points
Direct AnswerHow Cursor or Windsurf Get the List of Available Tools Why This Works Unexpected Detail Next Steps Comprehensive Analysis: Tool Discovery in mcp-atlassian for Cursor and WindsurfThis note provides a detailed analysis of how Cursor and Windsurf obtain the list of available tools from the mcp-atlassian server, given that it does not support a "get_tools" tool, as observed in previous interactions with Rivet. The discussion is grounded in the Model Context Protocol (MCP) specification, available documentation, and inferred practices, ensuring a thorough understanding for users integrating with Atlassian services via AI tools. Background and ContextRivet is an AI programming environment that uses a visual, node-based graph editor for building AI agents, particularly with large language models (LLMs) Rivet - AI Programming Environment. The Model Context Protocol (MCP), developed by Anthropic, is an open standard that connects AI assistants to various systems, enabling real-time data access and dynamic tool discovery Introducing the Model Context Protocol | Anthropic. The mcp-atlassian server, a specific MCP implementation, integrates with Atlassian's Confluence and Jira, offering tools for searching, creating, and managing content in these platforms mcp-atlassian GitHub Repository. Cursor, an AI-powered code editor, and Windsurf, likely another AI tool or IDE, are known to integrate with MCP servers, including mcp-atlassian, for enhanced functionality. The user previously encountered an error in Rivet when attempting to list tools using {"toolName": "get_tools", "args": {}}, indicating that mcp-atlassian does not support this tool. This raises the question of how Cursor and Windsurf manage to get the list of available tools, given this limitation. Understanding Tool Discovery in MCPMCP provides a standardized way for clients to discover tools offered by servers, enabling dynamic integration without requiring hardcoded lists. From the MCP documentation, tool discovery is a key feature, allowing clients to list available tools through a specific mechanism Tools - Model Context Protocol. The specification details that clients can list available tools through the "tools/list" endpoint, typically via a JSON-RPC request Model Context Protocol explained as simply as possible. This method is standard across MCP implementations, ensuring interoperability. For HTTP transport, this likely involves sending a POST request with a JSON-RPC payload containing the method "tools/list". For STDIO transport, it would involve writing a JSON-RPC message to stdin with the same method. The server responds with a list of tools, each identified by name and including metadata like parameters and descriptions. Analyzing mcp-atlassian's Tool DiscoveryGiven that mcp-atlassian is an MCP-compliant server, it should support the standard "tools/list" method for tool discovery. However, in the previous interaction with Rivet, sending {"toolName": "get_tools", "args": {}} resulted in an error, suggesting that Rivet interprets this as trying to invoke a tool named "get_tools", which mcp-atlassian does not have. This indicates that Rivet's MCP node is designed specifically for tool invocation, not for sending arbitrary JSON-RPC requests like "tools/list". To confirm mcp-atlassian's support for tool discovery, we can refer to its documentation. The repository lists available tools, such as confluence_search and jira_get_issue, but does not explicitly mention how clients discover them dynamically mcp-atlassian GitHub Repository. However, as an MCP server, it is reasonable to assume it implements the standard "tools/list" method, given the specification. Further evidence comes from the mention of "MCP Inspector", a debugging tool for MCP servers, which can be used with mcp-atlassian via npx @modelcontextprotocol/inspector uvx mcp-atlassian .... This tool likely sends a "tools/list" request to list the server's capabilities, suggesting that mcp-atlassian does support this method. How Cursor and Windsurf Likely Get the ListCursor and Windsurf, as full MCP clients, likely implement the complete protocol, including sending "tools/list" requests to discover tools dynamically. Given their nature as AI-powered IDEs or tools, they probably use HTTP mode for remote server connections, sending a JSON-RPC request with method "tools/list" to the server's endpoint. For example, if mcp-atlassian is running locally, they might send a POST request to [invalid url, do not cite] with a payload like: text CollapseWrapCopy {
"jsonrpc": "2.0",
"method": "tools/list",
"id": "1"
} The server would respond with a list of tools, such as: text CollapseWrapCopy {
"jsonrpc": "2.0",
"id": "1",
"result": [
{"name": "confluence_search", "description": "Search Confluence content using CQL", ...},
{"name": "jira_get_issue", "description": "Get details of a specific Jira issue", ...},
...
]
} For STDIO mode, if used locally, they would write a similar JSON-RPC message to stdin, and the server would respond via stdout. This aligns with the MCP specification, where clients first request the list of capabilities, including tools, and then use them based on the AI model's needs What is the Model Context Protocol (MCP)?. The flexibility of MCP allows Cursor and Windsurf to integrate seamlessly with mcp-atlassian, dynamically discovering tools without needing hardcoded lists. Comparison with RivetThe difference with Rivet lies in its implementation. Rivet's MCP node appears to be designed for tool invocation, expecting inputs like {"toolName": "confluence_search", "args": {"query": "some query"}}, not for sending JSON-RPC requests like "tools/list". This limitation means Rivet users must know the tools in advance, possibly by referring to the documentation or using external tools like MCP Inspector, rather than dynamically discovering them through the node. Table: Tool Discovery Methods Across Clients
Client | Supports "tools/list" Request | Transport Mode | Notes
-- | -- | -- | --
Cursor | Yes | Likely HTTP | Sends JSON-RPC request to list tools dynamically
Windsurf | Yes | Likely HTTP | Similar to Cursor, integrates with MCP servers
Rivet | No (via MCP node) | STDIO/HTTP | Designed for tool invocation, not discovery
ConclusionCursor and Windsurf get the list of available tools from mcp-atlassian by sending a JSON-RPC request with method "tools/list", leveraging the MCP standard for tool discovery. This is likely done via HTTP mode with a POST request to the server's endpoint, though STDIO mode could also be used for local servers. The evidence suggests mcp-atlassian supports this, as expected from an MCP server, unlike Rivet's MCP node, which is limited to tool invocation and does not facilitate dynamic discovery through the node itself. Users can explore further using tools like MCP Inspector for debugging and listing capabilities. Cursor and Windsurf likely get the list of available tools from mcp-atlassian by sending a JSON-RPC request with the method "tools/list" to the server, following the MCP standard for tool discovery. This means they ask the server for a list of tools it can use, and the server responds with details like confluence_search or jira_get_issue. Why This Works Mcp-atlassian is designed to follow MCP, which includes a way for clients to discover tools dynamically. Unlike Rivet, which seemed to expect a "get_tools" tool that mcp-atlassian doesn't have, Cursor and Windsurf likely send a specific request to list tools, not try to call a tool named "get_tools". Unexpected Detail You might not expect that Rivet, unlike Cursor or Windsurf, doesn't seem to let you send this "tools/list" request directly through its MCP node, possibly requiring you to know the tools in advance or use another tool like MCP Inspector to list them. Next Steps If you're using Rivet and want to list tools, check the documentation at mcp-atlassian GitHub for the fixed list of tools, or consider using MCP Inspector (npx @modelcontextprotocol/inspector uvx mcp-atlassian ...) to explore the server's capabilities. Comprehensive Analysis: Tool Discovery in mcp-atlassian for Cursor and Windsurf Background and Context The user previously encountered an error in Rivet when attempting to list tools using {"toolName": "get_tools", "args": {}}, indicating that mcp-atlassian does not support this tool. This raises the question of how Cursor and Windsurf manage to get the list of available tools, given this limitation. Understanding Tool Discovery in MCP For HTTP transport, this likely involves sending a POST request with a JSON-RPC payload containing the method "tools/list". For STDIO transport, it would involve writing a JSON-RPC message to stdin with the same method. The server responds with a list of tools, each identified by name and including metadata like parameters and descriptions. Analyzing mcp-atlassian's Tool Discovery To confirm mcp-atlassian's support for tool discovery, we can refer to its documentation. The repository lists available tools, such as confluence_search and jira_get_issue, but does not explicitly mention how clients discover them dynamically mcp-atlassian GitHub Repository. However, as an MCP server, it is reasonable to assume it implements the standard "tools/list" method, given the specification. Further evidence comes from the mention of "MCP Inspector", a debugging tool for MCP servers, which can be used with mcp-atlassian via npx @modelcontextprotocol/inspector uvx mcp-atlassian .... This tool likely sends a "tools/list" request to list the server's capabilities, suggesting that mcp-atlassian does support this method. How Cursor and Windsurf Likely Get the List text Collapse Wrap Copy text Collapse Wrap Copy This aligns with the MCP specification, where clients first request the list of capabilities, including tools, and then use them based on the AI model's needs What is the Model Context Protocol (MCP)?. The flexibility of MCP allows Cursor and Windsurf to integrate seamlessly with mcp-atlassian, dynamically discovering tools without needing hardcoded lists. Comparison with Rivet Table: Tool Discovery Methods Across Clients Let me know if you want me to try some specific tests. |
Add Model Context Protocol (MCP) Integration
Description
This PR adds support for the Model Context Protocol (MCP), enabling seamless integration with external AI capabilities, tools, and resources through a standardized protocol. The implementation includes both HTTP and STDIO communication modes, making it flexible for different deployment scenarios.
Key Features
MCPNode
for handling MCP communicationsImplementation Details
MCPNode
class with full TypeScript type safetymcp-config.json
Technical Considerations
Testing
The implementation includes:
Documentation
Breaking Changes
None. This is a purely additive change that maintains compatibility with existing functionality.
Future Considerations