mirror of
https://github.com/invariantlabs-ai/invariant-gateway.git
synced 2026-10-12 07:27:08 +02:00
Add an option to add extra metadata that is pushed and passed to Guardrails during an MCP session (#47)
* use select() before readline * support for setting static metadata for MCP sessions * nest extra mcp metadata in metadata object * unify session metadata * extra metadata tests * use empty object as parameters, if None * list_tools as tool call * offset indices in tests * test: adjust addresses * mcp: make error reporting configurable * line logging * log version * verbose logging + loud exception failure * add server and client name to policy get * append trace even if not pushing * port tools/list message support to SSE * use python -m build * adjust guardrail failure address * support for blocking tools/list in SSE * use error-based failure response format by default * tools/list test * don't list_tools in stdio connect * flaky test: handle second possible result in anthropic streaming case --------- Co-authored-by: knielsen404 <kristian@invariantlabs.ai>
This commit is contained in:
1 parent
4dbb400620
commit
e18c6b5bdb
14 files changed
+1007
-104
No files matched your search
@@ -97,7 +97,13 @@ async def run(
|
||||
"PUSH-INVARIANT-EXPLORER": str(push_to_explorer),
|
||||
},
|
||||
)
|
||||
return await client.process_query(tool_name, tool_args)
|
||||
# list tools
|
||||
listed_tools = await client.session.list_tools()
|
||||
# call tool
|
||||
if tool_name == "tools/list":
|
||||
return listed_tools
|
||||
else:
|
||||
return await client.process_query(tool_name, tool_args)
|
||||
finally:
|
||||
# Sleep for a while to allow the server to process the background tasks
|
||||
# like pushing traces to the explorer
|
||||
|
||||
@@ -23,6 +23,7 @@ class MCPClient:
|
||||
project_name: str,
|
||||
server_script_path: str,
|
||||
push_to_explorer: bool,
|
||||
metadata_keys: Optional[dict[str, str]] = None,
|
||||
):
|
||||
"""
|
||||
Connect to an MCP server.
|
||||
@@ -42,6 +43,12 @@ class MCPClient:
|
||||
"--project-name",
|
||||
project_name,
|
||||
]
|
||||
# add metadata cli args
|
||||
if metadata_keys is not None:
|
||||
for key, value in metadata_keys.items():
|
||||
args.append("--metadata-" + key + "=" + value)
|
||||
|
||||
|
||||
if push_to_explorer:
|
||||
args.append("--push-explorer")
|
||||
args.extend(
|
||||
@@ -54,6 +61,7 @@ class MCPClient:
|
||||
os.path.basename(server_script_path),
|
||||
]
|
||||
)
|
||||
|
||||
server_params = StdioServerParameters(
|
||||
command="uvx",
|
||||
args=args,
|
||||
@@ -73,6 +81,7 @@ class MCPClient:
|
||||
)
|
||||
)
|
||||
|
||||
# initialize the session
|
||||
await self.session.initialize()
|
||||
|
||||
async def call_tool(
|
||||
@@ -101,6 +110,7 @@ async def run(
|
||||
push_to_explorer: bool,
|
||||
tool_name: str,
|
||||
tool_args: dict[str, Any],
|
||||
metadata_keys: Optional[dict[str, str]] = None,
|
||||
) -> types.CallToolResult:
|
||||
"""
|
||||
Main function to setup the MCP client and server.
|
||||
@@ -123,7 +133,13 @@ async def run(
|
||||
project_name,
|
||||
server_script_path,
|
||||
push_to_explorer,
|
||||
metadata_keys=metadata_keys
|
||||
)
|
||||
return await client.call_tool(tool_name, tool_args)
|
||||
listed_tools = await client.session.list_tools()
|
||||
if tool_name == "tools/list":
|
||||
# list tools
|
||||
return listed_tools
|
||||
else:
|
||||
return await client.call_tool(tool_name, tool_args)
|
||||
finally:
|
||||
await client.cleanup()
|
||||
Reference in new issue
Block a user