keep-it-markdown: pulling Google Keep notes into Obsidian, Logseq and Apple Notes
Export and convert Google Keep notes dynamically to markdown for Obsidian, Apple Notes, Logseq, Joplin and Notion using the unofficial Keep API. Also, import simple markdown notes back into Google Keep.
At a glance
- What is it?
- keep-it-markdown, or KIM, reads Google Keep through the unofficial gkeepapi and writes each note out as a markdown file, with an import path that puts simple markdown notes back into Keep. It suits someone who captures notes in Keep on any device and wants them in a local markdown vault, and it depends on an API Google never promised to keep.
- Who is it for?
- keep-it-markdown fits a note taker who wants Google Keep as a capture device and a local markdown vault as the system of record, and it does not fit anyone who needs a supported, guaranteed API contract.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why an unofficial API, and what that means for the tool's lifespan
keep-it-markdown, usually shortened to KIM, converts Google Keep notes to markdown using the unofficial Python Keep API, without having to use Google Takeout to export notes first. It can also import markdown notes back to Keep, and the script runs on Windows, macOS or Linux.
The interesting design decision is skipping Takeout. A Google Takeout export is a zip of HTML files with a manifest, which you then have to convert into whatever format your notes app wants. KIM goes the other way: it talks to Keep as a client would, using the gkeepapi library, and asks the service for the notes directly. That is why the tool is a script with a search prompt rather than a converter you point at a folder.
The readme is explicit about the risk in one sentence, and it is the most important line in the document: unofficial implies that Google could change the API at any time that might stop the script from working. The library underneath is gkeepapi, and the token KIM uses is a Keep token, not a Google OAuth credential.
The stated goal is to use Google Keep as an easy way to capture raw notes on all devices, or additionally using the browser plugin, and then query notes for export to markdown files directly into notetaking apps such as Obsidian, Logseq, Apple Notes, Joplin and Notion, or used directly with Typora.
So the audience is a specific person: someone whose capture habit is Google Keep and whose thinking tool is a local markdown vault.
The token dance: a browser cookie, an OAuth value and a fake Android ID
Authentication is the hardest part of the installation, and the readme is refreshingly honest about how awkward it is.
KIM requires a Google Keep authentication token. The token can only be retrieved once you have a Google page OAuth cookie, and the documented route is to install the Chrome extension called Cookie Tab Viewer, follow the Second way instructions in the linked gpsoauth-java repository, press I agree on the Google page, and then read the cookie value with the extension. You copy the cookie called oauth_token, and then run the token script:
> python get_token.pyYou are prompted for your Google email account name, the OAuth token and an Android ID. The Android ID can just be a random value, the readme suggests something like abcdef123, because the Keep API expects a device identifier and the tool is not registering a real device.
The output is a Keep token that looks like aas_et/FKcp... with a run of characters, and the readme asks you to copy that token and save it in a safe place. It also warns that the OAuth token may have expired, that it takes about 5 minutes to expire, and that you should run the step again until it works.
That five-minute window is the sharpest operational detail in the document. It means the setup is not a one-time thing in the way the readme says the installation steps are, because a token minted from an expired OAuth cookie fails, and you find out by running the script again.
Storing the token in the keyring, and the interactive query loop
Once you have a Keep token, KIM stores it in a local secure keyring rather than a config file:
> python kim.py -t <your long token value here>If the email and token are correct, you should see a successful login and the statement that you have successfully logged into Google Keep.
From then on the tool runs interactively:
> python kim.pyand you get a prompt asking for a case sensitive keyword or label search, or --all to convert Keep notes to markdown, or --x to exit.
Two behaviours matter for planning a large export. Entering a query term and pressing Enter executes your first export of a note or a set of notes as individual markdown files from your active note list, and all queries to convert ignore notes in archive and trash unless you use the option flags. The tool stays active to do more conversions until you press --x or Ctrl-C.
So this is an interactive search and export loop, not a batch job with a directory argument. That is the right shape for a personal library where you want to export a label at a time, and it is a different shape from a scripted sync.
Where the output lands, and the settings file you can edit
The output location is the detail that surprises people, so it is worth stating exactly.
On the first run, KIM creates a settings.cfg file in the directory where you chose to install it, and you can edit that with a text editor. The keys are google_userid, which is your Google account id and allows you to bypass typing it in, output_path, the path where the output markdown files are created, which if empty is your install directory, and media_path, the location of the exported media files, images and audio, relative to your output_path. The readme gives the composition rule: if the output_path is /mdexport and media_path is media/data, the media full path will be /mdexport/media/data. Media paths cannot start with /, mount or drive letter. Windows users use forward slashes, for example c:/md-files/export.
The default, as the readme notes, is that on the first execution exported markdown files are created in a default KIM sub-directory called mdfiles within your install directory, and images are exported into media within the default directory. This can be changed later.
The advice that follows is practical: for the first test, use a keyword query that returns and converts only a few notes at most, and the readme suggests doing the same search in Keep first to see how many notes your query will return.
A separate switch covers the import direction, and the readme points to the -i switch for the import settings, which are configured separately from the export ones.
Labels, titles and the option flags, with EXAMPLES.md as the reference
Query syntax is minimal, and that is a feature. Searching for notes by labels just requires the # character in front of the search term, so #MyLabel finds a label, and on some operating systems like Linux you may need to enclose the term in quotes. Titles and keywords work the same way, and a query can be a single word, a phrase or a label.
Everything else is a flag, and the readme deliberately does not enumerate them. The instruction is to discover all KIM options with the help output:
> python kim.py --helpand to see many option combinations in EXAMPLES.md, which is one of the top-level files in the repository. The visible flags in the readme are the archive and trash inclusion flags, the -t option for setting the token, the -i switch for import, --all to convert everything, and --x to exit.
That split between the readme and the examples file is worth noting for anyone writing a wrapper or a scheduled job. The interaction model is the documented interface, the flags are discoverable, and the semantics of a given flag combination live in EXAMPLES.md rather than in the readme's option list.
The repository also carries APPLE-NOTES.md and NOTION.md as separate documents, which is the tell that the target apps differ in how the output has to be shaped. A markdown file that Obsidian opens happily is not automatically a note that Apple Notes imports, and the tool handles those differences outside the core conversion.
Running it in Docker, and the dependencies behind it
The repository ships a Dockerfile, and the readme refers to an Advanced Docker Setup for people who hit login problems or cannot get a browser cookie on the host.
The image is built from ubuntu:22.04, installs python-is-python3, python3-pip, curl and ca-certificates, downloads the release tarball for version 0.7.1 from GitHub, extracts it, installs keyrings.alt and then the requirements. The Dockerfile in the repository stops there, with no entrypoint, which tells you the container is meant to be run interactively rather than as a service.
The dependencies are worth listing because they show what the tool actually needs. requirements.txt names gkeepapi, which is the unofficial Keep API client, keyring, which is where the token is stored, click, which is the command line interface, and pillow, which is the image library. The file also carries a section of commented-out pinned versions, gkeepapi 0.13.1, keyring 17.1.1 and click 7.1.2, with a note that they were worked with Python 3.7.3, so the current versions are the unpinned ones and the pins are historical.
The licence is Apache-2.0, the repository is not archived, and the last push was on 2026-10-14. The recent releases are 0.7.1 from 2026-08-23, 0.7.0 from 2026-05-23 and 0.6.9 from 2026-03-23, so the project is shipping regularly.
What the tool does not promise, and the questions to settle first
The readme's own warnings are the most useful part of it for an evaluator.
First, the unofficial API. The readme says it in bold and repeats it, and it is the reason to think of KIM as a convenience script rather than infrastructure. The whole tool rests on gkeepapi, which is a reverse-engineered client, and the OAuth cookie flow with a five-minute expiry and a fabricated Android ID is a good illustration of what that means in practice.
Second, the import direction is limited. The description says KIM can import simple markdown notes back into Keep, and the word simple is doing the work. A markdown file with links, tables, front matter or a heading hierarchy is not necessarily a note that Keep will hold, and the readme does not document what happens to the parts it cannot represent.
Third, the visible documentation does not cover conflict handling, scheduled or unattended operation, or what happens when a note is edited in Keep after you have exported it. KIM writes individual markdown files, and nothing in the readme describes a merge or sync strategy, so a two-way workflow is a manual thing.
For a first run, the sensible sequence is the one the readme implies: set the token, run one narrow query on a handful of notes, look at the mdfiles directory and the media directory, then decide whether the output is what your vault wants before letting it loose on a library of thousands.
Editorial conclusion
keep-it-markdown fits a note taker who wants Google Keep as a capture device and a local markdown vault as the system of record, and it does not fit anyone who needs a supported, guaranteed API contract. Before you rely on it, read the Key Callouts section the readme refers to, keep your Keep token in a safe place because the OAuth cookie it comes from expires in about five minutes, and export a small set of notes first, since the default output directory is created inside the install directory rather than where you would expect.
Frequently asked questions
What is keep-it-markdown and what does it convert?
It is a Python script, usually called KIM, that converts Google Keep notes to markdown using the unofficial gkeepapi without needing a Google Takeout export first. The output is individual markdown files aimed at Obsidian, Logseq, Apple Notes, Joplin, Notion and Typora, and KIM can also import simple markdown notes back into Keep.
How do I get a Google Keep token for keep-it-markdown?
KIM needs a Keep token, and the readme's route is to install the Cookie Tab Viewer Chrome extension, follow the Second way instructions in the linked gpsoauth-java repository, copy the oauth_token cookie, then run python get_token.py with your Google email, that token and a random Android ID. The OAuth token expires in about five minutes, so you may have to repeat the step until it works.
Where does keep-it-markdown put the exported files?
On the first run it creates a settings.cfg in the install directory with google_userid, output_path and media_path keys. By default the markdown files go to a KIM sub-directory called mdfiles inside the install directory and images to a media sub-directory, and both paths can be changed in that settings file, with media_path relative to output_path and using forward slashes on Windows.
How do I search and export notes with KIM?
Run python kim.py and you are prompted for a case sensitive keyword or label search, or --all to convert every note, or --x to exit. A label search uses the # character in front of the term, for example #MyLabel, and all queries ignore notes in archive and trash unless you use the option flags, with KIM staying active for more conversions until you exit.
What does keep-it-markdown need to run?
Python 3.10 or greater, the dependencies in requirements.txt which are gkeepapi, keyring, click and pillow, and a Keep token stored in the local keyring with python kim.py -t. The script runs on Windows, macOS and Linux, and a Dockerfile based on ubuntu:22.04 is included for running it in a container.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/djsudduth-keep-it-markdown)Was this useful?