Repository navigation
MCP Server
FreeITSM speaks the Model Context Protocol (MCP), so an AI assistant - Claude Code, Claude Desktop, or any MCP client - can read it directly: "Which projects are off track, and why?", "What changed this morning?", "Is the VPN down?"
It is read-only, and it sees exactly what the analyst behind its API key may see.
- System β API β create a key with the MCP server permission. The key acts as the analyst you choose, so pick the analyst whose view the assistant should have. Limit it to companies if you need to.
- Give the assistant the address shown on that page:
https://your-server/api/mcp/
Claude Code:
claude mcp add --transport http freeitsm https://your-server/api/mcp/ --header "Authorization: Bearer fitsm_β¦"Any other client that supports MCP over HTTP ("Streamable HTTP") with a bearer token works the same way: the address, and the header Authorization: Bearer <key>.
Note
Connectors that only sign in with OAuth (rather than a key in a header) cannot connect yet: FreeITSM uses its API keys.
| Tool | Answers | Needs |
|---|---|---|
list_projects |
Projects with health, status, progress, target, project manager and why they are the colour they are | Projects |
project_overview |
One project in full: goal, health and why, stages and gates, open risks and issues, budget against actual, linked changes not yet approved, recent history | Projects |
project_raid |
A project's RAID log, with risk scores and plans | Projects |
project_budget |
Planned against actual, every line, labour - never one person's rate | Projects |
project_tasks |
A project's tasks, overdue first | Projects |
open_incidents |
Open tickets at a priority | Tickets |
ticket_spike |
Whether tickets are arriving faster than usual | Tickets |
related_tickets |
Tickets linked to one ticket | Tickets |
on_call |
Who is on call | Tickets |
service_status |
Services and open service incidents | Service Status |
recent_changes |
Changes in the last few days | Changes |
asset_lookup |
An asset by name, tag or serial | Assets |
impact_of |
What depends on a configuration item | CMDB |
known_errors |
Problems with a known workaround | Problems |
supplier_contact |
Who to call at a supplier | Contracts |
morning_checks |
Today's morning checks | Morning Checks |
search_knowledge |
Knowledge article titles | Knowledge |
Tickets are referred to by number and projects by code (PRJ-0042); project_* tools also accept a project's id or a unique part of its name. Ticket answers carry operational facts - numbers, states, subjects (a confidential ticket by number only) - not ticket bodies or requester details.
- Read-only. No tool changes anything. An assistant reading a ticket can be fed instructions by whoever wrote it; read-only makes that harmless.
- As the key's analyst. A tool is offered only if that analyst can open its module (the Needs column above) and has any permission it needs. A tool they cannot use is not listed at all.
- Never wider than the analyst. A key's companies are narrowed to the companies its analyst may see: a key left on all companies for an analyst limited to one company sees that one company, and a key naming a company the analyst cannot reach sees nothing there.
- Within those companies. The Projects and Knowledge tools are limited to them. On an install with more than one company, the tools that read one company's tickets, changes, assets, CMDB or problems are offered only when the key and its analyst both cover every company - they do not narrow themselves by company yet, so they are withheld rather than allowed to show another company's data.
- No chat. War-room search is not offered: it includes the analyst's direct messages and private channels, and a key can act as any analyst, so it would let a key holder read somebody's private conversations.
- History that names another module (a linked contract, a raised ticket, a Knowledge article) is left out of a project overview when the analyst cannot open that module.
- The same key rules as the REST API: expiry, rate limit, a disabled key or an inactive analyst, and last used on System β API.
- What comes back is text people wrote. Tool answers include titles, workarounds, plans, notes and comments that analysts (and sometimes customers, quoted in a known error or a service comment) wrote. The assistant reads them; because every tool is read-only, text that tries to give the assistant instructions cannot make FreeITSM do anything.
- Reviewed. An independent security review of the MCP layer (October 2026) found the gaps above - a key reaching beyond its analyst's companies, chat including direct messages, Knowledge ignoring the key's companies, database error text reaching the client - all fixed before release.
| File | What it is |
|---|---|
api/mcp/index.php |
The protocol: MCP Streamable HTTP, stateless JSON responses (no event stream, no session). initialize, notifications/* (202), ping, tools/list, tools/call. Speaks 2025-06-18, 2025-03-26 and 2024-11-05. JSON-RPC errors: -32700 parse, -32600 invalid (batches are refused - 2025-06-18 removed them), -32601 unknown method, -32602 unknown or forbidden tool. GET/DELETE are 405. A request whose Origin is not the request's own Host is refused - a second fence only: the real protection from browsers is that the endpoint takes nothing but a bearer key (no cookies, no CORS). |
includes/mcp/tools.php |
The tools and the gate. mcpEffectiveScope() narrows the key's companies to its analyst's, once, straight after authentication. Warbot handlers are called directly (not through warbotRunTool(), which returns exception text). MCP has its own search_knowledge through KnowledgeViewer::forApiKey(). A thin adapter over the Warbot registry (includes/warbot/tools.php): each Warbot tool is mapped to its module and marked company-safe or not in mcpWarbotToolMap(); the Projects tools are MCP-only and company-scoped by the key. mcpToolAllowed() = module access + capability + (company-safe, or single-company install, or a key covering every company). |
api/v1/lib/auth.php |
Reused as is: apiAuthenticate(), the mcp permission (api/v1/lib/permissions.php). |
api/mcp/.htaccess |
Passes the Authorization header through on FastCGI / PHP-FPM (#115). |
Adding a tool: a Warbot tool appears once it has a row in mcpWarbotToolMap() - module and whether it is company-safe. Do not mark a tool company-safe unless its handler genuinely scopes by company or reads install-wide data. An MCP-only tool is a mcpTools() entry with module, company_safe, capability and a handler (PDO, args, analystId, apiKey) returning text; throw ServiceError for a problem the assistant should see as a tool error.
Not built yet: write tools; OAuth sign-in for connectors that need it; company scoping inside the Warbot tools (so they can be offered to a single-company key); a log of which tools an assistant called.
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- π§ͺ Developer tests
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- Theming & Dark Mode
- ποΈ Recent β getting back to what you were doing
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
-
MobileβFriendly
- β³ π« Mobile: Tickets
- β³ π» Mobile: Assets
- β³ π Mobile: Calendar
- β³ π Mobile: Knowledge
- β³ π¦ Mobile: Service Status
- β³ πΌ Mobile: Watchtower
- β³ π§© Mobile: Problem Management
- β³ π Mobile: Change Management
- β³ πΏ Mobile: Software
- β³ β Mobile: Tasks
- β³ π Mobile: Forms
- β³ π Mobile: Contracts
- β³ π Mobile: Domains
- β³ π Mobile: People
- β³ π Mobile: Projects
- β³ π Mobile: LMS
- β³ πΊοΈ Mobile: CMDB
- β³ πΊοΈ Mobile: Network Mapper
- β³ π§ Mobile: Process Mapper
- β³ βοΈ Mobile: Workflow
- β³ π₯οΈ Mobile: System
- β³ π Mobile: Reporting
- β³ π Mobile: System Wiki
- β³ π Mobile: Self-Service Portal
- β³ π§° Mobile: Techniques & Tricks
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- β³ π‘οΈ CSRF protection (S4) β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- π CardDAV contact sync
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π REST API: Domains
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ π·οΈ REST API: Cost centres
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ π Rota copy and paste β Developer Deep Dive
- β³ β Checklists & SOPs
- β³ βοΈ Mandatory fields
- β³ π·οΈ Ticket categories
- β³ π₯ Assigning tickets to a team, and escalation
- β³ π’ One board across every company
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
-
β³
βοΈ Telegram channel - β³ β CSAT company scope and filters β Developer Guide
- β³ π₯ Microsoft Teams channel
- β³ π¨οΈ Mattermost channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ β Record previews
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ π¨ Telling the analyst a ticket is theirs
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ π Confidential tickets
- β³ π₯ Portal managers
- β³ π Who has seen a ticket
- β³ π Reading long tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π½ Just my tickets, or no closed ones
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
- π Projects
-
Assets
- β³ π’ Moving an asset between companies
- β³ π Shared asset locations
- β³ π§βπΌ Assigning assets to analysts
- β³ π Warranty and lease alerts
- β³ π Saved table views
- β³ π¨οΈ Recording anything, and importing it
- β³ π·οΈ QR asset labels
- β³ π Who holds what, and handover documents
- β³ π₯οΈ The inventory agent (PowerShell)
- β³ ποΈ Proxmox VE servers
- β³ βοΈ VMware Cloud Director servers
- β³ π Linking equipment to tickets
- β³ βοΈ Follow-up tasks on a ticket
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
-
Forms
- β³ π¨ The form designer β Developer Guide
- β³ π Layout & the grid β Developer Guide
- β³ ποΈ Collections β grouping submissions
- β³ π Submissions as PDFs
- β³ β‘ What happens next β a form's own actions
- β³ π οΈ Sections & conditional logic β Developer Guide
- β³ π οΈ Lookup fields β Developer Guide
- β³ π‘οΈ Catalogue request approvals
- People
- Domains
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ π’ One board across every company
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)
- What this is
-
π Bugs resolved
- β³ πΌοΈ Logo and courses broke on Apache with PHP-FPM
- β³ π’ Chat tickets ignored your ticket numbering
- β³ π Dates shown as a dash, or in server time
- β³ π Assets β Users showed people from other companies
- β³ π Restricted analysts could read other modules' data
- β³ πΌοΈ Replies with a picture in the thread failed to send
- β³ π Reply attachments never reached the customer
- β³ π οΈ Outbound email attachments β Developer Guide
- β³ π A global SSO provider was missing from the portal
- β³ π Behind a proxy, the SSO redirect said http
- β³ βοΈ The portal tagline moved when you saved it
- β³ π¨ The portal settings screen forgot what you saved
- β³ π‘οΈ The approvals inbox said "Error" and nothing else
- β³ π A table's answers were missing from the PDF
- β³ β A single-select column let you tick every option
- β³ π The portal ignored a form's field widths
- β³ π The tasks board stopped taking clicks
- β³ ποΈ #121 The index list is out of date after upgrading
- β³ π #133 The calendar subscription was empty
- β³ π #131 Tasks always reopened on the board
- β³ π₯ #129 Every page returned HTTP 500 after upgrading
- β³ π³ #127 A PHP warning above the System page
- β³ π #126 Notes stamped with the server's clock
- β³ π Storing every date in UTC
- β³ πͺ The portal was down for everyone signed in
- β³ βοΈ #120 Workflow notes could never be written
- β³ βοΈ #123 Three errors when running Database Verification
- β³ π #122 The description box was a stub in the corner
- β³ π£ Demo data deleted real accounts
- β³ π #117 Sign-in redirected to the wrong address
- β³ π¨ #108 The priority dot was invisible
- β³ β±οΈ #116 Time logged from the right-click menu
- β³ π #114 API keys refused by our own guard
- β³ ποΈ #110 Assigning a task told nobody
- β³ πͺ #107 Signed out while still working
- β³ π #103 "Share with Requester" reached nobody
- β³ π #102 Search found nothing for hyphens
- β³ πͺ #101 Source code editor opened behind
- β³ βοΈ #88 Subtasks could not be ticked off
- β³ π» #84 Asset deep link selected nothing
- β³ π« #79 A new ticket arrived with no status
- β³ π§ #79 A ticket from email did not say so
- β³ π #78 Bell opened to nothing
- β³ π¬ #77 Mail only collected from Inbox
- β³ π #74 The default password could not be changed
- β³ π¦ #70 Renaming an impact level
- β³ π€ #67 App-only mailboxes could not send
- β³ π #45 Verify only ever worked for Microsoft
- β³ π #45 IMAP reported as not authenticated
- β³ βοΈ An email template stopped escaping itself
- β³ π The portal dashboard showed the wrong time
- β³ π’ The folder said 99 and the list showed 96