> For the complete documentation index, see [llms.txt](https://docs.siit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.siit.io/integrations/mcp.md).

# MCP

Siit's MCP Server exposes your workspace to AI tools that support the Model Context Protocol: Claude, Codex, Mistral, Cursor and more.

{% embed url="<https://screen.studio/share/ClTjiL6U>" %}

The Siit Model Context Protocol (MCP) app allows your third-party AI assistant to access your Siit data and account, so they can read and analyze your requests, and audit and update your service desk.<br>

### Setup Instructions

The Siit MCP connector is approved and published in Claude's connector directory. On Claude, browse to Siit in the directory and add it in a few clicks, no server URL to paste or configuration to wire up by hand. Every other MCP-compatible client (Codex, Mistral, Cursor, and more) still connects by adding a custom connector.

Tools authenticate with your Siit account via OAuth and can read and act on requests, people, and catalog resources within the data you can access in the Siit admin dashboard.

**Server URL:** `https://mcp.siit.io/mcp`\
**Auth:** OAuth 2.1 with dynamic client registration. Actions are performed on behalf of the authenticated user; access is scoped to the same data as in the Siit admin dashboard. **Transport:** Streamable HTTP.

For step-by-step connection instructions for each client, see the [Help Center setup guide.](https://help.siit.io/mcp-server-setup-guide)

> **Note:** On ChatGPT, the connector requires Dynamic Client Registration, which ChatGPT does not enable by default. See the Help Center setup guide for the exact steps.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2F9mUix9jajaAS5V206if8%2Fimage.png?alt=media&amp;token=f1dc3c6d-40e4-49f5-8b47-507457d6d821" alt=""><figcaption></figcaption></figure>

***

### What you can do with MCP today

Access follows the same scoping as the Siit admin dashboard, **the MCP cannot return data that the authenticated user cannot already see**, or perform writes that the authenticated user cannot already perform in the UI.

**Requests**

| Tool                     | Read / Write | Description                                                                                    |
| ------------------------ | ------------ | ---------------------------------------------------------------------------------------------- |
| `list_requests`          | Read         | List open requests with full context: requester, status, linked apps, equipment, SLA           |
| `get_request`            | Read         | Fetch a single request by ID with all nested details                                           |
| `get_request_events`     | Read         | List the full timeline of events on a request                                                  |
| `get_request_agent_logs` | Read         | Retrieve the AI agent's execution timeline: messages, tool calls, decisions                    |
| `update_request`         | Write        | Update any field on a request: status, assignee, priority, tags, linked apps, linked equipment |
| `send_request_message`   | Write        | Send a message in a request thread                                                             |
| `add_request_note`       | Write        | Add an internal note on a request                                                              |
| `list_request_tags`      | Read         | List all request tags                                                                          |
| `get_request_tag`        | Read         | Fetch a single request tag                                                                     |
| `create_request_tag`     | Write        | Create a request tag, available in every team inbox                                            |
| `update_request_tag`     | Write        | Rename a request tag; every request carrying it shows the new name                             |
| `delete_request_tag`     | Write        | Delete a request tag and remove it from every request carrying it, archived ones included      |
| `unarchive_request`      | Write        | Restore an archived request                                                                    |
| `fetch_attachment`       | Read         | Fetch an attachment on a request (file metadata and content)                                   |

> **Note** : `get_request` and `list_requests` also return `satisfaction_survey_rating` as part of the standard Request payload, so no extra call is needed to pull CSAT data into your AI client.

> **Note:** `get_request` and `list_requests` now carry a `requests_group_uid` field (null when the request isn't grouped), and `list_requests` accepts `mode=grouped` to list groups instead of individual requests.

**Grouped Requests**

| Tool                                | Read / Write | Description                                                                                                  |
| ----------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------ |
| `get_request_group`                 | Read         | Fetch a group's aggregate payload: request count, status/priority breakdown, requesters, assignees, and more |
| `get_request_group_events`          | Read         | List the group's own timeline: creation and membership changes                                               |
| `group_requests`                    | Write        | Create a new group from a set of requests                                                                    |
| `add_requests_to_group`             | Write        | Add requests to an existing group                                                                            |
| `remove_requests_from_group`        | Write        | Remove requests from a group                                                                                 |
| `rename_request_group`              | Write        | Rename a group                                                                                               |
| `disband_request_group`             | Write        | Disband a group, returning its requests to standalone                                                        |
| `send_message_to_requests_in_group` | Write        | Send one public message to every request in the group, delivered to each requester in their own channel      |
| `add_note_to_requests_in_group`     | Write        | Add one internal note to every request in the group, visible to admins only                                  |
| `set_status_of_requests_in_group`   | Write        | Set the status of every request in the group                                                                 |
| `set_priority_of_requests_in_group` | Write        | Set the priority of every request in the group                                                               |
| `set_assignee_of_requests_in_group` | Write        | Assign every request in the group to an admin, or unassign them all                                          |
| `add_tags_to_requests_in_group`     | Write        | Add tags to every request in the group, keeping the tags each one already carries                            |
| `archive_requests_in_group`         | Write        | Archive every request in the group                                                                           |
| `snooze_requests_in_group`          | Write        | Snooze every request in the group until a chosen date                                                        |

> **Note:** Bulk tools act only on the requests the authenticated user can already see, and they are not atomic, so an individual request can be skipped. Each one returns the number of requests it processed, which is a count of records handled rather than a delivery receipt. The group timeline records one bulk event per call, which is what you read back with `get_request_group_events`.

**People**

| Tool                  | Read / Write | Description                                                                        |
| --------------------- | ------------ | ---------------------------------------------------------------------------------- |
| `list_people`         | Read         | List users in your workspace                                                       |
| `get_person`          | Read         | Fetch a user with full profile: department, office location, Okta groups, and more |
| `create_person`       | Write        | Create a new user                                                                  |
| `update_person`       | Write        | Update a user's profile                                                            |
| `batch_update_people` | Write        | Update up to 25 users in one call, for example to move a group to a new department |
| `archive_person`      | Write        | Archive a user                                                                     |
| `unarchive_person`    | Write        | Restore an archived user                                                           |
| `merge_person`        | Write        | Merge two users into one                                                           |
| `whoami`              | Read         | Return the currently authenticated user                                            |

> **Note:** `batch_update_people` updates each user on its own, so one failure doesn't block the rest. It answers with a status per user, in the order you sent them, and nothing is updated at all when a uid is unknown or you can't manage users. The updated users aren't returned — read them back with `get_person`.

**CMDB (Apps & Equipments)**

| Tool                        | Read / Write | Description                                |
| --------------------------- | ------------ | ------------------------------------------ |
| `list_applications`         | Read         | List all apps in your catalog              |
| `get_application`           | Read         | Fetch a single app with full details       |
| `create_application`        | Write        | Add an app to your catalog                 |
| `update_application`        | Write        | Update an app                              |
| `list_equipments`           | Read         | List all equipment in your inventory       |
| `get_equipment`             | Read         | Fetch a single equipment with full details |
| `create_equipment`          | Write        | Add equipment to your inventory            |
| `update_equipment`          | Write        | Update an equipment                        |
| `list_equipment_categories` | Read         | List all equipment categories              |

> **Note:** an app's `app_owner` and `app_owner_backup` can each be a person, a team or a team inbox, and `create_application` and `update_application` accept any of the three. Teams and team inboxes share a uid prefix, so expanding the field is what tells them apart — and expanding it needs the matching read consent. Without it, the default response returns the owner's uid instead, and an explicit `expand` on the owner is refused.

**Services**

| Tool                               | Read / Write | Description                                   |
| ---------------------------------- | ------------ | --------------------------------------------- |
| `list_services`                    | Read         | List all services available in your catalog   |
| `get_services`                     | Read         | Fetch a single service with its configuration |
| `create_service`                   | Write        | Create a new service                          |
| `update_service`                   | Write        | Update a service                              |
| `create_service_custom_form_input` | Write        | Add a custom form field to a service          |
| `get_service_custom_form_input`    | Read         | Fetch a single custom form field              |
| `update_service_custom_form_input` | Write        | Update a custom form field                    |
| `delete_service_custom_form_input` | Write        | Permanently delete a custom form field        |

> **Note:** `create_service` and `update_service` set who the service is restricted to, with `is_restricted_to_audience` and an `audience` of matchers on people attributes — department, team, office location, legal entity, country, job title, contract type, lifecycle, status, preferred language, or named people. These are the same rules you set in the dashboard, see [Audience & visibility](/service-catalog/audience-and-visibility.md). Matchers alone change nothing: the restriction only applies while `is_restricted_to_audience` is true, and lifting it means setting that back to false rather than emptying the matchers. An `audience` replaces the whole matcher list, so read the current one back first when you only mean to change part of it.

**Workflow**

| Tool                           | Read / Write | Description                                                                                                                                                               |
| ------------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_workflows`               | Read         | List all workflows                                                                                                                                                        |
| `get_workflow`                 | Read         | Fetch a single workflow with its configuration                                                                                                                            |
| `create_workflow`              | Write        | Create a new workflow                                                                                                                                                     |
| `get_workflow_manifest_schema` | Read         | Return the workflow manifest schema (valid triggers, conditions and actions), as a catalog first and then a schema for the trigger and actions you pick                   |
| `get_workflow_execution_logs`  | Read         | Fetch a workflow run's execution log: trigger event and timestamp, ordered steps with status, inputs and outputs, and the failure reason on any step that didn't complete |

> **Note:** `get_workflow_execution_logs` reports a branch the run didn't take as one skipped step rather than listing every action inside it, which keeps the log readable on a workflow with many branches. Pass `include_skipped=true` when you need each skipped action spelled out.

> **Note:** workflows created through the MCP land as drafts and never run on their own. The MCP cannot change a workflow's status either: an admin sets it live, or pauses it, with **Set live** on the Workflows page. See [Workflow status](/workflow/triggers-overview.md#workflow-status).

**App Access**

| Tool                                              | Read / Write | Description                                                 |
| ------------------------------------------------- | ------------ | ----------------------------------------------------------- |
| `list_app_access_roles`                           | Read         | List all app access roles                                   |
| `get_app_access_role`                             | Read         | Fetch a single app access role                              |
| `create_app_access_role`                          | Write        | Create an app access role                                   |
| `update_app_access_role`                          | Write        | Update an app access role                                   |
| `delete_app_access_role`                          | Write        | Delete an app access role                                   |
| `get_app_access_role_provisioning_actions_schema` | Read         | Return the provisioning actions schema for app access roles |

> **Note:** `create_app_access_role` and `update_app_access_role` take an `audience` of the same shape, deciding who can request the role, alongside the `is_restricted_to_audience` switch that turns the restriction on.

**App Access Requests**

| Tool                         | Read / Write | Description                                                                     |
| ---------------------------- | ------------ | ------------------------------------------------------------------------------- |
| `get_app_access_request`     | Read         | Fetch a single app access request: the app, current status, and full timeline   |
| `approve_app_access_request` | Write        | Approve a pending app access request awaiting the authenticated user's decision |
| `reject_app_access_request`  | Write        | Reject a pending app access request awaiting the authenticated user's decision  |
|                              |              |                                                                                 |

> **Note:** Approve/reject tools only act on requests where the authenticated user's decision is pending, matching the same rule stated at the top of this page: the MCP can't do anything the user couldn't already do in the admin console.

**Knowledge base**

| Tool                      | Read / Write | Description                              |
| ------------------------- | ------------ | ---------------------------------------- |
| `list_articles`           | Read         | List knowledge base articles             |
| `get_article`             | Read         | Fetch a single article                   |
| `create_article`          | Write        | Create a new article                     |
| `update_article`          | Write        | Update an article                        |
| `publish_article`         | Write        | Publish an article to the knowledge base |
| `unpublish_article`       | Write        | Revert an article to draft               |
| `archive_article`         | Write        | Archive an article                       |
| `unarchive_article`       | Write        | Restore an archived article              |
| `list_article_categories` | Read         | List knowledge base categories           |

> **Note:** `create_article` and `update_article` take the same `is_restricted_to_audience` and `audience` as services, to decide who sees the article. A synced article — Notion, Confluence, Guru, Slab, Slack or an external link — keeps its content from its source, so those two fields are the only ones it accepts, and a call mixing them with a title or a body is refused whole.

**Organization**

Teams, departments, office locations and legal entities are your people groups. Each one can be created, renamed and deleted, and people can be added to it or taken out of it.

| Tool                                                                           | Read / Write | Description                                 |
| ------------------------------------------------------------------------------ | ------------ | ------------------------------------------- |
| `list_teams`                                                                   | Read         | List all teams                              |
| `get_team`                                                                     | Read         | Fetch a single team                         |
| `create_team` / `update_team` / `delete_team`                                  | Write        | Create, rename or delete a team             |
| `add_users_to_team` / `remove_users_from_team`                                 | Write        | Change who belongs to a team                |
| `list_departments`                                                             | Read         | List all departments                        |
| `get_department`                                                               | Read         | Fetch a single department                   |
| `create_department` / `update_department` / `delete_department`                | Write        | Create, rename or delete a department       |
| `add_users_to_department` / `remove_users_from_department`                     | Write        | Change who belongs to a department          |
| `list_office_locations`                                                        | Read         | List all office locations                   |
| `get_office_location`                                                          | Read         | Fetch a single office location              |
| `create_office_location` / `update_office_location` / `delete_office_location` | Write        | Create, rename or delete an office location |
| `add_users_to_office_location` / `remove_users_from_office_location`           | Write        | Change who is based in an office location   |
| `list_legal_entities`                                                          | Read         | List all legal entities                     |
| `get_legal_entity`                                                             | Read         | Fetch a single legal entity                 |
| `create_legal_entity` / `update_legal_entity` / `delete_legal_entity`          | Write        | Create, rename or delete a legal entity     |
| `add_users_to_legal_entity` / `remove_users_from_legal_entity`                 | Write        | Change who belongs to a legal entity        |
| `list_team_inboxes`                                                            | Read         | List all inboxes                            |
| `get_team_inbox`                                                               | Read         | Fetch a single inbox                        |

> **Note:** `list_people` reads a group's members directly — pass `team_uid`, `department_uid`, `office_location_uid` or `legal_entity_uid`. Pass `none` instead of a uid to find the people who have no team, department, office location or legal entity.

**Custom integrations**

A custom integration connects Siit to a third-party API that has no pre-built connector: a name, the credential to call it with, and the way that credential travels on every request. Each one carries custom actions, the individual operations Siit can run against it, described by a URL, an HTTP method (`GET`, `POST`, `PUT`, `PATCH` or `DELETE`, defaulting to `POST`), and the inputs and outputs it expects. You can also set all of this up in the admin console — see [Custom integrations](/integrations/custom-integrations.md).

`create_custom_action` and `update_custom_action` read and write `http_method` and `body`, so an action's method and its request body can be set from your AI client rather than in the console. Left alone, the body is a JSON object of the input values keyed by slug; a `body` replaces it with a raw template sent as is, which means you declare `Content-Type` yourself in the headers and quote string placeholders yourself. Pass an empty string to drop the template and go back to the default JSON body. A `submit_url` takes `{{inputs.<slug>}}` as well as context variables, company variables and secrets, which is how a `GET` action passes its inputs — nothing checks on save that the slug exists, so declare an input used in the URL path as required in every input definition the action runs with, and keep optional ones in the query string.

Enabling an action is required but not enough on its own; where it is offered also depends on how it is configured:

* **Run from a request or a person** — the action needs a manual run mode (`interactive_mode` other than `disabled`) and a request or person context.
* **Workflow step** — the action needs a workflow input definition (`workflow_input_definition`), even an empty one, and a context that matches the workflow's trigger.
* **App access role provisioning and deprovisioning** — the action needs a workflow input definition and the app access request context.

Custom integrations are available in every workspace, on every plan. What you can reach with these tools comes from your own role permissions, as everywhere else.

| Tool                        | Read / Write | Description                                                                         |
| --------------------------- | ------------ | ----------------------------------------------------------------------------------- |
| `list_custom_integrations`  | Read         | List your custom integrations                                                       |
| `get_custom_integration`    | Read         | Fetch a single custom integration                                                   |
| `create_custom_integration` | Write        | Create a custom integration with its credential, authentication method, and headers |
| `update_custom_integration` | Write        | Update a custom integration                                                         |
| `delete_custom_integration` | Write        | Delete a custom integration, with its actions and their history                     |
| `list_custom_actions`       | Read         | List the actions of a custom integration                                            |
| `get_custom_action`         | Read         | Fetch a single custom action                                                        |
| `create_custom_action`      | Write        | Declare a custom action: where it posts, what it asks for, and what it answers with |
| `update_custom_action`      | Write        | Update a custom action, including enabling or disabling it                          |
| `delete_custom_action`      | Write        | Remove a custom action, keeping its execution history                               |

> **Notes:**
>
> * The credential of a custom integration is write-only. It is never returned by any tool, and leaving it out of an update keeps the current one. A new custom action is created disabled, so nothing can run it until you enable it deliberately.
> * Disabling a custom action only stops it from being offered for new uses. Workflow steps and app access roles that already use it keep running it. To stop those runs, remove the action from them first; deleting the action instead makes those steps fail when they run.
> * These tools ask for the **Read Custom Integrations** and **Write Custom Integrations** consents the first time your client uses them. As everywhere else, they act with your own permissions.

***

### Use case examples

* **Triage your inbox without opening Siit** : Ask Claude "What are the open P1 requests assigned to no one?" and get a prioritized list with full context — requester department, linked apps, SLA status — then instruct it to assign and update them directly.
* **Investigate a request end to end :** Paste a Siit request link into Claude Code and ask it to investigate: who raised it, what app or equipment is involved, what their Okta group is, and whether there are similar open requests. Get a full diagnosis in seconds.
* **Run ad hoc analysis across your IT data :** Ask questions like "How many open requests are linked to Slack?" or "Show me all requests from the Engineering team this week" — combining Siit data with other connected tools like Notion or Linear for richer context.
* **Draft and send a reply from your AI client** : Ask Claude to draft a response to a specific request based on its context, then send it as a message in the thread — without ever switching tabs.
* **Bulk triage after a tool outage** : Ask "List all requests created in the last 2 hours linked to Okta, assign them to the IT team inbox, and tag them as incident." Done in one prompt.
* **Debug a workflow run**: Ask Claude why last night's onboarding Workflow skipped the equipment step, and it pulls the run's execution log, points at the step that broke, and reads back the error.

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.siit.io/integrations/mcp.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
