diff --git a/.github/workflows/build-backend-prd.yml b/.github/workflows/build-backend-prd.yml index 3c52fc09..77c30900 100644 --- a/.github/workflows/build-backend-prd.yml +++ b/.github/workflows/build-backend-prd.yml @@ -65,6 +65,7 @@ jobs: XTRAMCP_OPENREVIEW_PASSWORD: ${{ secrets.XTRAMCP_OPENREVIEW_PASSWORD_PRD }} XTRAMCP_CROSSREF_EMAIL_ADDRESS: ${{ secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_PRD }} XTRAMCP_DOI_EMAIL_ADDRESS: ${{ secrets.XTRAMCP_DOI_EMAIL_ADDRESS_PRD }} + XTRAMCP_ACL_METADATA_DB_URL: ${{ secrets.XTRAMCP_ACL_METADATA_DB_URL_PRD }} XTRAMCP_ARXIV_METADATA_DB_URL: ${{ secrets.XTRAMCP_ARXIV_METADATA_DB_URL_PRD }} XTRAMCP_MONGO_URI: ${{ secrets.XTRAMCP_MONGO_URI_PRD }} MONGO_URI: ${{ secrets.MONGO_URI_PRD }} diff --git a/.github/workflows/build-backend-stg.yml b/.github/workflows/build-backend-stg.yml index 10ccd283..d3f02824 100644 --- a/.github/workflows/build-backend-stg.yml +++ b/.github/workflows/build-backend-stg.yml @@ -65,6 +65,7 @@ jobs: XTRAMCP_OPENREVIEW_PASSWORD: ${{ secrets.XTRAMCP_OPENREVIEW_PASSWORD_STG }} XTRAMCP_CROSSREF_EMAIL_ADDRESS: ${{ secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_STG }} XTRAMCP_DOI_EMAIL_ADDRESS: ${{ secrets.XTRAMCP_DOI_EMAIL_ADDRESS_STG }} + XTRAMCP_ACL_METADATA_DB_URL: ${{ secrets.XTRAMCP_ACL_METADATA_DB_URL_PRD }} XTRAMCP_ARXIV_METADATA_DB_URL: ${{ secrets.XTRAMCP_ARXIV_METADATA_DB_URL_STG }} XTRAMCP_MONGO_URI: ${{ secrets.XTRAMCP_MONGO_URI_STG }} MONGO_URI: ${{ secrets.MONGO_URI_STG }} diff --git a/hack/prd.sh b/hack/prd.sh index 13e30499..26b173e0 100755 --- a/hack/prd.sh +++ b/hack/prd.sh @@ -18,6 +18,7 @@ XTRAMCP_OPENREVIEW_USERNAME=${XTRAMCP_OPENREVIEW_USERNAME:-dummy-XTRAMCP_OPENREV XTRAMCP_OPENREVIEW_PASSWORD=${XTRAMCP_OPENREVIEW_PASSWORD:-dummy-XTRAMCP_OPENREVIEW_PASSWORD} XTRAMCP_CROSSREF_EMAIL_ADDRESS=${XTRAMCP_CROSSREF_EMAIL_ADDRESS:-dummy-crossref-email-address} XTRAMCP_DOI_EMAIL_ADDRESS=${XTRAMCP_DOI_EMAIL_ADDRESS:-dummy-doi-email-address} +XTRAMCP_ACL_METADATA_DB_URL=${XTRAMCP_ACL_METADATA_DB_URL:-postgresql://dummy-acl-metadata-db-url} XTRAMCP_ARXIV_METADATA_DB_URL=${XTRAMCP_ARXIV_METADATA_DB_URL:-postgresql://dummy-arxiv-metadata-db-url} XTRAMCP_MONGO_URI=${XTRAMCP_MONGO_URI:-mongodb://dummy-mongo-uri} PAPERDEBUGGER_IMAGE=${PAPERDEBUGGER_IMAGE:-ghcr.io/paperdebugger/sharelatex-paperdebugger:latest} @@ -42,6 +43,7 @@ helm template $ROOT_DIR/helm-chart \ --set-string xtramcp_openreview_password=$XTRAMCP_OPENREVIEW_PASSWORD \ --set-string xtramcp_crossref_email_address=$XTRAMCP_CROSSREF_EMAIL_ADDRESS \ --set-string xtramcp_doi_email_address=$XTRAMCP_DOI_EMAIL_ADDRESS \ + --set-string xtramcp_acl_metadata_db_url=$XTRAMCP_ACL_METADATA_DB_URL \ --set-string xtramcp_arxiv_metadata_db_url=$XTRAMCP_ARXIV_METADATA_DB_URL \ --set-string xtramcp_mongo_uri=$XTRAMCP_MONGO_URI \ --set-string paperdebugger.image=$PAPERDEBUGGER_IMAGE \ diff --git a/hack/stg.sh b/hack/stg.sh index e3f32056..c3be2760 100755 --- a/hack/stg.sh +++ b/hack/stg.sh @@ -18,6 +18,7 @@ XTRAMCP_OPENREVIEW_USERNAME=${XTRAMCP_OPENREVIEW_USERNAME:-dummy-XTRAMCP_OPENREV XTRAMCP_OPENREVIEW_PASSWORD=${XTRAMCP_OPENREVIEW_PASSWORD:-dummy-XTRAMCP_OPENREVIEW_PASSWORD} XTRAMCP_CROSSREF_EMAIL_ADDRESS=${XTRAMCP_CROSSREF_EMAIL_ADDRESS:-dummy-crossref-email-address} XTRAMCP_DOI_EMAIL_ADDRESS=${XTRAMCP_DOI_EMAIL_ADDRESS:-dummy-doi-email-address} +XTRAMCP_ACL_METADATA_DB_URL=${XTRAMCP_ACL_METADATA_DB_URL:-postgresql://dummy-acl-metadata-db-url} XTRAMCP_ARXIV_METADATA_DB_URL=${XTRAMCP_ARXIV_METADATA_DB_URL:-postgresql://dummy-arxiv-metadata-db-url} XTRAMCP_MONGO_URI=${XTRAMCP_MONGO_URI:-mongodb://dummy-mongo-uri} PAPERDEBUGGER_IMAGE=${PAPERDEBUGGER_IMAGE:-ghcr.io/paperdebugger/sharelatex-paperdebugger:latest} @@ -42,6 +43,7 @@ helm template $ROOT_DIR/helm-chart \ --set-string xtramcp_openreview_password=$XTRAMCP_OPENREVIEW_PASSWORD \ --set-string xtramcp_crossref_email_address=$XTRAMCP_CROSSREF_EMAIL_ADDRESS \ --set-string xtramcp_doi_email_address=$XTRAMCP_DOI_EMAIL_ADDRESS \ + --set-string xtramcp_acl_metadata_db_url=$XTRAMCP_ACL_METADATA_DB_URL \ --set-string xtramcp_arxiv_metadata_db_url=$XTRAMCP_ARXIV_METADATA_DB_URL \ --set-string xtramcp_mongo_uri=$XTRAMCP_MONGO_URI \ --set-string paperdebugger.image=$PAPERDEBUGGER_IMAGE \ diff --git a/helm-chart/templates/paperdebugger-xtramcp-server.yaml b/helm-chart/templates/paperdebugger-xtramcp-server.yaml index 2b97dbd7..4d663dc6 100644 --- a/helm-chart/templates/paperdebugger-xtramcp-server.yaml +++ b/helm-chart/templates/paperdebugger-xtramcp-server.yaml @@ -60,3 +60,4 @@ data: MONGODB_CONNECTION_STRING: "{{ .Values.xtramcp_mongo_uri }}" MONGODB_DATABASE: "paperdebugger" ARXIV_METADATA_DB_URL: "{{ .Values.xtramcp_arxiv_metadata_db_url }}" + ACL_METADATA_DB_URL: "{{ .Values.xtramcp_acl_metadata_db_url }}" diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml index fd2e779c..ec96e51b 100644 --- a/helm-chart/values.yaml +++ b/helm-chart/values.yaml @@ -14,7 +14,7 @@ paperdebuggerMcpServer: image: ghcr.io/paperdebugger/paperdebugger-mcp-server:main-14409c5 paperdebuggerXtraMcpServer: - image: ghcr.io/paperdebugger/xtragpt-mcp-server:sha-2f1404c + image: ghcr.io/paperdebugger/xtragpt-mcp-server:sha-16c3861 mongo: in_cluster: true diff --git a/internal/api/user/list_prompts.go b/internal/api/user/list_prompts.go index 849935e3..94d3426e 100644 --- a/internal/api/user/list_prompts.go +++ b/internal/api/user/list_prompts.go @@ -13,44 +13,60 @@ import ( ) var defaultPrompts = []*userv1.Prompt{ + { + Id: "1", + CreatedAt: timestamppb.New(time.Time{}), + UpdatedAt: timestamppb.New(time.Time{}), + Title: "Tool List", + Content: "List available MCP tools with a brief description for each tool.", + IsUserPrompt: false, + }, { Id: "2", CreatedAt: timestamppb.New(time.Time{}), UpdatedAt: timestamppb.New(time.Time{}), - Title: "Search Relevant Papers (Powered by XtraMCP)", - Content: "First, understand my paper and extract the key ideas into an optimized query to find papers that are relevant to my work. Then search for relevant papers to read.\n\nOptional Args:\ntop_k: 10\nStart Date: None (e.g. 2018-12-31)\nEnd Date: None (e.g. 2025-12-31)", + Title: "Search Relevant Papers (XtraMCP's Researcher)", + Content: "You are a research assistant helping to retrieve related academic papers.\n\nStep 1 — Query synthesis:\nCarefully read the provided paper content.\nExtract the core technical ideas, methods, problem setting, and application domain.\nProduce ONE concise, high-signal search query optimized for academic paper retrieval.\n- Prefer technical keywords and established terminology\n- Include model names, task names, or methodological frameworks when applicable\n- Avoid unnecessary elaboration, prose, or citations\n\nStep 2 — Tool invocation:\nCall `search_relevant_papers` using the synthesized query.\n\nTool parameters:\n- query: \n- top_k: 10\n- start_date: 2018-12-31\n- end_date: 2025-12-31", IsUserPrompt: false, }, { Id: "3", CreatedAt: timestamppb.New(time.Time{}), UpdatedAt: timestamppb.New(time.Time{}), - Title: "Paper Review (Powered by XtraMCP)", - Content: "Call review_paper and evaluate my paper.\n\nOptional Args:\nTarget Venue: None (e.g. ICML, NeurIPS, CVPR)\nSeverity Level (blocker | major | minor | nit): Major\nSpecific Sections (default: entire paper): None (e.g. Abstract, Results,
)", + Title: "Paper Review (XtraMCP's Reviewer)", + Content: "Call `review_paper` and evaluate my paper.\n\nTool parameters:\nTarget Venue: None (e.g. ICML, NeurIPS, CVPR)\nSeverity Level (blocker | major | minor | nit): Major\nSpecific Sections (default: entire paper): None (e.g. Abstract, Results,
)", IsUserPrompt: false, }, { Id: "4", CreatedAt: timestamppb.New(time.Time{}), UpdatedAt: timestamppb.New(time.Time{}), - Title: "Verify Citations (Powered by XtraMCP)", - Content: "Call verify_citations to check the validity of all citations in my paper and identify any potential issues such as incorrect formatting, missing information, or inaccurate references.", + Title: "Verify Citations (XtraMCP's Reviewer)", + Content: "Call `verify_citations` to check the validity of all citations in my paper and identify any potential issues such as incorrect formatting, missing information, or inaccurate references.", IsUserPrompt: false, }, { Id: "5", CreatedAt: timestamppb.New(time.Time{}), UpdatedAt: timestamppb.New(time.Time{}), - Title: "Deep Research (Powered by XtraMCP)", - Content: "First, understand my paper and extract the key ideas into an optimized query. Do deep research and compare my paper against others.", + Title: "Generate Citations (XtraMCP's Reviewer)", + Content: "Call `generate_citations` to create properly formatted citations for:\n\nTool parameters:\n- links: [\n\t# paste URLs, arXiv IDs, DOIs, or titles\n\t# eg.: XtraGPT: Context-Aware and Controllable Academic Paper Revision\n\t...\n]", IsUserPrompt: false, }, { Id: "6", CreatedAt: timestamppb.New(time.Time{}), UpdatedAt: timestamppb.New(time.Time{}), - Title: "Online Research (Powered by XtraMCP)", - Content: "Understand my paper and run online search to find the latest papers related to my work.", + Title: "Deep Research (XtraMCP's Researcher)", + Content: "You are a research assistant helping to retrieve related academic papers to prepare for Deep Research.\n\nStep 1 — Query synthesis:\nCarefully read the provided paper content.\nExtract the core technical ideas, methods, problem setting, and application domain.\nProduce ONE concise, high-signal search query optimized for academic paper retrieval.\n- Prefer technical keywords and established terminology\n- Include model names, task names, or methodological frameworks when applicable\n- Avoid unnecessary elaboration, prose, or citations\n\nStep 2 — Tool invocation:\nCall `deep_research` using the synthesized query.\n\nTool parameters:\n- query: ", + IsUserPrompt: false, + }, + { + Id: "7", + CreatedAt: timestamppb.New(time.Time{}), + UpdatedAt: timestamppb.New(time.Time{}), + Title: "Online Research (XtraMCP's Researcher)", + Content: "You are a research assistant assisting with a recency-focused academic literature search.\n\nStep 1 — Keyword extraction:\nCarefully read the paper and extract a set of high-recall search keywords, including:\n- core task names and problem statements\n- methodological approaches and system types\n- application domains\n- commonly used synonyms and alternative phrasings\n- well-known model or framework names if relevant and widely used\n\nPrefer established terminology used in paper titles and abstracts.\nAvoid internal project names or marketing labels.\n\nStep 2 — Query construction:\nConstruct a keyword-based search query optimized for lexical search:\n- Use keyword phrases rather than full sentences\n- Combine terms using natural keyword adjacency (not prose)\n- Bias toward recall over precision\n\nStep 3 — Online retrieval:\nCall `online_search_papers` using the constructed query to find recent papers outside the internal database.", IsUserPrompt: false, }, } diff --git a/webapp/_webapp/src/components/message-entry-container/tools/tools.tsx b/webapp/_webapp/src/components/message-entry-container/tools/tools.tsx index 43978aed..bb517752 100644 --- a/webapp/_webapp/src/components/message-entry-container/tools/tools.tsx +++ b/webapp/_webapp/src/components/message-entry-container/tools/tools.tsx @@ -8,6 +8,7 @@ import { ReviewPaperCard } from "./xtramcp/review-paper"; import { SearchRelevantPapersCard } from "./xtramcp/search-relevant-papers"; import { OnlineSearchPapersCard } from "./xtramcp/online-search-papers"; import { VerifyCitationsCard } from "./xtramcp/verify-citations"; +import { GenerateCitationsCard } from "./xtramcp/generate-citations"; import { isXtraMcpTool } from "./xtramcp/utils/common"; import { GeneralToolCard } from "./general"; @@ -67,6 +68,10 @@ export default function Tools({ messageId, functionName, message, error, prepari return ( ); + } else if (functionName === "generate_citations") { + return ( + + ); } // Generic XtraMCP tool (not specialized) diff --git a/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/generate-citations.tsx b/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/generate-citations.tsx new file mode 100644 index 00000000..9c36cbb3 --- /dev/null +++ b/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/generate-citations.tsx @@ -0,0 +1,116 @@ +import { cn } from "@heroui/react"; +import { LoadingIndicator } from "../../../loading-indicator"; +import MarkdownComponent from "../../../markdown"; +import { useState } from "react"; +import { XtraMcpToolCardProps, parseXtraMcpToolResult, CollapseArrowButton, CollapseWrapper } from "./utils/common"; + +export const GenerateCitationsCard = ({ functionName, message, preparing, animated }: XtraMcpToolCardProps) => { + const [isMetadataCollapsed, setIsMetadataCollapsed] = useState(false); + + // Loading state (tool executing) + if (preparing) { + return ( +
+
+

Generating your citations..

+
+ +
+ ); + } + + // Parse XtraMCP ToolResult format + const result = parseXtraMcpToolResult(message); + + // No result or not ToolResult format - minimal display + if (!result) { + return ( +
+
+

{functionName}

+
+
+ ); + } + + // Error state + if (result.error || result.success === false) { + return ( +
+ {/* Header with Error label and arrow button */} +
setIsMetadataCollapsed(!isMetadataCollapsed)} + > +

{functionName}

+
+ Error + +
+
+ + {/* Error message dropdown */} + +
+ {result.error || "Tool execution failed"} +
+
+
+ ); + } + + // Success state - verbatim mode (guaranteed for this tool on success) + // Display compact card + content below + if (typeof result.content === "string") { + return ( + <> + {/* COMPACT TOOL CARD - Just title + metadata dropdown */} +
+ {/* Header with arrow button */} +
setIsMetadataCollapsed(!isMetadataCollapsed)} + > +

{functionName}

+ +
+ + {/* Metadata dropdown - INSIDE the tool card */} + {result.metadata && Object.keys(result.metadata).length > 0 && ( + +
+ {/* Custom metadata rendering */} +
⚠️ [Experimental Feature] Some BibTeX entries may not be able to be generated.
Report if you encounter an unknown issue.
+ {result.metadata.total_links !== undefined && ( +
+ Total Links/IDs/Info: {result.metadata.total_links} +
+ )} +
+
+ )} +
+ + {/* CONTENT - OUTSIDE/BELOW the tool card, always visible */} +
+ {result.content} +
+ + ); + } + + // Fallback - unknown format + return ( +
+
+

{functionName}

+
+
+ ); +}; diff --git a/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/search-relevant-papers.tsx b/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/search-relevant-papers.tsx index 09878ac5..07fff255 100644 --- a/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/search-relevant-papers.tsx +++ b/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/search-relevant-papers.tsx @@ -93,7 +93,10 @@ export const SearchRelevantPapersCard = ({ functionName, message, preparing, ani {result.metadata && Object.keys(result.metadata).length > 0 && (
- {/* Custom metadata rendering */} + {/* Custom metadata rendering; NOTE: hard-coded the CAA date */} +
+ ⚠️ Papers searched from a pool updated as of 31st Dec 2025. +
{result.metadata.query && (
Query Used: "{result.metadata.query}" diff --git a/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/utils/common.tsx b/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/utils/common.tsx index 63263455..15b66877 100644 --- a/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/utils/common.tsx +++ b/webapp/_webapp/src/components/message-entry-container/tools/xtramcp/utils/common.tsx @@ -27,11 +27,12 @@ const XTRA_MCP_TOOL_NAMES = [ // REVIEWER TOOLS "review_paper", "verify_citations", + "generate_citations", // ENHANCER TOOLS // "enhance_academic_writing", // OPENREVIEW ONLINE TOOLS - // "search_user", - // "get_user_papers" + "search_user", + "get_user_papers" ]; export const isXtraMcpTool = (functionName: string): boolean => {