feat: add file asset listing prompt
Expose list_file_assets so agents can browse allowed source files without relying on empty search queries. Add a how_to_use_wiki_file_assets prompt to make the MCP purpose and workflow visible to clients that inspect prompts/resources before tools.
This commit is contained in:
@@ -151,6 +151,32 @@ def create_server(
|
||||
)
|
||||
)
|
||||
|
||||
@server.tool()
|
||||
def list_file_assets(
|
||||
doc_type: str | None = None,
|
||||
source_type: str | None = None,
|
||||
product_line: str | None = None,
|
||||
customer: str | None = None,
|
||||
competitor: str | None = None,
|
||||
limit: int = 10,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""List safe source files matching optional filters. Use search_file_assets when the user gives keywords such as product codes, sizes, or drawing names."""
|
||||
return _as_mcp_results(
|
||||
core_search_file_assets(
|
||||
vault,
|
||||
"",
|
||||
db_path=db,
|
||||
limit=limit,
|
||||
doc_type=doc_type,
|
||||
source_type=source_type,
|
||||
product_line=product_line,
|
||||
customer=customer,
|
||||
competitor=competitor,
|
||||
profile_name=profile_name,
|
||||
expose_paths=expose_paths,
|
||||
)
|
||||
)
|
||||
|
||||
@server.tool()
|
||||
def get_file_asset_metadata(file_id: str) -> dict[str, Any]:
|
||||
"""Return safe metadata and the resource URI for one indexed source file."""
|
||||
@@ -176,6 +202,22 @@ def create_server(
|
||||
)
|
||||
return resource["bytes"]
|
||||
|
||||
@server.prompt(
|
||||
"how_to_use_wiki_file_assets",
|
||||
description="Explain how to search and retrieve original source files from the wiki-file-assets MCP server.",
|
||||
)
|
||||
def how_to_use_wiki_file_assets() -> str:
|
||||
return (
|
||||
"wiki-file-assets serves original source files archived from an Obsidian wiki vault. "
|
||||
"Use search_file_assets for keyword searches such as product codes, drawing names, sizes, "
|
||||
"or document types. Use list_file_assets to browse allowed engineering files with optional "
|
||||
"filters. Use get_file_asset_metadata with a file_id from search/list results to get the "
|
||||
"asset://source/sha256/... URI, then read that resource to fetch the original file bytes. "
|
||||
"This MCP is intentionally limited to safe engineering files such as drawings, CAD/3D models, "
|
||||
"specifications, product parameters, and test reports; it blocks raw orders, prices, email "
|
||||
"correspondence, complaint evidence, claims, and personal data."
|
||||
)
|
||||
|
||||
return server
|
||||
|
||||
|
||||
|
||||
@@ -100,12 +100,15 @@ class RemoteMcpServerTests(unittest.TestCase):
|
||||
def test_create_server_uses_file_asset_service_name(self):
|
||||
class FakeMCP:
|
||||
names = []
|
||||
tool_names = []
|
||||
prompt_names = []
|
||||
|
||||
def __init__(self, name, **kwargs):
|
||||
self.names.append(name)
|
||||
|
||||
def tool(self):
|
||||
def decorator(func):
|
||||
self.tool_names.append(func.__name__)
|
||||
return func
|
||||
|
||||
return decorator
|
||||
@@ -116,6 +119,13 @@ class RemoteMcpServerTests(unittest.TestCase):
|
||||
|
||||
return decorator
|
||||
|
||||
def prompt(self, name=None, **_kwargs):
|
||||
def decorator(func):
|
||||
self.prompt_names.append(name or func.__name__)
|
||||
return func
|
||||
|
||||
return decorator
|
||||
|
||||
with (
|
||||
tempfile.TemporaryDirectory() as tmp,
|
||||
patch.dict("sys.modules", {"mcp.server.fastmcp": type("Mod", (), {"FastMCP": FakeMCP})()}),
|
||||
@@ -124,6 +134,10 @@ class RemoteMcpServerTests(unittest.TestCase):
|
||||
|
||||
self.assertIsInstance(server, FakeMCP)
|
||||
self.assertEqual(FakeMCP.names[-1], "wiki-file-assets")
|
||||
self.assertIn("search_file_assets", FakeMCP.tool_names)
|
||||
self.assertIn("list_file_assets", FakeMCP.tool_names)
|
||||
self.assertIn("get_file_asset_metadata", FakeMCP.tool_names)
|
||||
self.assertIn("how_to_use_wiki_file_assets", FakeMCP.prompt_names)
|
||||
|
||||
def test_run_http_server_fails_before_server_creation_without_token(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
|
||||
Reference in New Issue
Block a user