SuccessFactors-MCP

SAP SuccessFactors Model Context Protocol Server

Installation · Quick Start · 62 Tools · Deployment · API Reference

Version Python License MCP

--- A production-grade [Model Context Protocol](https://modelcontextprotocol.io) server that connects Claude (or any MCP client) to **SAP SuccessFactors** via OData APIs. Query employee data, manage permissions, run compliance reports, and administer HR operations — all through natural language. ``` You: "Who on the Engineering team has a work anniversary this month?" Claude: [calls get_anniversary_employees] Found 3 upcoming anniversaries... - Jane Smith (5 years - milestone!) - March 12 - Bob Johnson (2 years) - March 18 - Alice Chen (10 years - milestone!) - March 25 ``` ## Why SF-MCP? | Challenge | SF-MCP Solution | |-----------|-----------------| | SAP SuccessFactors APIs are complex and verbose | **62 purpose-built tools** with clean interfaces | | Building OData queries requires deep SF knowledge | **Natural language** — ask Claude in plain English | | Security concerns with API access | **Per-request auth**, input validation, audit logging | | Managing multiple SF instances | **21 data centers** supported, cross-instance comparison | | API rate limits and performance | **Connection pooling**, response caching, rate limiting | ## Tools 62 tools organized across 16 categories:
Configuration & Discovery (3 tools) | Tool | Description | |------|-------------| | `get_configuration` | Retrieve OData metadata for any entity | | `list_entities` | Discover all available OData entities | | `compare_configurations` | Compare entity config between two instances |
RBP Security (7 tools) | Tool | Description | |------|-------------| | `get_rbp_roles` | List all Role-Based Permission roles | | `get_role_permissions` | Get permissions for specific roles | | `get_user_permissions` | Get all permissions for a user | | `get_user_roles` | Get roles assigned to a user | | `get_permission_metadata` | Map UI labels to permission types | | `check_user_permission` | Check if user has specific permission | | `get_dynamic_groups` | List permission groups (dynamic groups) |
Security & Audit (6 tools) | Tool | Description | |------|-------------| | `get_role_history` | View modification history for roles | | `get_role_assignment_history` | View history of role assignments | | `get_login_audit_log` | Login events — who logged in, when, from where | | `get_admin_audit_log` | Admin-level config/data change history | | `get_sod_violations` | Detect segregation-of-duty conflicts in RBP assignments | | `get_dormant_users` | Active accounts with no recent login activity |
Data Query (2 tools) | Tool | Description | |------|-------------| | `query_odata` | Flexible OData queries with filtering, pagination | | `get_picklist_values` | Get dropdown/picklist options |
Employee Lookup (4 tools) | Tool | Description | |------|-------------| | `get_employee_profile` | Complete profile with job info, manager, optional compensation | | `search_employees` | Find by name, department, location, or manager | | `get_employee_history` | Job history — promotions, transfers, title changes | | `get_team_roster` | Manager's team with direct/indirect reports |
Time Off (3 tools) | Tool | Description | |------|-------------| | `get_time_off_balances` | Vacation, PTO, sick leave balances | | `get_upcoming_time_off` | Team absence calendar for a date range | | `get_time_off_requests` | Pending/approved time-off requests |
Hiring & Onboarding (3 tools) | Tool | Description | |------|-------------| | `get_open_requisitions` | Job requisitions with status and hiring manager | | `get_candidate_pipeline` | Candidates by stage for a requisition | | `get_new_hires` | Recent/upcoming hires for onboarding |
Compliance & Reporting (3 tools) | Tool | Description | |------|-------------| | `get_terminations` | Terminated employees for exit processing | | `get_employees_missing_data` | Incomplete profiles for compliance audits | | `get_anniversary_employees` | Upcoming work anniversaries for recognition |
Performance & Compensation (5 tools) | Tool | Description | |------|-------------| | `get_performance_review_status` | Review form completion across the org | | `get_compensation_details` | Pay breakdown with recurring/non-recurring components | | `get_compensation_history` | Full compensation change history (not just latest) | | `get_compensation_review_status` | Comp planning worksheet completion by manager/department | | `get_salary_range_analysis` | Compa-ratio: pay vs. grade midpoint |
Performance & Talent (4 tools) | Tool | Description | |------|-------------| | `get_goal_summary` | Employee goals — category, weight, completion | | `get_development_plans` | Development goals and learning activities | | `get_talent_flags` | Potential, flight risk, impact of loss, key position | | `get_succession_nominees` | Talent pool nominees for key positions |
Position Management (3 tools) | Tool | Description | |------|-------------| | `get_position_details` | Position with incumbent, department, FTE | | `get_vacant_positions` | Open positions for headcount planning | | `get_org_chart` | Org hierarchy from any position (up or down) |
MDF Objects (3 tools) | Tool | Description | |------|-------------| | `get_mdf_object_definitions` | List custom MDF objects and their fields | | `query_mdf_object` | Query any MDF/generic object (`cust_*`) | | `get_foundation_objects` | Query foundation objects (departments, cost centers, etc.) |
Workflow (2 tools) | Tool | Description | |------|-------------| | `get_pending_approvals` | Pending workflow items for a user or globally | | `get_workflow_history` | Audit trail of approval steps |
Monitoring & Admin (6 tools) | Tool | Description | |------|-------------| | `get_alert_notifications` | System alerts and notifications | | `get_scheduled_job_status` | Scheduled job run status | | `get_integration_center_jobs` | Integration Center job status | | `get_api_quota_status` | Rate limit usage per instance | | `get_cache_status` | Cache hit rates and entry counts | | `clear_cache` | Clear cached responses |
Employee Central (5 tools) | Tool | Description | |------|-------------| | `get_global_assignments` | International assignments — home/host details | | `get_employee_documents` | Documents attached to an employee's record | | `get_pay_component_groups` | Recurring pay elements (allowances, bonuses) | | `get_work_permit_expiry` | Work permits/visas expiring soon | | `get_probation_end_dates` | Employees approaching end of probation |
Data Management (3 tools) | Tool | Description | |------|-------------| | `bulk_export_employees` | Paginated full export of active employees | | `get_picklist_usage` | Which picklists are used on which entity fields | | `get_country_specific_fields` | Field population rates for a given country |
## Installation ### Prerequisites - **Python 3.10+** - **[uv](https://docs.astral.sh/uv/)** package manager - SAP SuccessFactors account with API access ### Setup ```bash git clone https://github.com/aiadiguru2025/sf-mcp.git cd sf-mcp uv sync ``` ### Quick Start **Development mode** (MCP Inspector): ```bash uv run mcp dev main.py ``` **Stdio mode** (Claude Desktop): ```bash uv run main.py ``` **HTTP mode** (Cloud Run / remote): ```bash PORT=8080 uv run main.py ``` ## Claude Desktop Integration ### Step 1 — Find the path to `uv` ```bash # macOS / Linux which uv # Windows (PowerShell) Get-Command uv | Select-Object -ExpandProperty Source ``` ### Step 2 — Edit your Claude Desktop config | OS | Config path | |----|------------| | macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` | | Windows | `%APPDATA%\Claude\claude_desktop_config.json` | Add the sf-mcp server: ```json { "mcpServers": { "sf-mcp": { "command": "/path/to/uv", "args": ["--directory", "/path/to/sf-mcp", "run", "main.py"] } } } ``` ### Step 3 — Restart Claude Desktop The MCP tools icon (hammer) will appear in the input area with all 62 tools available. > **Note:** Credentials (`auth_user_id` and `auth_password`) are provided on each tool call — nothing is stored in the config. ## Deployment ### Google Cloud Run ```bash # Build and deploy export PROJECT_ID=your-gcp-project-id gcloud builds submit --tag gcr.io/$PROJECT_ID/sf-mcp gcloud run deploy sf-mcp \ --image gcr.io/$PROJECT_ID/sf-mcp \ --platform managed \ --region us-central1 ``` Then point Claude Desktop to the remote URL: ```json { "mcpServers": { "sf-mcp": { "url": "https://sf-mcp-xxxxx-uc.a.run.app/mcp" } } } ``` ### Docker (local) ```bash docker build -t sf-mcp . docker run -p 8080:8080 sf-mcp ``` ### API Key Protection (optional) Set `MCP_API_KEY` to require authentication on the HTTP endpoint: ```bash MCP_API_KEY=your-secret-key PORT=8080 uv run main.py ``` Clients must then include `X-API-Key: your-secret-key` in requests. ## Configuration All tool parameters (`data_center`, `environment`, `auth_user_id`, `auth_password`) are provided per-request. Server-side environment variables are optional: ### Rate Limiting | Variable | Default | Description | |----------|---------|-------------| | `SF_RATE_LIMIT` | `100` | Max requests per window per instance | | `SF_RATE_LIMIT_WINDOW` | `60` | Window duration in seconds | | `SF_RATE_LIMIT_WARN_THRESHOLD` | `0.8` | Log warning at 80% usage | | `SF_RATE_LIMIT_RETRY_AFTER` | `5` | Seconds to wait on 429 retry | | `SF_RATE_LIMIT_MAX_RETRIES` | `3` | Max 429 retry attempts | ### Response Caching | Variable | Default | Description | |----------|---------|-------------| | `SF_CACHE_TTL_METADATA` | `3600` | Metadata cache TTL (1 hour) | | `SF_CACHE_TTL_SERVICE_DOC` | `3600` | Service doc cache TTL (1 hour) | | `SF_CACHE_TTL_PICKLIST` | `1800` | Picklist cache TTL (30 min) | | `SF_CACHE_TTL_PERMISSIONS` | `3600` | Permission cache TTL (1 hour) | | `SF_CACHE_TTL_DEFAULT` | `0` | Default TTL (0 = disabled) | | `SF_CACHE_MAX_ENTRIES` | `1000` | Max cache entries before eviction | ### Endpoint Protection | Variable | Default | Description | |----------|---------|-------------| | `MCP_API_KEY` | *(none)* | API key for HTTP endpoint auth | Copy `.env.example` to `.env` to customize: ```bash cp .env.example .env ``` ## Supported Data Centers 21 data centers across 6 continents with alias support: | Data Center | Alias | Location | Environments | |-------------|-------|----------|--------------| | DC2 | DC57 | Netherlands | preview, production, sales_demo | | DC4 | DC68 | Virginia, US | preview, production, sales_demo | | DC8 | DC70 | Ashburn, Virginia, US | preview, production, sales_demo | | DC10 | DC66 | Sydney, Australia | preview, production | | DC12 | DC33 | Germany | preview, production | | DC15 | DC30 | Shanghai, China | preview, production | | DC17 | DC60 | Toronto, Canada | preview, production | | DC19 | DC62 | Sao Paulo, Brazil | preview, production | | DC22 | — | Dubai, UAE | preview, production | | DC23 | DC84 | Riyadh, Saudi Arabia | preview, production | | DC40 | — | — | sales_demo | | DC41 | — | Virginia, US | preview, production | | DC44 | DC52 | Singapore | preview, production | | DC47 | — | Canada Central | preview, production | | DC50 | — | Tokyo, Japan | preview, production | | DC55 | — | Frankfurt, Germany | preview, production | | DC74 | — | Zurich, Switzerland | preview, production | | DC80 | — | Mumbai, India | preview, production | | DC82 | — | Riyadh, Saudi Arabia | preview, production | ## Architecture ``` sf-mcp/ ├── main.py # Entry point (stdio + HTTP modes) ├── sf_mcp/ │ ├── server.py # FastMCP instance │ ├── config.py # DC mappings, constants, env vars │ ├── auth.py # Credential resolution, API key middleware │ ├── client.py # HTTP client (OData, metadata, service doc, pagination) │ ├── cache.py # TTL-based response cache with deep-copy safety │ ├── rate_limiter.py # Sliding-window rate limiter (per-instance) │ ├── validation.py # 10 input validators with registry pattern │ ├── decorators.py # sf_tool decorator (cross-cutting concerns) │ ├── dependencies.py # FastMCP DI for schema exclusion │ ├── logging_config.py # Cloud Logging JSON formatter, audit_log() │ ├── xml_utils.py # Safe XML parsing (defusedxml), SAP date parsing │ └── tools/ # 62 tools across 16 modules │ ├── configuration.py # get_configuration, compare_configurations, list_entities │ ├── permissions.py # 7 RBP security tools │ ├── audit.py # Role history, role assignment history │ ├── query.py # query_odata, get_picklist_values │ ├── employee.py # Profile, search, history, team roster │ ├── time_off.py # Balances, upcoming absences, requests │ ├── recruiting.py # Requisitions, pipeline, new hires │ ├── compliance.py # Terminations, missing data, anniversaries, reviews, comp │ ├── position.py # Position details, vacancies, org chart │ ├── workflow.py # Pending approvals, workflow history │ ├── mdf.py # MDF object definitions, queries, foundation objects │ ├── monitoring.py # Alerts, scheduled jobs, integration jobs │ ├── admin.py # Rate limit quota, cache status, cache clear │ └── utils.py # Shared utilities (display_name) ├── tests/ # 110 tests ├── Dockerfile # Cloud Run container ├── .env.example # Configuration template └── pyproject.toml # Project metadata, dependencies, linter config ``` ### Design Principles **Zero boilerplate** — The `sf_tool` decorator handles request ID generation, timing, audit logging, input validation, credential checking, error handling, and `$top` clamping. Tool functions contain only business logic. **Secure by default** — 10 input validators (regex allowlists), OData injection prevention, XXE-safe XML parsing (defusedxml), timing-safe API key comparison (hmac.compare_digest), and automatic credential masking in logs. **Production-ready** — Connection pooling (requests.Session), mutation-safe response caching (deep-copy on put/get), sliding-window rate limiting with automatic 429 retry, and Cloud Logging-compatible JSON audit trail. **Schema-clean** — Internal parameters (`request_id`, `start_time`, `api_host`) are hidden from the MCP tool schema via FastMCP's Dependency injection, keeping tool interfaces clean for LLM consumers. ## Security | Layer | Mechanism | |-------|-----------| | **Input validation** | 10 regex-based validators; OData filter blocklist checks raw + URL-decoded + double-decoded input | | **Injection prevention** | Entity paths, $select, $orderby, $filter, $expand all validated; control characters rejected | | **Authentication** | Per-request credentials (never stored); timing-safe API key comparison via `hmac.compare_digest` | | **XML safety** | `defusedxml` prevents XXE, entity expansion, and DTD attacks | | **Audit logging** | Every tool call logged with structured JSON; passwords automatically masked | | **Cache safety** | Deep-copied on store and retrieval to prevent mutation bugs | | **Date handling** | All SAP timestamp parsing uses explicit UTC to prevent timezone inconsistencies | ## Testing ```bash # Run all 110 tests uv run pytest tests/ -v # Run with coverage uv run pytest tests/ --cov=sf_mcp # Lint uv run ruff check . # Type check uv run mypy sf_mcp/ ``` Test coverage includes: - **Config** — DC mapping resolution, case insensitivity, aliases, error cases - **Validation** — All 10 validators with valid/invalid inputs, injection prevention - **Client** — Mocked HTTP responses (200, 401, 500, empty, connection error) - **Rate limiter** — Limit enforcement, sliding window, per-instance isolation, thread safety - **Cache** — Put/get, TTL expiry, category TTLs, invalidation, eviction, deep-copy safety - **Pagination** — Single/multi page, max_pages limit, error handling, $skip increments - **Decorators** — Value injection, validation errors, max_top clamping, exception handling ## API Reference Every tool accepts these common parameters: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `instance` | string | Yes | SuccessFactors company ID | | `data_center` | string | Yes | SAP data center code (e.g., `DC55`, `DC10`) | | `environment` | string | Yes | `preview`, `production`, or `sales_demo` | | `auth_user_id` | string | Yes | SuccessFactors user ID (without @instance) | | `auth_password` | string | Yes | SuccessFactors password |
Configuration Tools #### `get_configuration` Retrieve OData metadata for a SuccessFactors entity. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `entity` | string | Yes | OData entity name (e.g., `User`, `Position`) | #### `list_entities` Discover all available OData entities in an instance. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `category` | string | No | `foundation`, `employee`, `talent`, `platform`, or `all` | #### `compare_configurations` Compare entity config between two instances (e.g., dev vs prod). | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `instance1` | string | Yes | First instance | | `instance2` | string | Yes | Second instance | | `entity` | string | Yes | Entity to compare | | `data_center1` | string | Yes | Data center for instance1 | | `environment1` | string | Yes | Environment for instance1 | | `data_center2` | string | Yes | Data center for instance2 | | `environment2` | string | Yes | Environment for instance2 |
RBP Security Tools #### `get_rbp_roles` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `include_description` | boolean | No | Include role descriptions (default: false) | #### `get_role_permissions` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `role_ids` | string | Yes | Single or comma-separated: `10` or `10,20,30` | | `locale` | string | No | Locale for labels (default: `en-US`) | #### `get_user_permissions` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_ids` | string | Yes | Single or comma-separated: `admin` or `admin,user2` | | `locale` | string | No | Locale for labels (default: `en-US`) | #### `get_user_roles` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | User ID to look up roles for | | `include_permissions` | boolean | No | Also fetch permissions per role (default: false) | #### `get_permission_metadata` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `locale` | string | No | Locale for labels (default: `en-US`) | #### `check_user_permission` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `access_user_id` | string | Yes | User whose permission to check | | `target_user_id` | string | Yes | Target user of the permission | | `perm_type` | string | Yes | Permission type from metadata | | `perm_string_value` | string | Yes | Permission string value | | `perm_long_value` | string | No | Permission long value (default: `-1L`) | #### `get_dynamic_groups` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `group_type` | string | No | Filter by group type |
Security & Audit Tools #### `get_role_history` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `role_id` | string | No | Filter by role ID | | `role_name` | string | No | Filter by role name | | `from_date` | string | No | Start date (YYYY-MM-DD) | | `to_date` | string | No | End date (YYYY-MM-DD) | | `top` | integer | No | Max records (default: 100, max: 500) | #### `get_role_assignment_history` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `role_id` | string | No | Filter by role ID | | `user_id` | string | No | Filter by user ID | | `from_date` | string | No | Start date (YYYY-MM-DD) | | `to_date` | string | No | End date (YYYY-MM-DD) | | `top` | integer | No | Max records (default: 100, max: 500) | > At least one of `role_id` or `user_id` is required. #### `get_login_audit_log` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | No | Filter to a single user's login history | | `from_date` | string | No | Start date (YYYY-MM-DD) | | `to_date` | string | No | End date (YYYY-MM-DD) | | `top` | integer | No | Max records (default: 100, max: 500) | > Requires the instance's Audit Trail / Login Tracking feature to be provisioned. #### `get_admin_audit_log` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `entity_name` | string | No | Filter by entity/object name (e.g., `RBPRole`, `User`) | | `changed_by` | string | No | Filter by the admin who made the change | | `from_date` | string | No | Start date (YYYY-MM-DD) | | `to_date` | string | No | End date (YYYY-MM-DD) | | `top` | integer | No | Max records (default: 100, max: 500) | > Requires the instance's Audit Trail feature to be provisioned. #### `get_sod_violations` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_ids` | string | Yes | Employee user ID(s), comma-separated (max 20) | | `permission_pairs` | string | No | Custom conflict pairs: `"PermA\|PermB,PermC\|PermD"`. Defaults to a built-in list of common RBP conflicts | #### `get_dormant_users` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `dormant_days` | integer | No | Flag users with no login in this many days (default: 90) | | `department` | string | No | Filter by department | | `top` | integer | No | Max records (default: 100, max: 500) |
Data Query Tools #### `query_odata` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `entity` | string | Yes | Entity name or key: `User` or `User('admin')` | | `select` | string | No | Fields: `userId,firstName,lastName` | | `filter` | string | No | OData filter: `status eq 'active'` | | `expand` | string | No | Nav properties: `empInfo,jobInfoNav` | | `top` | integer | No | Max records (default: 100, max: 1000) | | `skip` | integer | No | Records to skip | | `orderby` | string | No | Sort: `lastName asc` | | `paginate` | boolean | No | Auto-fetch all pages (default: false) | | `max_pages` | integer | No | Max pages when paginating (default: 10, max: 50) | #### `get_picklist_values` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `picklist_id` | string | Yes | Picklist ID: `ecJobFunction`, `nationality` | | `locale` | string | No | Locale for labels (default: `en-US`) | | `include_inactive` | boolean | No | Include inactive values (default: false) |
Employee Lookup Tools #### `get_employee_profile` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | Employee user ID | | `include_compensation` | boolean | No | Include compensation (default: false) | #### `search_employees` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `search_text` | string | No | Partial name search | | `department` | string | No | Filter by department | | `location` | string | No | Filter by location | | `manager_id` | string | No | Filter to manager's reports | | `status` | string | No | `active`, `inactive`, or `all` (default: `active`) | | `top` | integer | No | Max results (default: 50, max: 200) | #### `get_employee_history` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | Employee user ID | | `include_compensation_changes` | boolean | No | Include salary history (default: false) | #### `get_team_roster` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `manager_id` | string | Yes | Manager's user ID | | `include_indirect_reports` | boolean | No | Include reports-of-reports (default: false) | | `top` | integer | No | Max direct reports (default: 100, max: 200) |
Time Off Tools #### `get_time_off_balances` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_ids` | string | Yes | Comma-separated user IDs (max 50) | | `as_of_date` | string | No | Balance as of date (YYYY-MM-DD) | #### `get_upcoming_time_off` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `start_date` | string | Yes | Range start (YYYY-MM-DD) | | `end_date` | string | Yes | Range end (YYYY-MM-DD) | | `department` | string | No | Filter by department | | `manager_id` | string | No | Filter to manager's team | | `status` | string | No | `approved`, `pending`, or `all` (default: `approved`) | | `top` | integer | No | Max results (default: 200, max: 500) | #### `get_time_off_requests` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | No | Filter to employee | | `status` | string | No | `pending`, `approved`, `rejected`, `cancelled`, or `all` (default: `pending`) | | `from_date` | string | No | Submitted after date (YYYY-MM-DD) | | `top` | integer | No | Max results (default: 50, max: 200) |
Hiring & Onboarding Tools #### `get_open_requisitions` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `department` | string | No | Filter by department | | `hiring_manager_id` | string | No | Filter by hiring manager | | `location` | string | No | Filter by location | | `status` | string | No | `open`, `filled`, `closed`, or `all` (default: `open`) | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_candidate_pipeline` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `requisition_id` | string | Yes | Job requisition ID | | `include_rejected` | boolean | No | Include rejected candidates (default: false) | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_new_hires` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `start_date_from` | string | Yes | Hires on/after date (YYYY-MM-DD) | | `start_date_to` | string | Yes | Hires on/before date (YYYY-MM-DD) | | `department` | string | No | Filter by department | | `top` | integer | No | Max results (default: 100, max: 500) |
Compliance & Reporting Tools #### `get_terminations` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `from_date` | string | Yes | Range start (YYYY-MM-DD) | | `to_date` | string | Yes | Range end (YYYY-MM-DD) | | `department` | string | No | Filter by department | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_employees_missing_data` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `check_fields` | string | Yes | Comma-separated: `email`, `phone`, `address`, `emergency_contact` | | `department` | string | No | Filter by department | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_anniversary_employees` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `from_date` | string | Yes | Range start (YYYY-MM-DD) | | `to_date` | string | Yes | Range end (YYYY-MM-DD) | | `milestone_years_only` | boolean | No | Only 1, 5, 10, 15, 20, 25+ years (default: false) | | `department` | string | No | Filter by department | | `top` | integer | No | Max results (default: 100, max: 500) |
Performance & Compensation Tools #### `get_performance_review_status` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `form_template_id` | string | No | Filter by form template | | `department` | string | No | Filter by department | | `manager_id` | string | No | Filter by manager | | `status` | string | No | `not_started`, `in_progress`, `completed`, or `""` for all | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_compensation_details` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_ids` | string | Yes | Comma-separated user IDs (max 20) | | `effective_date` | string | No | Compensation as of date (YYYY-MM-DD) | #### `get_compensation_history` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | The employee's user ID | | `top` | integer | No | Max history records (default: 50, max: 200) | #### `get_compensation_review_status` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `form_template_id` | string | Yes | The compensation worksheet's form template ID | | `department` | string | No | Filter by department | | `manager_id` | string | No | Filter by manager | | `status` | string | No | `not_started`, `in_progress`, `completed`, or `""` for all | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_salary_range_analysis` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_ids` | string | Yes | Comma-separated user IDs (max 20) | > Returns compa-ratio (current salary ÷ grade midpoint × 100) per employee.
Performance & Talent Tools #### `get_goal_summary` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | The employee's user ID | | `status` | string | No | `not_started`, `in_progress`, `completed`, or `""` for all | | `top` | integer | No | Max results (default: 100, max: 200) | #### `get_development_plans` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | The employee's user ID | | `status` | string | No | `not_started`, `in_progress`, `completed`, or `""` for all | | `top` | integer | No | Max results (default: 100, max: 200) | #### `get_talent_flags` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_ids` | string | Yes | Comma-separated user IDs (max 20) | > Field availability depends on the instance's Succession Data Model configuration. #### `get_succession_nominees` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `pool_id` | string | No | Filter to nominees for a specific talent pool | | `user_id` | string | No | Filter to pools an employee is nominated to | | `top` | integer | No | Max results (default: 100, max: 200) |
Position Management Tools #### `get_position_details` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `position_id` | string | Yes | Position ID | #### `get_vacant_positions` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `department` | string | No | Filter by department | | `location` | string | No | Filter by location | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_org_chart` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `position_id` | string | Yes | Starting position ID | | `direction` | string | No | `down` or `up` (default: `down`) | | `levels` | integer | No | Levels to traverse (default: 2, max: 5) |
MDF Object Tools #### `get_mdf_object_definitions` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `object_name` | string | No | Specific MDF object (e.g., `cust_myObject`). Empty = list all. | #### `query_mdf_object` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `object_name` | string | Yes | MDF object name (e.g., `cust_myObject`) | | `select` | string | No | Comma-separated fields | | `filter` | string | No | OData filter | | `top` | integer | No | Max results (default: 100, max: 500) | | `skip` | integer | No | Pagination offset | | `orderby` | string | No | Sort order | | `effective_date` | string | No | Effective date filter (YYYY-MM-DD) | #### `get_foundation_objects` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `object_type` | string | Yes | `company`, `department`, `division`, `location`, `cost_center`, `job_code`, `job_function`, `pay_grade`, `pay_group`, `business_unit`, `event_reason`, `legal_entity` | | `filter` | string | No | Additional OData filter | | `top` | integer | No | Max results (default: 100, max: 500) | | `include_inactive` | boolean | No | Include end-dated records (default: false) |
Workflow Tools #### `get_pending_approvals` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | No | Filter to specific approver | | `wf_request_id` | string | No | Filter to specific workflow request | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_workflow_history` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `wf_request_id` | string | Yes | Workflow request ID | | `top` | integer | No | Max results (default: 100, max: 500) |
Monitoring & Admin Tools #### `get_alert_notifications` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `from_date` | string | No | Start date (YYYY-MM-DD) | | `to_date` | string | No | End date (YYYY-MM-DD) | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_scheduled_job_status` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `job_name` | string | No | Filter by job name | | `top` | integer | No | Max results (default: 50, max: 500) | #### `get_integration_center_jobs` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `job_name` | string | No | Filter by job name | | `status` | string | No | Filter by status | | `top` | integer | No | Max results (default: 50, max: 500) | #### `get_api_quota_status` Returns current rate limit usage for the specified instance. #### `get_cache_status` Returns cache hit rates, entry counts by category, and memory usage. #### `clear_cache` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `target_instance` | string | No | Clear specific instance. Empty = clear all. |
Employee Central Tools #### `get_global_assignments` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | No | Filter to a single employee's assignment history | | `active_only` | boolean | No | Only currently active assignments (default: true) | | `top` | integer | No | Max results (default: 100, max: 200) | #### `get_employee_documents` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | The employee's user ID | | `document_type` | string | No | Filter by document type | | `top` | integer | No | Max results (default: 50, max: 100) | #### `get_pay_component_groups` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `user_id` | string | Yes | The employee's user ID | | `effective_date` | string | No | Components as of date (YYYY-MM-DD) | #### `get_work_permit_expiry` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `within_days` | integer | No | Flag permits/visas expiring within N days (default: 90) | | `country` | string | No | Filter by ISO country code | | `top` | integer | No | Max results (default: 100, max: 500) | #### `get_probation_end_dates` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `within_days` | integer | No | Flag probation periods ending within N days (default: 30) | | `department` | string | No | Filter by department | | `top` | integer | No | Max results (default: 100, max: 500) |
Data Management Tools #### `bulk_export_employees` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `select` | string | No | Comma-separated fields. Defaults to a standard field set | | `department` | string | No | Filter by department | | `status` | string | No | `active`, `inactive`, or `all` (default: `active`) | | `top` | integer | No | Records per page (default: 500, max: 1000) | | `max_pages` | integer | No | Max pages to fetch (default: 10, max: 50) | #### `get_picklist_usage` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `entities` | string | No | Comma-separated entity names to scan. Defaults to a common set | #### `get_country_specific_fields` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `entity` | string | Yes | OData entity to analyze (e.g., `PerPersonal`, `PerNationalId`) | | `country` | string | Yes | ISO country code to filter the sample | | `sample_size` | integer | No | Records to sample for population rates (default: 50, max: 200) |
## Example Queries Ask Claude in natural language: | Query | Tool Used | |-------|-----------| | "Show me all users in the Sales department" | `search_employees` | | "What permissions does jsmith have?" | `get_user_permissions` | | "Compare User config between dev and prod" | `compare_configurations` | | "Who's on vacation next week?" | `get_upcoming_time_off` | | "List all open job requisitions for Engineering" | `get_open_requisitions` | | "How much PTO does jdoe have left?" | `get_time_off_balances` | | "Show me all new hires starting in March" | `get_new_hires` | | "Who has a 10-year anniversary this month?" | `get_anniversary_employees` | | "What are the status of performance reviews for my team?" | `get_performance_review_status` | | "Show John's complete job history" | `get_employee_history` | | "What custom MDF objects exist in our instance?" | `get_mdf_object_definitions` | | "List all departments with their cost centers" | `get_foundation_objects` | | "Are there any pending workflow approvals?" | `get_pending_approvals` | | "Check the status of our integration jobs" | `get_integration_center_jobs` | ## Common SuccessFactors Entities | Category | Entities | |----------|----------| | **Employee** | User, EmpEmployment, EmpJob, PerPersonal, PerPhone, PerEmail | | **Foundation** | FOCompany, FODepartment, FOJobCode, FOLocation, FOPayGrade | | **Position** | Position, PositionEntity, PositionMatrixRelationship | | **Talent** | Goal, GoalPlan, PerformanceReview, Competency | | **Recruiting** | JobRequisition, Candidate, JobApplication | Use `list_entities` to discover all available entities in your instance. ## Troubleshooting
Authentication Errors (HTTP 401) - Verify credential format: user ID **without** `@instance` - Confirm the password is correct - Ensure the API user has proper permissions in SuccessFactors Admin Center
Validation Errors All inputs are validated to prevent injection attacks: | Parameter | Rules | |-----------|-------| | `instance` | Alphanumeric, underscores, hyphens only | | `entity` | Valid OData entity name pattern | | `filter` | No blocked keywords (`$batch`, `$metadata`, `