Skip to main content
Glama

import_bibtex

Add BibTeX entries to Zotero for organized reference management. Specify a collection to organize imported citations.

Instructions

Import BibTeX entries into Zotero

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bibtexYes
collection_keyNo

Implementation Reference

  • The tool registration and entry point for importing BibTeX.
    @mcp.tool(description="Import BibTeX entries into Zotero")
    def import_bibtex(bibtex: str, collection_key: str = "") -> str:
        """Parse BibTeX string and create items in Zotero."""
        keys = _get_client().import_bibtex(bibtex, collection_key)
        return json.dumps({"created_keys": keys, "count": len(keys)}, ensure_ascii=False)
  • The business logic implementation for processing BibTeX string and creating items.
    def import_bibtex(self, bibtex: str, collection_key: str = "") -> list[str]:
        """Import BibTeX entries. Returns list of created item keys."""
        entries = self._parse_bibtex(bibtex)
        keys = []
        for entry in entries:
            if collection_key:
                entry["collections"] = [collection_key]
            resp = self.zot.create_items([entry])
            created = resp.get("successful", resp.get("success", {}))
            if created:
                val = list(created.values())[0] if isinstance(created, dict) else created[0]
                key = val.get("key", val.get("data", {}).get("key", "")) if isinstance(val, dict) else str(val)
                keys.append(key)
        return keys
  • The helper function that performs the actual regex-based parsing of the BibTeX input string.
    @staticmethod
    def _parse_bibtex(bibtex: str) -> list[dict]:
        """Parse BibTeX string into Zotero item dicts."""
        entries = []
        pattern = r"@(\w+)\{([^,]*),(.*?)\n\}"
        for match in re.finditer(pattern, bibtex, re.DOTALL):
            bib_type = match.group(1).lower()
            body = match.group(3)
    
            type_map = {
                "article": "journalArticle",
                "inproceedings": "conferencePaper",
                "conference": "conferencePaper",
                "book": "book",
                "incollection": "bookSection",
                "phdthesis": "thesis",
                "mastersthesis": "thesis",
                "misc": "document",
                "techreport": "report",
            }
            item_type = type_map.get(bib_type, "document")
    
            fields = {}
            for fmatch in re.finditer(r"(\w+)\s*=\s*\{(.*?)\}", body, re.DOTALL):
                fields[fmatch.group(1).lower()] = fmatch.group(2).strip()
    
            creators = []
            if "author" in fields:
                for author in re.split(r"\s+and\s+", fields["author"]):
                    parts = [p.strip() for p in author.split(",", 1)]
                    if len(parts) == 2:
                        creators.append({
                            "creatorType": "author",
                            "firstName": parts[1],
                            "lastName": parts[0],
                        })
                    else:
                        name_parts = parts[0].rsplit(" ", 1)
                        creators.append({
                            "creatorType": "author",
                            "firstName": name_parts[0] if len(name_parts) > 1 else "",
                            "lastName": name_parts[-1],
                        })
    
            item = {
                "itemType": item_type,
                "title": fields.get("title", ""),
                "creators": creators,
                "date": fields.get("year", ""),
                "DOI": fields.get("doi", ""),
                "url": fields.get("url", ""),
                "abstractNote": fields.get("abstract", ""),
            }
    
            if item_type == "journalArticle":
                item["publicationTitle"] = fields.get("journal", "")
                item["volume"] = fields.get("volume", "")
                item["pages"] = fields.get("pages", "")
            elif item_type == "conferencePaper":
                item["conferenceName"] = fields.get("booktitle", "")
            elif item_type == "bookSection":
                item["bookTitle"] = fields.get("booktitle", "")
            elif item_type == "book":
                item["publisher"] = fields.get("publisher", "")
    
            entries.append(item)
    
        return entries

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/BirdInTheTree/zotero-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server