Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-backend-prd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-backend-stg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
2 changes: 2 additions & 0 deletions hack/prd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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 \
Expand Down
2 changes: 2 additions & 0 deletions hack/stg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions helm-chart/templates/paperdebugger-xtramcp-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
2 changes: 1 addition & 1 deletion helm-chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 26 additions & 10 deletions internal/api/user/list_prompts.go
Original file line number Diff line number Diff line change
Expand Up @@ -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: <your synthesized 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, <section name in paper>)",
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, <section name in paper>)",
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: <your synthesized 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,
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -67,6 +68,10 @@ export default function Tools({ messageId, functionName, message, error, prepari
return (
<VerifyCitationsCard functionName={functionName} message={message} preparing={preparing} animated={animated} />
);
} else if (functionName === "generate_citations") {
return (
<GenerateCitationsCard functionName={functionName} message={message} preparing={preparing} animated={animated} />
);
}

// Generic XtraMCP tool (not specialized)
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<div className={cn("tool-card", { animated: animated })}>
<div className="flex items-center justify-between">
<h3 className="tool-card-title">Generating your citations..</h3>
</div>
<LoadingIndicator text="Processing ..." estimatedSeconds={35} />
</div>
);
}

// Parse XtraMCP ToolResult format
const result = parseXtraMcpToolResult(message);

// No result or not ToolResult format - minimal display
if (!result) {
return (
<div className={cn("tool-card noselect narrow", { animated: animated })}>
<div className="flex items-center justify-between">
<h3 className="tool-card-title">{functionName}</h3>
</div>
</div>
);
}

// Error state
if (result.error || result.success === false) {
return (
<div className={cn("tool-card noselect narrow", { animated: animated })}>
{/* Header with Error label and arrow button */}
<div
className="flex items-center justify-between cursor-pointer"
onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)}
>
<h3 className="tool-card-title">{functionName}</h3>
<div className="flex items-center gap-2">
<span className="text-red-500 text-sm font-medium">Error</span>
<CollapseArrowButton
isCollapsed={isMetadataCollapsed}
ariaLabel={isMetadataCollapsed ? "Expand error" : "Collapse error"}
/>
</div>
</div>

{/* Error message dropdown */}
<CollapseWrapper isCollapsed={isMetadataCollapsed}>
<div className="text-xs text-red-600 mt-2 pt-2 border-t border-red-200">
{result.error || "Tool execution failed"}
</div>
</CollapseWrapper>
</div>
);
}

// 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 */}
<div className={cn("tool-card noselect narrow", { animated: animated })}>
{/* Header with arrow button */}
<div
className="flex items-center justify-between cursor-pointer"
onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)}
>
<h3 className="tool-card-title">{functionName}</h3>
<CollapseArrowButton
isCollapsed={isMetadataCollapsed}
ariaLabel={isMetadataCollapsed ? "Expand metadata" : "Collapse metadata"}
/>
</div>

{/* Metadata dropdown - INSIDE the tool card */}
{result.metadata && Object.keys(result.metadata).length > 0 && (
<CollapseWrapper isCollapsed={isMetadataCollapsed}>
<div className="text-xs text-gray-600 mt-2 pt-2 border-t border-gray-200">
{/* Custom metadata rendering */}
<div className="mb-2 italic">⚠️ [Experimental Feature] Some BibTeX entries may not be able to be generated.<br />Report if you encounter an unknown issue.</div>
{result.metadata.total_links !== undefined && (
<div>
<span className="font-medium">Total Links/IDs/Info:</span> {result.metadata.total_links}
</div>
)}
</div>
</CollapseWrapper>
)}
</div>

{/* CONTENT - OUTSIDE/BELOW the tool card, always visible */}
<div className="canselect text-sm mt-2">
<MarkdownComponent animated={animated}>{result.content}</MarkdownComponent>
</div>
</>
);
}

// Fallback - unknown format
return (
<div className={cn("tool-card noselect narrow", { animated: animated })}>
<div className="flex items-center justify-between">
<h3 className="tool-card-title">{functionName}</h3>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ export const SearchRelevantPapersCard = ({ functionName, message, preparing, ani
{result.metadata && Object.keys(result.metadata).length > 0 && (
<CollapseWrapper isCollapsed={isMetadataCollapsed}>
<div className="text-xs text-gray-600 mt-2 pt-2 border-t border-gray-200">
{/* Custom metadata rendering */}
{/* Custom metadata rendering; NOTE: hard-coded the CAA date */}
<div className="mb-2">
<span className="font-medium">⚠️ Papers searched from a pool updated as of 31st Dec 2025.</span>
</div>
{result.metadata.query && (
<div className="mb-2">
<span className="font-medium">Query Used:</span> "{result.metadata.query}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down