Skip to main content
Glama
dbankscard

Jamf Pro MCP Server

by dbankscard
README.md
# Jamf Pro MCP Server v2.2

[![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue)](https://www.typescriptlang.org/)
[![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.0.0-purple)](https://github.com/modelcontextprotocol/sdk)
[![Tools](https://img.shields.io/badge/Tools-115-orange)]()
[![Resources](https://img.shields.io/badge/Resources-12-green)]()
[![Prompts](https://img.shields.io/badge/Prompts-12-blue)]()

A comprehensive MCP (Model Context Protocol) server that enables AI assistants to interact with Jamf Pro for complete Apple device management. Works with Claude Desktop and **ChatGPT** (via MCP Connectors).

**Two modes**: Classic Mode (115 individual tools) or **Code Mode** (2 tools + sandboxed JavaScript SDK)

### What's New in v2.2

- **Code Mode** — a new execution model that exposes just 2 MCP tools (`jamf_search` + `jamf_execute`) instead of 115 individual tools. The agent writes JavaScript that runs in a sandboxed `node:vm` context with a typed Jamf API client, enabling complex multi-step workflows in a single tool call. Includes capability-based access control, budget tracking, plan/apply workflow, and an approval gate for high-impact commands.
- **Concurrency limiting** — semaphore-style `ConcurrencyLimiter` (default 5, configurable via `JAMF_MAX_CONCURRENCY`) prevents 429 rate-limit errors. Applied to both the core API client and Code Mode sandbox.
- **Policy caching** — `getPolicyDetails` results are now cached to avoid redundant API calls, with automatic invalidation on policy writes.
- **Static computer group XML fix** — `createStaticComputerGroup` and `updateStaticComputerGroup` now use proper XML via `XmlBuilder` (with escaping) instead of broken JSON or raw template literals.

### What's in v2.1

- **115 tools** (up from 56) — expanded coverage across the full Jamf Pro API and Classic API
- **12 resources** — all returning live data including compliance, storage, OS versions, encryption, and patch reports
- **12 workflow prompts** — guided templates for common admin tasks like onboarding, offboarding, security audits, and staged rollouts
- **Compound tools** — single-call operations like `getFleetOverview`, `getDeviceFullProfile`, `getSecurityPosture`, and `getPolicyAnalysis` that combine multiple API calls behind the scenes
- **Bearer Token authentication on Classic API** — full OAuth2 Client Credentials support without needing a username/password
- **Parallel API calls** — batch operations and compound tools run requests concurrently for faster results
- **Correct Jamf terminology** — all documentation and tool descriptions align with official Jamf developer documentation

![Tests](https://github.com/dbankscard/jamf-mcp-server/actions/workflows/test-skills.yml/badge.svg)

## Quick Start

### For Claude Desktop Users
```bash
git clone https://github.com/dbankscard/jamf-mcp-server.git
cd jamf-mcp-server
npm install
npm run build
```

Configure your credentials in Claude Desktop (see [Configuration](#configuration) below).

### For ChatGPT Users
```bash
git clone https://github.com/dbankscard/jamf-mcp-server.git
cd jamf-mcp-server
./chatgpt/start-chatgpt-poc.sh
```

See our [ChatGPT Quick Start Guide](chatgpt/QUICK_START.md) for 5-minute setup.

## Code Mode (New)

Code Mode replaces 115 individual MCP tools with just 2:

| Tool | Purpose |
|---|---|
| `jamf_search` | Discover API methods — search by keyword, browse by category, view signatures and required capabilities |
| `jamf_execute` | Run JavaScript in a sandboxed VM with access to the full Jamf API client |

**Why Code Mode?** This implementation is inspired by [Cloudflare's Code Mode pattern](https://blog.cloudflare.com/code-mode-mcp/), which addresses a fundamental tension in MCP: agents need many tools to do useful work, but every tool definition consumes context window tokens. Cloudflare found that exposing their full API as individual MCP tools would consume over 1 million tokens — more than the entire context window of most models. Their solution: collapse everything into a `search` + `execute` pattern where agents discover APIs on demand and write code against a typed SDK, reducing token usage by up to 99.9%.

We applied the same pattern to Jamf Pro. Our 115 Classic Mode tools consume ~14,000 tokens of tool definitions. Code Mode reduces that to ~500 tokens (2 tool definitions) while retaining access to the full API surface. The agent uses `jamf_search` to discover methods, then writes JavaScript that runs in a sandboxed `node:vm` context. This also enables multi-step workflows in a single tool call — chaining API calls, filtering results, and building reports without LLM round-trips between each step.

**Safety features:**
- **Plan/Apply workflow** — run with `mode: "plan"` to preview all writes without executing, then `mode: "apply"` to commit
- **Capability-based access** — declare only the permissions your code needs (`read:computers`, `write:policies`, `command:mdm`, etc.)
- **Budget tracking** — automatic call-count limits prevent runaway loops
- **Approval gate** — high-impact commands (wipe, lock, delete) require an explicit approval token
- **Concurrency throttling** — API calls are rate-limited to prevent 429 errors

### Code Mode Configuration

Use `dist/index-code.js` as the entry point instead of `dist/index-main.js`:

```json
{
  "mcpServers": {
    "jamf-code": {
      "command": "node",
      "args": ["/absolute/path/to/jamf-mcp-server/dist/index-code.js"],
      "env": {
        "JAMF_URL": "https://your-instance.jamfcloud.com",
        "JAMF_CLIENT_ID": "your-api-client-id",
        "JAMF_CLIENT_SECRET": "your-api-client-secret"
      }
    }
  }
}
```

### Code Mode Example

```javascript
// Find all computers not checked in for 30 days
const computers = await jamf.getAllComputers(200);
const stale = computers.filter(c => helpers.daysSince(c.lastContactTime) > 30);
log(`Found ${stale.length} stale computers`);
return stale.map(c => ({ id: c.id, name: c.name, lastContact: c.lastContactTime }));
```

### Code Mode vs Classic Mode Benchmark

Real numbers from a live Jamf Pro instance (`npm run benchmark`):

#### Tool Definition Overhead

Every conversation loads all tool definitions into the LLM's context window. Fewer tools = more room for actual work.

| Mode    | Tools | Def. Size (bytes) | Est. Tokens |
|---------|------:|--------------:|--------:|
| Classic |   115 |        55,639 |  13,910 |
| Code    |     2 |         1,963 |     491 |

Code Mode uses **28x fewer tokens** just for tool definitions.

#### Scenario Results

10 scenarios covering baseline parity, cross-domain joins, multi-source audits, and workflows that are impossible in Classic Mode:

| #  | Scenario                       | Mode    | LLM Trips | Time (ms) | Completable |
|---:|--------------------------------|---------|----------:|----------:|:-----------:|
|  1 | Single device lookup           | classic |         1 |       308 | Yes         |
|  1 | Single device lookup           | code    |         1 |       241 | Yes         |
|  2 | Device profile + policy logs   | classic |         1 |       276 | Yes         |
|  2 | Device profile + policy logs   | code    |         1 |       228 | Yes         |
|  3 | Orphaned scripts audit         | classic |         2 |       131 | Yes         |
|  3 | Orphaned scripts audit         | code    |         1 |       172 | Yes         |
|  4 | Policies targeting a group     | classic |         2 |       133 | Yes         |
|  4 | Policies targeting a group     | code    |         1 |     2,611 | Yes         |
|  5 | OS version by department       | classic |       N/A |       N/A | **No**      |
|  5 | OS version by department       | code    |         1 |     1,073 | Yes         |
|  6 | Full security audit            | classic |         4 |    62,945 | Yes         |
|  6 | Full security audit            | code    |         1 |     6,936 | Yes         |
|  7 | Policy comparison              | classic |         2 |       221 | Yes         |
|  7 | Policy comparison              | code    |         1 |       115 | Yes         |
|  8 | Stale devices + details (top 10) | classic |       1 |     1,017 | Yes         |
|  8 | Stale devices + details (top 10) | code    |       1 |         4 | Yes         |
|  9 | Package dependency audit       | classic |         1 |    15,639 | Yes         |
|  9 | Package dependency audit       | code    |         1 |    15,015 | Yes         |
| 10 | Group + FileVault + OS filter  | classic |       N/A |       N/A | **No**      |
| 10 | Group + FileVault + OS filter  | code    |         1 |       187 | Yes         |

**Code Mode: 10/10 completable. Classic Mode: 8/10.**

**Key takeaways:**

- **Tool definition overhead**: Classic Mode consumes ~14K tokens of context window just for tool definitions — before any work begins. Code Mode uses ~500 tokens.
- **Impossible workflows**: Scenarios 5 and 10 require cross-resource joins (OS version × department, group members × FileVault × OS filter) that Classic Mode simply cannot express in bounded tool calls.
- **Multi-step workflows**: Security audit (S6) drops from 4 sequential LLM round-trips to 1. Policy comparison (S7) drops from 2 to 1. Each saved round-trip eliminates seconds of LLM inference latency.
- **Cross-domain joins**: Orphaned scripts (S3), group-scoped policies (S4), and package dependencies (S9) each require fetching a list, then detail-fetching N items — a pattern that forces Classic Mode into N sequential LLM calls. Code Mode does it in 1.
- **Simple lookups**: Roughly equivalent. Classic's purpose-built tools have slightly less overhead for single-call operations.
- **Scaling note**: These results are from a small Jamf instance. On a production fleet with hundreds of policies and devices, Classic Mode trip counts for S3/S4/S8/S9 would reach 10–20+, pushing the average LLM round-trip reduction well above 80%.

Run the benchmark yourself:
```bash
npm run benchmark                        # all 10 scenarios
npm run benchmark -- --scenarios 1,5,10  # run a subset
# requires JAMF_URL, JAMF_CLIENT_ID, JAMF_CLIENT_SECRET
```

## Classic Mode (115 Tools)

## What You Can Do

Ask natural language questions about your Jamf fleet:
- "How is my fleet doing?" — uses `getFleetOverview` for a single-call summary
- "Tell me about LAPTOP-001" — uses `getDeviceFullProfile` to resolve by name, serial, or ID
- "What's our security posture?" — uses `getSecurityPosture` for encryption and compliance analysis
- "How is the Software Install policy performing?" — uses `getPolicyAnalysis` with auto-resolve by name
- "Find all devices that haven't checked in for 30 days"
- "Deploy software updates to the marketing team"
- "Retrieve the LAPS password for this device"
- "Show me patch compliance across the fleet"

## Tools (115)

### Compound Tools (Start Here)
These combine multiple API calls into a single operation:

- **getFleetOverview**: Comprehensive fleet summary — inventory counts, compliance rates, and mobile device status in one call
- **getDeviceFullProfile**: Complete device profile by name, serial, or ID — resolves automatically and fetches details, policy logs, and history in parallel
- **getSecurityPosture**: Fleet security analysis — FileVault encryption rates, compliance status, and OS version currency
- **getPolicyAnalysis**: Policy analysis by ID or name — configuration, scope, compliance, and performance

### Device Management
- **searchDevices**: Find devices by name, serial number, IP address, or username
- **getDeviceDetails**: Detailed device information by ID
- **checkDeviceCompliance**: Find devices that haven't reported in X days
- **getDevicesBatch**: Get details for multiple devices in a single request
- **updateInventory**: Force inventory update on a device

### Computer History & MDM Commands
- **getComputerHistory**: Full computer history — policy logs, MDM commands, audit events, screen sharing, user/location changes
- **getComputerPolicyLogs**: Policy execution logs showing success/failure per device
- **getComputerMDMCommandHistory**: MDM command history with status and timestamps
- **sendComputerMDMCommand**: Send MDM commands to macOS — lock, wipe, restart, shutdown, remote desktop (requires confirmation)
- **flushMDMCommands**: Clear pending/failed MDM commands to unstick devices (requires confirmation)

### Policy Management
- **listPolicies**: List all policies with optional category filter
- **getPolicyDetails**: Detailed policy info including scope, scripts, and packages
- **searchPolicies**: Search policies by name
- **executePolicy**: Run a policy on specific devices (requires confirmation)
- **createPolicy**: Create a new policy with full configuration (requires confirmation)
- **updatePolicy**: Update an existing policy (requires confirmation)
- **clonePolicy**: Clone a policy with a new name (requires confirmation)
- **setPolicyEnabled**: Enable or disable a policy (requires confirmation)
- **updatePolicyScope**: Add/remove computers and groups from policy scope (requires confirmation)
- **deletePolicy**: Delete a policy (requires confirmation)

### Script Management
- **listScripts**: List all scripts
- **searchScripts**: Search scripts by name
- **getScriptDetails**: Full script content, parameters, and metadata
- **deployScript**: Execute a script on devices (requires confirmation)
- **createScript**: Create a new script (requires confirmation)
- **updateScript**: Update an existing script (requires confirmation)
- **deleteScript**: Delete a script (requires confirmation)

### Configuration Profile Management
- **listConfigurationProfiles**: List profiles (computer or mobile device)
- **getConfigurationProfileDetails**: Detailed profile information
- **searchConfigurationProfiles**: Search profiles by name
- **deployConfigurationProfile**: Deploy a profile to devices (requires confirmation)
- **removeConfigurationProfile**: Remove a profile from devices (requires confirmation)
- **deleteConfigurationProfile**: Delete a configuration profile (requires confirmation)

### Package Management
- **listPackages**: List all packages
- **searchPackages**: Search packages by name
- **getPackageDetails**: Detailed package information
- **getPackageDeploymentHistory**: Deployment history via policy analysis
- **getPoliciesUsingPackage**: Find all policies using a specific package
- **getPackageDeploymentStats**: Deployment statistics and scope analysis

### Computer Group Management
- **listComputerGroups**: List groups (smart, static, or all)
- **getComputerGroupDetails**: Group details including membership and smart group criteria
- **searchComputerGroups**: Search groups by name
- **getComputerGroupMembers**: List all members of a group
- **createStaticComputerGroup**: Create a static group (requires confirmation)
- **updateStaticComputerGroup**: Update group membership (requires confirmation)
- **deleteComputerGroup**: Delete a group (requires confirmation)

### Advanced Computer Searches
- **listAdvancedComputerSearches**: List all saved advanced searches
- **getAdvancedComputerSearchDetails**: Get search configuration and results
- **createAdvancedComputerSearch**: Create a new advanced search (requires confirmation)
- **deleteAdvancedComputerSearch**: Delete a saved search (requires confirmation)

### Mobile Device Management
- **searchMobileDevices**: Search mobile devices by name, serial, or UDID
- **getMobileDeviceDetails**: Detailed mobile device information
- **listMobileDevices**: List all mobile devices
- **listMobileDeviceApplications**: List mobile device applications configured for delivery
- **getMobileDeviceApplicationDetails**: Get a delivered mobile application definition and scope details
- **updateMobileDeviceInventory**: Force inventory update on a mobile device
- **sendMDMCommand**: Send MDM commands — lock, wipe, clear passcode, lost mode, settings (requires confirmation)
- **listMobileDeviceGroups**: List mobile device groups
- **getMobileDeviceGroupDetails**: Group details including membership

### Reporting & Analytics
- **getInventorySummary**: Fleet inventory summary — device counts, OS distribution, model distribution
- **getDeviceComplianceSummary**: Compliance summary — check-in rates, failed policies, missing software
- **getPolicyComplianceReport**: Policy compliance — success/failure rates, scope coverage
- **getSoftwareVersionReport**: Software version distribution across devices

### Buildings, Departments & Categories
- **listBuildings** / **getBuildingDetails**: Organizational buildings for multi-site scoping
- **listDepartments** / **getDepartmentDetails**: Departments for scoping and reporting
- **listCategories** / **getCategoryDetails**: Categories for organizing policies, scripts, and profiles

### Local Administrator Password Solution (LAPS)
- **getLocalAdminPassword**: Retrieve the current LAPS password for a device (requires confirmation)
- **getLocalAdminPasswordAudit**: Audit trail of password views and rotations
- **getLocalAdminPasswordAccounts**: List LAPS-managed accounts on a device

### Patch Management
- **listPatchSoftwareTitles**: List patch software title configurations
- **getPatchSoftwareTitleDetails**: Patch title details with versions and definitions
- **listPatchPolicies**: List patch policies with deployment status
- **getPatchPolicyDashboard**: Patch compliance dashboard — latest version, pending, failed

### Extension Attributes
- **listComputerExtensionAttributes**: List all custom extension attributes
- **getComputerExtensionAttributeDetails**: Full EA details including script content
- **createComputerExtensionAttribute**: Create a new extension attribute (requires confirmation)
- **updateComputerExtensionAttribute**: Update an extension attribute (requires confirmation)
- **deleteComputerExtensionAttribute**: Delete an extension attribute (requires confirmation)

### Managed Software Updates
- **listSoftwareUpdatePlans**: List active and completed OS update plans
- **createSoftwareUpdatePlan**: Create an OS update plan for specific devices (requires confirmation)
- **getSoftwareUpdatePlanDetails**: Update plan status and device progress

### PreStage Enrollments
- **listComputerPrestages** / **getComputerPrestageDetails** / **getComputerPrestageScope**: Computer PreStage Enrollment configuration and device assignments
- **listMobilePrestages** / **getMobilePrestageDetails**: Mobile device PreStage Enrollments

### Network Segments
- **listNetworkSegments**: List network segments for location-based management
- **getNetworkSegmentDetails**: Segment details including IP ranges and building assignment

### Accounts & Users
- **listAccounts** / **getAccountDetails** / **getAccountGroupDetails**: Jamf Pro admin accounts and groups with privileges
- **listUsers** / **getUserDetails** / **searchUsers**: End-user records (not admin accounts)

### App Installers
- **listAppInstallers**: List Jamf App Catalog titles
- **getAppInstallerDetails**: Detailed app installer information

### Restricted Software
- **listRestrictedSoftware**: List restricted software entries
- **getRestrictedSoftwareDetails**: Restricted software configuration details
- **createRestrictedSoftware**: Create a new restricted software entry (requires confirmation)
- **updateRestrictedSoftware**: Update an existing restricted software entry (requires confirmation)
- **deleteRestrictedSoftware**: Delete a restricted software entry (requires confirmation)

### Webhooks
- **listWebhooks**: List configured webhooks
- **getWebhookDetails**: Webhook configuration details

## Resources (12)

| Resource URI | Description |
|---|---|
| `jamf://inventory/computers` | Paginated computer inventory |
| `jamf://inventory/mobile-devices` | Paginated mobile device inventory |
| `jamf://reports/compliance` | Security and patch compliance report |
| `jamf://reports/mobile-device-compliance` | Mobile device compliance and management status |
| `jamf://reports/storage` | Disk usage analytics |
| `jamf://reports/os-versions` | OS version breakdown |
| `jamf://reports/patch-compliance` | Fleet-wide patch compliance by software title |
| `jamf://reports/encryption-status` | FileVault encryption compliance |
| `jamf://reports/extension-attributes` | Extension Attributes collection summary |
| `jamf://inventory/prestages` | PreStage Enrollment assignments overview |
| `jamf://reports/failed-mdm-commands` | Devices with stuck or failed MDM commands |
| `jamf://reports/laps-audit` | LAPS password access audit trail |

## Prompts (12 Workflow Templates)

| Prompt | Description |
|---|---|
| `troubleshoot-device` | Step-by-step device troubleshooting |
| `deploy-software` | Software deployment workflow |
| `compliance-check` | Comprehensive compliance reporting |
| `mass-update` | Bulk device operations |
| `storage-cleanup` | Disk space management |
| `security-audit` | Full security posture audit — encryption, OS currency, compliance, failed policies |
| `new-device-onboarding` | Verify new device enrollment — profiles, policies, group memberships |
| `device-offboarding` | Device offboarding — unscope, wipe/lock, retire from inventory |
| `software-update-review` | OS version distribution review and update planning |
| `fleet-health-dashboard` | Comprehensive fleet health — devices, compliance, storage, OS, mobile |
| `investigate-device-issue` | Deep device investigation — profiles, policies, groups, scripts |
| `policy-rollout` | Staged policy rollout — clone, test group, verify, expand to production |

## Skills (ChatGPT Integration)

Advanced multi-step operations for the ChatGPT connector:

- **skill_device_search**: Intelligent device search with natural language processing
- **skill_find_outdated_devices**: Identify devices not checking in
- **skill_batch_inventory_update**: Update multiple devices efficiently
- **skill_deploy_policy_by_criteria**: Deploy policies based on device criteria
- **skill_scheduled_compliance_check**: Automated compliance reporting

## Configuration

### Jamf Pro API Authentication

1. In Jamf Pro, go to **Settings** > **System** > **API Roles and Clients**
2. Create a new API Role with necessary permissions
3. Create a new API Client — note the Client ID and generate a Client Secret

### Claude Desktop Configuration

Add to your Claude Desktop config file:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "jamf-pro": {
      "command": "node",
      "args": ["/absolute/path/to/jamf-mcp-server/dist/index-main.js"],
      "env": {
        "JAMF_URL": "https://your-instance.jamfcloud.com",
        "JAMF_CLIENT_ID": "your-api-client-id",
        "JAMF_CLIENT_SECRET": "your-api-client-secret"
      }
    }
  }
}
```

### ChatGPT Configuration

See [ChatGPT Connector Setup](chatgpt/CHATGPT_CONNECTOR_README.md) for detailed instructions.

### Enhanced Mode (Optional)

```json
{
  "env": {
    "JAMF_USE_ENHANCED_MODE": "true",
    "JAMF_MAX_CONCURRENCY": "5",
    "JAMF_MAX_RETRIES": "3",
    "JAMF_RETRY_DELAY": "1000",
    "JAMF_RETRY_MAX_DELAY": "10000",
    "JAMF_DEBUG_MODE": "false",
    "JAMF_ENABLE_RETRY": "true",
    "JAMF_ENABLE_RATE_LIMITING": "false",
    "JAMF_ENABLE_CIRCUIT_BREAKER": "false",
    "JAMF_READ_ONLY": "false"
  }
}
```

## Installation

```bash
git clone https://github.com/dbankscard/jamf-mcp-server.git
cd jamf-mcp-server
npm install
npm run build
```

### Development

```bash
npm run dev          # Run in development mode
npm run build:force  # Build without tests
npm test             # Run tests
```

## Security

- **Read-Only Mode**: Set `JAMF_READ_ONLY=true` to prevent any modifications
- **Confirmation Required**: All destructive operations require explicit `confirm: true`
- **Tool Annotations**: Each tool declares `readOnlyHint` and `destructiveHint` for client-side safety
- **Client Credentials Authentication**: Supports Jamf Pro API roles and clients
- **Concurrency Limiting**: Prevents 429 rate-limit errors (default 5 concurrent, configurable via `JAMF_MAX_CONCURRENCY`)
- **Code Mode Sandbox**: `node:vm` isolation — no `require`, `import`, `fetch`, `fs`, or `process` access
- **Rate Limiting**: Optional built-in rate limiter
- **Circuit Breaker**: Optional circuit breaker for failure protection

### Recommended API Permissions

For full functionality:
- Read access to computers, policies, scripts, configuration profiles, packages, mobile devices, buildings, departments, categories, Extension Attributes, Patch Management, PreStage Enrollments, network segments, accounts, users, webhooks
- LAPS password access (for LAPS tools)
- Update access for inventory updates, policies, scripts, extension attributes
- Execute access for policies, scripts, and MDM commands

For read-only mode:
- Read access to all resources only

## Architecture

```
                    ┌─ Classic Mode (110 tools) ──┐
Claude Desktop ──>  │  MCP Server (stdio)          │──>  Jamf Pro API
                    ├─ Code Mode (2 tools) ────────┤
                    │  jamf_search + jamf_execute   │──>  (sandboxed VM)  ──>  Jamf Pro API
                    └──────────────────────────────┘
ChatGPT ──>  Tunnel (Cloudflare) ──>  MCP Server (HTTP)  ──>  Jamf Pro API
```

The server uses a hybrid API client that supports both the Jamf Pro API and Classic API, with automatic fallback between them for maximum compatibility across Jamf Pro versions. All API calls pass through a concurrency limiter to prevent rate-limit errors.

## Troubleshooting

### Authentication Issues
- Verify your API credentials (Client ID and Secret)
- Ensure the API client has the required permissions
- For Classic API endpoints, the server automatically uses Bearer Token authentication

### 503 Errors on Classic API
- If using Client Credentials only (no username/password), ensure you're running v2.1+ which supports Bearer Token authentication on Classic API endpoints

### Timeouts on Compound Tools
- The default request timeout is 30 seconds
- Compound tools like `getFleetOverview` make parallel API calls and may need more time on slower instances

## Contributing

Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Submit a pull request

## License

MIT

## Resources

- [Model Context Protocol Documentation](https://modelcontextprotocol.io/)
- [Jamf Pro API Documentation](https://developer.jamf.com/)
- [ChatGPT MCP Connectors](https://help.openai.com/en/articles/9824990-using-connectors-in-chatgpt)
- [Claude Desktop MCP Servers](https://modelcontextprotocol.io/clients/claude)

## Support

- [Create an Issue](https://github.com/dbankscard/jamf-mcp-server/issues)
- [View Documentation](docs/)
- [Fork this Repository](https://github.com/dbankscard/jamf-mcp-server/fork)

---

Built with ❤️ for the Jamf, Claude, and ChatGPT communities