duo-metrics-mcp
README.md
# duo-metrics-mcp
Personal Duolingo metrics MCP server for AI assistants.
`duo-metrics-mcp` lets an MCP-compatible assistant answer daily language-learning
questions such as:
- Did I practice Duolingo today?
- How much XP did I earn today?
- How many sessions did I complete?
- How much time did I spend practicing?
- What is my current streak?
- What did my last week or month of Duolingo activity look like?
The server uses Duolingo's unofficial web endpoints. Public profile lookup works
without authentication. Daily XP summaries require an authenticated Duolingo web
session cookie.
## Status
This is an unofficial personal-use MCP server. Duolingo does not publish or
support these endpoints for third-party API use, so endpoint behavior can change
without notice.
The current implementation is intentionally lightweight:
- no database
- no background scheduler
- no password login
- live API reads on demand
- optional local ignored session file for authenticated calls
## Tools
### `duolingo_get_public_profile`
Fetches public profile data by username.
Authentication: not required.
Useful for:
- user id discovery
- public streak data
- total XP
- active course
- course XP split
Input:
```json
{
"username": "JoaoPedroS572669"
}
```
### `duolingo_get_authenticated_profile`
Fetches the richer authenticated profile by user id.
Authentication: required.
Input:
```json
{
"userId": 955434155472097
}
```
### `duolingo_get_xp_summaries`
Fetches daily XP summaries, including sessions, total practice time, and streak
extension status.
Authentication: required.
Input:
```json
{
"userId": 955434155472097,
"startDate": "2026-06-01",
"endDate": "2026-06-20",
"timezone": "America/Sao_Paulo",
"readable": true
}
```
Example output:
```json
{
"userId": 955434155472097,
"timezone": "America/Sao_Paulo",
"summaries": [
{
"date": "2026-06-20",
"gainedXp": 353,
"numSessions": 11,
"totalSessionTimeSeconds": 1057,
"totalSessionTimeMinutes": 17.6,
"streakExtended": true,
"frozen": false,
"repaired": false,
"dailyGoalXp": 1,
"shielded": false
}
]
}
```
### `duolingo_today_status`
Returns a compact daily status for assistant workflows.
Authentication: required.
Input:
```json
{
"userId": 955434155472097,
"timezone": "America/Sao_Paulo"
}
```
Example output:
```json
{
"userId": 955434155472097,
"date": "2026-06-20",
"timezone": "America/Sao_Paulo",
"playedToday": true,
"xpToday": 353,
"sessionsToday": 11,
"minutesToday": 17.6,
"streakExtended": true
}
```
### `duolingo_auth_help`
Explains the supported authentication configuration to the assistant.
Authentication: not required.
## Requirements
- Node.js 20 or newer
- npm
- an MCP-compatible client that supports stdio servers
## Installation
Clone and build:
```powershell
git clone https://github.com/Tavaresiqueira/duo-metrics-mcp.git
cd duo-metrics-mcp
npm install
npm run build
```
Run the server manually:
```powershell
npm start
```
For development:
```powershell
npm run dev
```
Run the smoke test:
```powershell
npm run smoke
```
The smoke test builds the project, starts the MCP server through stdio, lists the
available tools, calls the public profile tool, and verifies the missing-auth
path for authenticated tools.
## Configuration
The server reads defaults from environment variables:
```powershell
$env:DUOLINGO_USERNAME = "JoaoPedroS572669"
$env:DUOLINGO_USER_ID = "955434155472097"
```
These defaults let assistants call tools without repeating the username or user
id on every request.
## Authentication
Public profile data does not require authentication.
Daily XP summaries require an authenticated Duolingo session cookie. The server
supports two auth modes:
1. `DUOLINGO_COOKIE` environment variable
2. `.duolingo-session.json` in the repo root
### Environment Variable
Set the full Cookie header before starting the MCP server:
```powershell
$env:DUOLINGO_COOKIE = "jwt_token=...; logged_out_uuid=...; ..."
npm start
```
### Local Session File
Create `.duolingo-session.json`:
```json
{
"cookie": "jwt_token=...; logged_out_uuid=...; ...",
"createdAt": "2026-06-20T18:00:00Z",
"source": "manual browser session"
}
```
This file is ignored by git.
You can also create it from the environment variable:
```powershell
$env:DUOLINGO_COOKIE = "jwt_token=...; logged_out_uuid=...; ..."
npm run save-session
Remove-Item Env:\DUOLINGO_COOKIE
```
### Getting a Cookie
Use a browser where you are already logged in to Duolingo:
1. Open `https://www.duolingo.com/learn`.
2. Open browser developer tools.
3. Go to the Network tab.
4. Reload the page.
5. Select a request to `www.duolingo.com`.
6. Copy the request `Cookie` header.
7. Store it as `DUOLINGO_COOKIE` or in `.duolingo-session.json`.
Do not commit cookies, tokens, or session files.
## MCP Client Setup
Use the built server over stdio.
Example config:
```json
{
"mcpServers": {
"duo-metrics": {
"command": "node",
"args": [
"C:\\Users\\joao.siqueira\\Documents\\duo-metrics-mcp\\dist\\index.js"
],
"env": {
"DUOLINGO_USERNAME": "JoaoPedroS572669",
"DUOLINGO_USER_ID": "955434155472097"
}
}
}
}
```
If you want authenticated tools without a `.duolingo-session.json` file, include
`DUOLINGO_COOKIE` in the MCP environment block. Prefer the local session file for
personal desktop use so the cookie does not sit in a shared config file.
## Best Usage
This MCP works best as a small daily workflow source, not as a full Duolingo
clone.
Good assistant prompts:
```text
Check whether I completed Duolingo today.
```
```text
Show my Duolingo XP for the last 7 days.
```
```text
Include my Duolingo streak and today's XP in my evening shutdown.
```
```text
Compare today's Duolingo effort against the last 14 days.
```
```text
Before I stop working, confirm whether my Duolingo streak is safe.
```
Recommended workflow:
1. Keep `DUOLINGO_USERNAME` and `DUOLINGO_USER_ID` configured.
2. Keep `.duolingo-session.json` local and ignored.
3. Let the assistant call `duolingo_today_status` during daily check-ins.
4. Use `duolingo_get_xp_summaries` for weekly/monthly review prompts.
5. Refresh the session cookie only when Duolingo starts returning `401`.
## Troubleshooting
### Authenticated tools return missing session
Set `DUOLINGO_COOKIE` or create `.duolingo-session.json`.
### Authenticated tools return `401`
Your session probably expired. Log in to Duolingo in the browser again, copy a
fresh Cookie header, and update `.duolingo-session.json`.
### Public profile lookup fails
Check that the username is the Duolingo username, not the email address. The
username is case-insensitive for lookup, but the returned profile may use
Duolingo's canonical casing.
### Dates look off by one day
Pass the timezone explicitly:
```json
{
"timezone": "America/Sao_Paulo"
}
```
## Privacy
This server can access personal Duolingo account data when configured with a
session cookie. Treat `.duolingo-session.json` like a secret.
The project intentionally avoids password-based login. It only uses an existing
web session cookie that you provide.
## Development
Useful commands:
```powershell
npm run build
npm run typecheck
npm run smoke
```
Project layout:
```text
src/index.ts MCP server and tool registration
src/duolingoClient.ts Duolingo endpoint client and normalization
src/config.ts Environment/session-file configuration
src/types.ts Shared TypeScript types
scripts/save-session.mjs
scripts/smoke-test.mjs
```
## Limitations
- Duolingo endpoints are unofficial.
- Session cookies can expire.
- Some browser cookies are `HttpOnly`, so they cannot be read from
`document.cookie`.
- The server does not currently persist long-term history.
- The server does not currently automate login.
TDQS
A3.6/5.0
Scored across 5 tools
Disambiguation5/5
Each tool targets a distinct aspect of Duolingo data: public profile, authenticated profile, XP summaries, today's status, and auth configuration. There is no overlap in purpose.
Naming Consistency4/5
All tools share the 'duolingo_' prefix and use snake_case, but 'today_status' and 'auth_help' deviate from the 'get_' verb pattern used by the other three. Minor inconsistency.
Tool Count5/5
Five tools is ideal for a focused metrics server covering public info, authenticated details, daily summaries, and configuration. No tool feels redundant or missing.
Completeness4/5
Core Duolingo metrics (profile, XP, streak, daily activity) are covered. Missing historical trends or leaderboard data, but the set is practical for most use cases.
Maintenance
ActivityInactive
ResponsivenessNo issues