list_jobs
View published job listings with application statistics to monitor hiring progress and manage recruitment workflows.
Instructions
查看已发布的职位列表及申请统计。
返回信息:
职位基本信息(标题、城市、薪资)
申请数量(各职位的投递数)
职位状态(已发布/已过期等)
可用于:
了解各职位的招聘进展
决定是否需要刷新或关闭某职位
快速跳转到特定职位的候选人搜索
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | 会话 ID,从 register_company 获取 | |
| status | No | 职位状态过滤:0=草稿, 1=已发布, 2=已过期, 3=已下线 | |
| page | No | 页码,默认1 | |
| page_size | No | 每页数量,默认20,最大50 |
Implementation Reference
- src/tools/list_jobs.ts:63-170 (handler)The main execute handler for the list_jobs tool. Validates the session, calls the listJobs API, formats the job data with status text and salary ranges, and returns a structured response with job listings, pagination info, and usage stats.
async execute(input: Input) { // Validate session const session = getSession(input.session_id); if (!session) { return { content: [ { type: 'text', text: JSON.stringify({ error: { code: 'INVALID_SESSION', message: '会话已过期或无效,请重新调用 register_company', }, }, null, 2), }, ], isError: true, }; } try { const response = await listJobs({ session_id: input.session_id, status: input.status, page: input.page, page_size: input.page_size, }); const { data } = response; const tierConfig = getTierConfig(session); // Format jobs for display const formattedJobs = data.jobs.map(job => ({ job_token: job.token, job_post: job.job_post, city_names: job.city_names, salary_range: job.salary_min && job.salary_max ? `¥${(job.salary_min / 1000).toFixed(0)}k-${(job.salary_max / 1000).toFixed(0)}k` : '薪资面议', status: job.status, status_text: statusMap[job.status] || '未知', application_count: job.application_count, created_at: job.created_at, })); // Calculate page-level stats (note: these are for current page only, not global totals) const pageApplications = data.jobs.reduce((sum, job) => sum + job.application_count, 0); // Note: For accurate global totals, backend should return aggregated metrics // This is a known limitation - page 2+ will show different "active_jobs" counts return { content: [ { type: 'text', text: JSON.stringify({ data: { jobs: formattedJobs, total: data.total, page: data.page, page_size: data.page_size, summary: { // These stats reflect current page only due to pagination // Backend enhancement needed for global totals across all pages active_jobs_on_page: data.jobs.filter(j => j.status === 1).length, applications_on_page: pageApplications, total_jobs_global: data.total, note: '职位统计反映当前页数据。Backend enhancement needed for global totals (see KnownIssues.md #4)', }, }, access: { tier: session.tier, daily_limits: tierConfig.daily_limits, jobs_remaining_today: tierConfig.daily_limits.active_jobs - session.daily_usage.jobs_posted, }, meta: { session_id: session.session_id, }, next_steps: data.jobs.length > 0 ? [ '调用 search_candidates 搜索匹配的候选人', '调用 list_applications 查看最新投递', ] : [ '还没有发布职位,调用 post_job 发布第一个职位', ], }, null, 2), }, ], isError: false, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : '获取职位列表失败'; return { content: [ { type: 'text', text: JSON.stringify({ error: { code: 'LIST_JOBS_FAILED', message: errorMessage, }, }, null, 2), }, ], isError: true, }; } }, - src/tools/list_jobs.ts:12-37 (schema)Zod input schema definition for list_jobs tool. Defines validation for session_id (required string), status (optional int 0-4), page (optional positive int), and page_size (optional positive int max 50).
const inputSchema = z.object({ session_id: z.string() .describe('会话 ID,从 register_company 获取'), status: z.number() .int() .min(0) .max(4) .optional() .describe('职位状态过滤:0=草稿, 1=已发布, 2=已过期, 3=已下线'), page: z.number() .int() .positive() .optional() .describe('页码,默认1'), page_size: z.number() .int() .positive() .max(50) .optional() .describe('每页数量,默认20,最大50'), }); type Input = z.infer<typeof inputSchema>; - src/tools/index.ts:47-57 (registration)Registration of listJobsTool in the allTools array. The tool is imported on line 30 and exported, then added to the registry array on line 52.
// Tool registry for server initialization // eslint-disable-next-line @typescript-eslint/no-explicit-any export const allTools: Tool<any>[] = [ registerCompanyTool, postJobTool, listJobsTool, searchCandidatesTool, viewCandidateTool, listApplicationsTool, requestOutreachTool, ]; - src/backend-api.ts:228-254 (helper)TypeScript interfaces (ListJobsInput, ListJobsOutput) and the listJobs async function that makes the API request to fetch jobs from the backend with query parameters.
export interface ListJobsInput { session_id: string; status?: number; page?: number; page_size?: number; } export interface ListJobsOutput { jobs: JobWithStats[]; total: number; page: number; page_size: number; } export async function listJobs( input: ListJobsInput ): Promise<ApiResponse<ListJobsOutput>> { const params = new URLSearchParams(); params.append('session_id', input.session_id); if (input.status !== undefined) params.append('status', input.status.toString()); if (input.page !== undefined) params.append('page', input.page.toString()); if (input.page_size !== undefined) params.append('page_size', input.page_size.toString()); return apiRequest(`/jobs?${params.toString()}`, { method: 'GET', }); }