SuccessFactors-MCP
SAP SuccessFactors Model Context Protocol Server
Installation ·
Quick Start ·
62 Tools ·
Deployment ·
API Reference
---
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`, `