Batcave-MCP
Batcave — レジュメレビューMCPサーバー
2つのドキュメント — レジュメ と 求人情報 — を受け取り、3段階のレビューを実行するMCPサーバーです。各段階は次の段階に受け渡されます。マッチレポートができる前に書き換えはできず、書き換えができる前にATSパスは実行できません。
パイプライン
ツール | 機能 |
| 受け付け。レジュメと求人情報を生テキストまたは |
| ステージ1。 対象企業のシニアリクルーター: 100点満点のマッチスコア、不足しているキーワード上位5件、採用担当者が10秒以内に見つける3つのレッドフラグ。 |
| ステージ2。 経験セクションを、ステージ1のキーワードを盛り込みレッドフラグを除去する形で書き換えます。すべての箇条書きはGoogle XYZ形式 — Xを達成し、Yで測定され、Zを行うことによって。 |
| ステージ3。 ATSパーサーパスに加え、200件中147件目のレジュメを見る採用担当者: どのセクションがスキップされるかを特定し、スクロールを止めるように書き換えます。最終レジュメを返します。 |
| どのステージが完了済みか、結果待ちか、未開始か、次に何を呼ぶべきかを示します。 |
| 保存済みセッションを、最近更新された順に表示します。 |
| レビュー全体 — 3つのステージすべてと最終レジュメ — を1つのマークダウンドキュメントとして返します。 |
| セッションとそれに関連付けられたすべてのデータを削除します。自動的に期限切れになるものはありません。 |
Related MCP server: ats-resume-writer
ステージの実行方法
サーバーはモデルを呼び出しません。ブリーフを構成し、状態を保持し、順序を強制します。推論を行うのは接続されたクライアントのモデルです。したがって、各ステージツールは2回呼び出されます:
{ session_id }— そのステージの分析ブリーフを返します。レジュメ、求人情報、およびそれ以前のすべてのステージの出力がすでに埋め込まれています。{ session_id, result }— 回答を記録します。resultはステージのスキーマに対して検証されるため、4つのキーワードしかないレポートは保存されずに拒否されます。
ステージ2は記録されたステージ1のレポートを読み取ります。ステージ3はオリジナルではなく、ステージ2の updated_resume を読み取ります。順序を無視して呼び出されたステージは、最初に呼び出す必要があるツール名とともに失敗します。
ブリーフに組み込まれた2つのルール
捏造された数値は禁止。 元のレジュメに数値がない場合、書き換えは
[QUANTIFY: 測定するもの]を出力し、それをplaceholders_needing_user_inputにリストします。キーワードの詰め込みは禁止。 キーワードは実際の経験がそれを裏付ける場合にのみ入れられ、残りは理由とともに
keywords_not_addressedに返されます。
トランスポート
2つのエントリーポイント、同じツール:
エントリー | トランスポート | 用途 |
| stdio | 同じマシン上のクライアント — Claude Code、IDE |
|
| リモートクライアント — コンテナ内で実行されるのはこちら |
stdioは1台のマシン上の2つのプロセス間のパイプであり、ネットワーク経由で到達することはできません。stdioを提供するコンテナは接続を受け付けないため、EC2パスが serve.ts を使用するのはそのためです。
serve.ts は2つの変数を必要とし、どちらかがなければ起動を拒否します:
DB_URL— Postgres接続文字列MCP_AUTH_TOKEN— 共有シークレット。すべてのリクエストにAuthorization: Bearer <token>が必要です。
GET /healthz は認証不要の唯一のルートです。データベース接続を開かないため、それをポーリングするロードバランサーがPostgresを起動することはありません。
ストレージ
すべてはPostgresに保存されます。サーバーはローカルディスクに何も書き込みません — ローカルで読み取るのは、指定したレジュメと求人情報のファイルのみです。
resume_sessions(id, created_at, updated_at, company, role,
resume jsonb, job_description jsonb)
resume_stages(session_id -> resume_sessions.id on delete cascade, stage, status,
issued_at, completed_at, result jsonb, primary key (session_id, stage))
schema_migrations(module, id, applied_at) -- shared, owned by src/platform/db.ts1つのドキュメントではなく2つのテーブルを使用するため、ステージの記録は両方のレジュメを書き換えるのではなく1行を書き込むだけで済み、list_sessions はドキュメントテキストをまったく選択しません。テーブルにはモジュールのプレフィックスが付けられ、マイグレーションはそのモジュールの最初のクエリで遅延実行されます — サーバーの起動はデータベースを起動しません。
マイグレーションは追記のみで、schema_migrations に記録されるため、各マイグレーションはデータベースごとに正確に1回実行されます。bun run db:migrate は保留中のものを適用します。サーバーはフォールバックとして、モジュールの最初のクエリでも遅延実行します。
自動的に期限切れになるものはありません。セッションは delete_session が削除するまで蓄積されます。
実行方法
bun install
bun run dev # Postgres + the server, hot reload, nothing to configureこれは docker compose -f docker-compose.dev.yml up --build です: Postgresを起動し、開発用とテスト用のデータベースを作成し、マイグレーションを実行し、トークン dev-token-not-a-secret で http://127.0.0.1:3000/mcp でMCPを提供します。src/ 配下の何かを編集すると、実行中のサーバーがリロードされます。
代わりにホスト上でサーバーを直接実行するには:
export DB_URL='postgres://postgres:postgres@localhost:55432/batcave'
bun start # stdio, for a client on this machine
bun run serve # HTTP on :3000, also needs MCP_AUTH_TOKENサーバーの実行を必要としない2つのデータベースコマンド:
bun run db:check # can this machine reach DB_URL, and what is in it?
bun run db:migrate # create or update the tables; safe to run repeatedlydb:check は、サービスを提供せずに接続を開く唯一のものです。両方のエントリーポイントは起動時に DB_URL を検証しますが、最初のクエリで遅延接続するため、クリーンな起動は何も証明しません。
チェック:
bun run check # Biome format + lint (check:fix to apply)
bun run typecheck
bun test # unit tests; no database needed
TEST_DB_URL='postgres://postgres:postgres@localhost:55432/batcave_test' bun testエンドツーエンドテストは、実際のPostgresに対して実際のワイヤープロトコルで通信し、ティアダウン時にテーブルを削除します。これらは DB_URL ではなく、意図的に TEST_DB_URL を読み取るため、サーバーを実際のデータベースに向けてもティアダウンを仕掛けることはできません — また、開発スタックには別の batcave_test データベースが同梱されているため、テストを実行しても実行中のサーバーを妨げることはありません。
このディレクトリの .mcp.json は、Claude Code用にstdioサーバーを登録します。別のクライアントの場合:
{ "command": "bun", "args": ["index.ts"], "cwd": "/path/to/Batcave" }EC2での実行方法
export DB_URL='postgres://user:pass@host/db?sslmode=require'
export MCP_AUTH_TOKEN="$(openssl rand -hex 32)"
bun run db:check # confirm the instance is reachable from this box
docker compose run --rm mcp bun scripts/migrate.ts # create the tables
docker compose up -d --build
docker compose logs -f mcpサーバーがトラフィックを受ける前にマイグレーションを実行してください。 これをスキップすると、最初のツール呼び出しで自動的にマイグレーションされますが、その場合、壊れたマイグレーションはデプロイの失敗ではなくユーザーリクエストの失敗として表面化し、最初の呼び出し元がスキーマを待つことになります。新しいマイグレーションを同梱するデプロイのたびに db:migrate を再実行してください。適用するものがない場合は何もしません。
Composeは、どちらかの変数が未設定の場合、起動を拒否します。シェルプロファイルまたはインスタンスシークレットに保管してください — このリポジトリのファイルには入れないでください。
公開ポートは意図的に 127.0.0.1:3000 です。 エンドポイントは平文HTTPで通信し、ベアラートークンで認証します。オープンインターネット上では、そのトークンは経路上の誰にでも読み取られます。その前にTLSを配置してください — HTTPSを終端してインスタンスに転送するALB、または同じボックス上のnginx/Caddyが 127.0.0.1:3000 にプロキシする方法です。その後、セキュリティグループはクライアントからの443のみを許可し、それ以外は許可しないようにします。ポート3000は外部に閉じたままにします。
トークンのローテーションは export MCP_AUTH_TOKEN=... && docker compose up -d で、コンテナが再起動されます。全員に1つのトークンがあります — 誰も特定しないため、あなたのセッションと友人のセッションを区別できません。ユーザーごとのアクセスには、実際の認証と resume_sessions のオーナー列が必要ですが、どちらもまだ存在しません。
resume_path はコンテナ内で解決されるため、リモートの呼び出し元はそれを使用できません — 彼らのラップトップ上のパスはサーバーにとって意味がありません。HTTP経由では、resume_text と job_description_text を渡してください。ボックス上のファイルでパス形式を機能させたい場合は、ボリュームをマウントしてください。
docker-compose.yml は本番スタックのみです。ローカル開発では docker-compose.dev.yml を使用し、独自のPostgresを同梱し、この構成を一切共有しません。
レイアウト
サーバーはモジュールのホストです。モジュールとは、独自のテーブルと独自の語彙を持つ、自己完結型のツールファミリーです。レジュメレビューは今日のところ唯一のものであり、2つ目の無関係なモジュールは src/features/ 配下のフォルダーと、index.ts のリストの1エントリです。
index.ts stdio entrypoint
serve.ts HTTP entrypoint (the container runs this)
src/modules.ts the one list of mounted modules, shared by both entries
src/module.ts the ToolModule contract every feature implements
src/server.ts mounts modules onto an McpServer
src/http.ts Streamable HTTP handler, bearer auth, /healthz
src/platform/ feature-agnostic; knows nothing about resumes
db.ts lazy Postgres pool + per-module migration runner
documents.ts text / pdf / docx extraction
stored-document.ts what an extracted document looks like
tool-result.ts keeps `content` and `structuredContent` in step
src/features/resume-review/
index.ts the ToolModule: name, migrations, register()
migrations.ts this module's tables
sessions.ts repository, domain types, stage gating
briefs.ts the three briefs
schemas.ts zod schema per stage result
stage-tool.ts the brief-then-record tool shape
dossier.ts markdown rendering
tools/ one file per group of registered tools
intake.ts, stages.ts, dossier.ts, session-admin.ts構造を支える2つのルール:
src/platformはsrc/featuresからインポートしません。 2つ目のモジュールも必要とするものはplatformに属し、レジュメレビューのみが必要とするものはフィーチャーに残ります。モジュールは他のモジュールをインポートしません。 互いを知る必要がある2つのモジュールは、1つのモジュールです。
stage-tool.ts はplatformではなく、意図的にフィーチャー内に配置されています。ブリーフ→記録の形状は再利用可能になるかもしれませんが、今日のところ消費者は正確に1つであり、2つ目が存在する前に一般的なケースを推測することは、プラットフォーム層が腐る方法です。
モジュールの追加
// src/features/interview-prep/index.ts
export const interviewPrep: ToolModule = {
name: "interview-prep",
migrations, // its own tables, namespaced in schema_migrations
register(server) {
registerWhateverTools(server);
},
};// index.ts
const server = createServer([resumeReview, interviewPrep]);これが契約のすべてです。マイグレーションはそれぞれ1回適用され、schema_migrations でモジュールごとに追跡され、そのモジュールが最初にデータベースに触れたときに遅延実行されます — 未使用のモジュールはラウンドトリップを消費しません。tests/modules.test.ts は、レジュメとは無関係のスタブモジュールでシームをテストします。
貢献
CONTRIBUTING.md を参照してください — bun run dev がセットアップ全体です。セキュリティの問題は公開イシューではなく、SECURITY.md を通じて報告してください。
ライセンス
MIT。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAnalyzes resumes against job descriptions to identify missing skills, keywords, and improvement opportunities using AI. Provides structured feedback including gap analysis, ATS optimization suggestions, and actionable recommendations to improve job application success.
- AlicenseAqualityCmaintenanceRewrites resumes to beat ATS screening (Workday, Greenhouse, iCIMS, Taleo) against a specific job description, with strict truthfulness guardrails — never invents dates, metrics, titles, or seniority. Pay-what-you-want access codes ($0 works).2MIT
- FlicenseNot gradedqualityDmaintenanceAutomates ATS resume scanning via Jobscan, enabling AI to iteratively scan, analyze gaps, optimize, and rescan resumes against job descriptions to improve match rates.3
- FlicenseAqualityCmaintenanceEnables tailoring resumes to job descriptions by scraping JDs, applying rules, and generating optimized DOCX resumes.11
Related MCP Connectors
Tailor resumes, generate cover letters, render CVs as PDF, and browse 22+ templates.
Search 6.3M+ live jobs from companies' own career pages, plus resume tailoring & cover letters.
Search AI-native jobs, inspect application forms, and fetch free interview-prep resources.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/pnaskardev/Batcave-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server