Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
지원 현황을 칸반 보드로 관리하고, AI가 작성한 이력서·자소서와 검색 분석을 제공해 다음 직장을 잡아줍니다
Track applications on a Kanban board, get AI-drafted resumes and cover letters grounded in your real experience, and see the analytics behind your search. Everything you need to land your next role.
비즈니스TypeScript · HTMLGitHub @mankatcheung온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Trakwyn is a job application tracker that helps you manage your job search end to end: log applications, track interview rounds and offers, keep notes and documents attached to each one, and get AI-assisted help drafting cover letters and filling in job descriptions.
The project is a monorepo with a GraphQL API, a web app, a browser extension for clipping job postings, and a CLI.README 전문 보기 ↗Trakwyn is a job application tracker that helps you manage your job search end to end: log applications, track interview rounds and offers, keep notes and documents attached to each one, and get AI-assisted help drafting cover letters and filling in job descriptions.
The project is a monorepo with a GraphQL API, a web app, a browser extension for clipping job postings, and a CLI.
| App | Path | Description |
|---|---|---|
| API | apps/api | Fastify + Mercurius + Pothos GraphQL server, following Clean Architecture. Owns auth, data, and all business logic. |
| Web | apps/web | TanStack Start (SSR React) frontend — the main UI for managing applications. |
| Extension | apps/extension | Browser extension ("Trakwyn Clipper") that saves job postings from LinkedIn, Indeed, and Glassdoor straight to your account. |
| CLI | apps/cli | tw command-line tool for authenticating and managing applications from the terminal. |
The API ships a Model Context Protocol server, so an AI assistant can read your job-search data, answer questions about it, and — with full access — log applications and notes for you.
Most tools are read-only, and read-only access can only reach those. A few tools create or update data; they require full access and are refused outright otherwise. Nothing deletes — there are no delete tools at all.
Most MCP clients — Claude Desktop, Cursor, Claude Code, and others — support OAuth, which is the easiest way to connect: nothing to copy, paste, or store yourself. docs/mcp-oauth.md walks through the whole flow and the reasoning behind it; the summary is below.
Point your client at the endpoint, POST https://api.trakwyn.com/mcp. The
client discovers the authorization server from:
GET https://api.trakwyn.com/.well-known/oauth-protected-resourceGET https://api.trakwyn.com/.well-known/oauth-authorization-serverThe authorization server supports dynamic public-client registration, the
authorization-code flow with PKCE (S256), rotating refresh tokens, and token
revocation. Redirect URIs must be exact HTTPS URLs, or loopback HTTP URLs for
local clients. The authorization flow uses your existing Trakwyn browser
session and displays an explicit MCP consent screen before issuing a code —
sign in, approve, and the client is connected.
The consent screen asks for one of two scopes: a read grant reaches the
read-only tools and nothing else; full also reaches the tools that create or
update records. Start with read unless the client genuinely needs to write.
Revoking is grant-wide. POST /oauth/revoke accepts either an access token or
a refresh token, and either one takes down every credential issued from that
consent — so a client cannot "revoke" and then quietly refresh its way back in.
The same happens automatically if an authorization code or a rotated refresh
token is ever replayed, since that means the credential leaked.
Deploy prerequisite: set API_ORIGIN to this API's own public origin (e.g.
https://api.trakwyn.com). It is what the discovery documents advertise as the
issuer and endpoint URLs; without it they fall back to the request's Host
header, which a caller controls.
For Claude Code:
claude mcp add --transport http trakwyn https://api.trakwyn.com/mcp
For a script, a CI job, or a client that doesn't support OAuth, a manually
created API token works the same way a read/full OAuth grant does:
trakwyn_…) — it's shown only once.Authenticate with Authorization: Bearer <token> instead of an OAuth access
token — the endpoint accepts either. Existing trakwyn_... tokens keep working
regardless of how many clients connect over OAuth.
Verify it works:
curl -s https://api.trakwyn.com/mcp \
-H "Authorization: Bearer trakwyn_your_token_here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
You should get a JSON-RPC response listing the tools below. To fetch data:
curl -s https://api.trakwyn.com/mcp \
-H "Authorization: Bearer trakwyn_your_token_here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"list_applications","arguments":{"status":"interviewing"}}}'
For Claude Code with a token instead of OAuth:
claude mcp add --transport http trakwyn https://api.trakwyn.com/mcp \
--header "Authorization: Bearer trakwyn_your_token_here"
Transport caveat: this endpoint is plain JSON-RPC over
POST— there is noGET/SSE endpoint and no session management, so it implements only the subset of MCP's Streamable HTTP transport that request/response tooling needs. Thecurlcalls above are covered by integration tests and are known to work. Clients that require SSE or session negotiation may not connect; if yours doesn't, that's the likely reason.
All are scoped to the authenticated user — a token can never read another account's data.
list_applications is paginated: it returns { items, hasNextPage, nextCursor }. Pass the returned nextCursor back to fetch the following page. Everything else returns its records directly.
| Tool | Arguments |
|---|---|
list_applications | status, limit, cursor (all optional) |
get_application | applicationId |
list_notes | applicationId |
list_contacts | applicationId |
list_interview_rounds | applicationId |
list_work_experiences | — |
list_educations | — |
list_skills | — |
list_documents | applicationId |
list_offers | applicationId |
list_activity | applicationId |
list_calendar_events | — |
get_analytics | — |
A full-access token also reaches these write tools, which create, update or trash records (required arguments shown; each also accepts further optional fields to set):
| Tool | Required arguments |
|---|---|
create_application | company, role |
update_application | applicationId |
trash_application | applicationId |
create_note | applicationId, content |
update_note | noteId, content |
create_contact | applicationId, name |
update_contact | contactId |
create_interview_round | applicationId |
update_interview_round | interviewRoundId |
create_offer | applicationId, baseSalary |
update_offer | offerId |
create_skill | name |
update_skill | skillId |
create_education | institution, startDate |
update_education | educationId |
create_work_experience | company, title, startDate |
update_work_experience | workExperienceId |
trash_application moves the application to Trash, where it can be restored from the web app for 30 days. Nothing is permanently deleted over MCP. create_offer needs a plan with offers and answers PLAN_REQUIRED (in error.data.code) otherwise.
Every tool in tools/list carries MCP tool annotations (readOnlyHint, destructiveHint, idempotentHint), so a client can ask before calling a write tool. trash_application is the only one marked destructive.
Server identifies as trakwyn-mcp v1.0.0. It speaks MCP protocol 2025-03-26 and still accepts 2024-11-05: initialize answers with the client's version when it is one of those, otherwise with 2025-03-26. Supported methods: initialize, tools/list, tools/call.
For local development the endpoint is http://localhost:3001/mcp.
Install dependencies (from the repo root):
pnpm install
Configure environment variables — copy both example env files and fill them in:
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env
In apps/api/.env, at minimum set:
DATABASE_URL — an absolute path to a local SQLite file, e.g. file:/absolute/path/to/trakwyn/apps/api/local.dbJWT_SECRET and JWT_REFRESH_SECRET — any strong random valuesTOTP_ENCRYPTION_KEY and LLM_API_KEY_ENCRYPTION_KEY — any strong random valuesEverything else in apps/api/.env.example (OAuth, email, push, Redis, observability) is optional for local dev and can be left blank — those features are simply disabled until configured.
Apply database migrations:
pnpm db:migrate
Run the app (starts both the API and web app):
pnpm dev
The API runs at http://localhost:3001 and the web app at http://localhost:3000 (proxying /graphql to the API).
pnpm build # Build all packages
pnpm typecheck # Type-check all packages
pnpm test # Run all tests
pnpm lint # Lint
pnpm format # Format with Prettier
cd apps/api && pnpm db:studio # Open Drizzle Studio to inspect the local DB
# GraphQL codegen (requires the API running at localhost:3001)
cd apps/web && pnpm codegen
See CLAUDE.md for architecture details and development conventions.
The API and web app deploy on every merge to main and are identified by commit SHA. They also share one version (tagged api-v… and web-v…, for example to pin a self-hosted install), alongside the browser extension, the mobile app and the CLI, with release-please:
fix or feat commits on main has an open release PR, kept up to date on every merge. The version bump and changelog come from the commit titles (fix is a patch, feat a minor, ! a major).clipper-v0.2.0) and creates a GitHub Release.Versions live in each package's package.json and are never edited by hand.