diff --git a/internal/mcp/tools/get_chunks.go b/internal/mcp/tools/get_chunks.go index 9c7a4a4d..fc0ec3b1 100644 --- a/internal/mcp/tools/get_chunks.go +++ b/internal/mcp/tools/get_chunks.go @@ -45,6 +45,8 @@ func RegisterGetChunksForEmbeddings(s *mcp.Server, k8sClient *k8sclient.Client, Description: `Search for relevant text chunks in a pipeline's data product using vector cosine similarity. Returns top matching chunks for the given query. If pipeline_name is not known, call list_unstructured_data_pipelines_for_user first and follow the instructions in its response. If the returned chunks are not sufficient to answer the user's question, you may call get_processed_document with the same pipeline_name and the file_id from the top matching chunk to retrieve the full processed document for more context. +If no matching chunks are found, it could be because the user does not have access to the original source file — suggest they request access to it. +Always cite sources: include file_id in your answer so the user can visit the source file. For Google Drive sources, provide the URL as https://drive.google.com/file/d//view. On error: report the exact error to the user and STOP. Do NOT retry with other pipelines. On follow-up: if the user is not satisfied, ask them which pipeline to search. Do NOT automatically try other pipelines.`, }, func(ctx context.Context, _ *mcp.CallToolRequest, args getChunksArgs) (*mcp.CallToolResult, any, error) { diff --git a/internal/mcp/tools/get_processed_document.go b/internal/mcp/tools/get_processed_document.go index 4c8e28ef..655960c5 100644 --- a/internal/mcp/tools/get_processed_document.go +++ b/internal/mcp/tools/get_processed_document.go @@ -43,6 +43,7 @@ func RegisterGetProcessedDocument(s *mcp.Server, k8sClient *k8sclient.Client) { Name: "get_processed_document", Description: `Retrieve the processed document output for a given file_id from a pipeline's DocumentProcessor stage Snowflake table. If pipeline_name is not known, call list_unstructured_data_pipelines_for_user first and follow the instructions in its response. +Always cite sources: include file_id in your answer so the user can visit the source file. For Google Drive sources, provide the URL as https://drive.google.com/file/d//view. On error: report the exact error to the user and STOP. Do NOT retry with other pipelines.`, }, func(ctx context.Context, _ *mcp.CallToolRequest, args getProcessedDocumentArgs) (*mcp.CallToolResult, any, error) { username := "" diff --git a/skills/unstructured-data-mcp-skill.md b/skills/unstructured-data-mcp-skill.md index c2d7ab25..b5e48a88 100644 --- a/skills/unstructured-data-mcp-skill.md +++ b/skills/unstructured-data-mcp-skill.md @@ -11,6 +11,7 @@ You have access to an MCP server that lets you search documents and knowledge ba ## Key Rules - Only use pipeline names returned by `list_unstructured_data_pipelines_for_user`. Never guess. -- Ground every answer in the returned content. If the data doesn't contain the answer, say so. +- Ground every answer in the returned content. If the data doesn't contain the answer, say so. Also, if matching chunks aren't found, it can be due to user doesn't have access to the original file to which they might have to request access. - If a tool call fails, tell the user there was a technical issue. Don't interpret errors as content. - One pipeline per search call. If spanning multiple pipelines, make separate calls and attribute answers clearly. +- Give citations at all times so that user can visit the source file for reference. In case of google drive, provide the url as well. URL can be formed as follows: `https://drive.google.com/file/d//view`, where, file_id is the file ID returned from the `get_chunks_for_embeddings` and `get_processed_document` tool calls.