Access control for AI agents and MCP servers: allow, hold for approval, or block each tool call
Kisi MCP by usefulapi is installed from its publisher's own source and answers where it runs, so this marketplace is not in the path of a single call. There is no address here to send one to, and a panel that pretended otherwise would be showing you an answer we made up. Install it and call it from your own client — the Installation tab has the entry for each one.
What it does
Read Kisi places, doors, users, groups, access rights and access logs (no unlocking).
Quickstart
# 1 — add it to Claude Code
claude mcp add --scope user --transport http kisi-mcp-by-usefulapi https://kisi.usefulapi.io/mcp
# 2 — ask your agent for something these tools do
# kisi_get_current_user, kisi_get_organization, kisi_list_places and 17 more
Kisi MCP by usefulapi costs nothing on mcprush: there is no plan to choose here, no cap to set and nothing mcprush can bill you for.
Collected from a public index. Nobody has claimed this account, so nothing here was written by its author — claim it if it is yours.
Where are you running it?
Every route below installs the same thing and ends at the same approval screen. Nothing here runs on your machine and nothing runs on ours: this server answers at its publisher’s own address, and what you install is the connection straight to it.
This is a public server: it answers at its publisher’s own address and this marketplace is not in the path. Claude Code registers it in one command; --scope user makes it available in every project. The transport below is http, as the publisher's own manifest declares it.
claude mcp add --scope user --transport http kisi-mcp-by-usefulapi https://kisi.usefulapi.io/mcpReconnect, or start a new session, and the tools appear in the model’s tool list.
One config entry pointing straight at the publisher’s own address — this marketplace is not in the path, and nothing from this listing executes on your machine.
20 tools, with what each one reads, writes and reaches shown before you agree — the same list on every route above. Read the tool surface.
Tool surface
What the model actually sees. Descriptions are diffed on every release — see version history.
The Kisi user the API key belongs to (id, name, email, organization). Good first call. GET /user.
No parameter schema on file.
The current Kisi organization (name, domain, settings summary). GET /organization.
No parameter schema on file.
List places (sites/buildings) in the organization with address, time zone and lock/member counts. GET /places.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | no | Free-text search over place name. |
| ids | string | no | Comma-separated list of ids to fetch. |
| sort | string | no | Sort order. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
One place by id, including lockdown state. GET /places/{id}.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| place_id | integer | yes | The place id (numeric). |
List locks/doors with their state: online, unlocked, locked_down, configured, place and floor. Filter to find offline or locked-down doors. GET /locks.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | no | Free-text search over lock name. |
| place_id | integer | no | Only locks in this place. |
| floor_id | integer | no | Only locks on this floor. |
| online | boolean | no | Filter by online (true) / offline (false). |
| unlocked | boolean | no | Filter by currently unlocked (true) / locked (false). |
| locked_down | boolean | no | Filter by lockdown state. |
| configured | boolean | no | Filter by whether the lock is configured. |
| ids | string | no | Comma-separated list of ids to fetch. |
| sort | string | no | Sort order. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
One lock/door by id: online/unlocked/locked-down state, place, floor, settings. GET /locks/{id}.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| lock_id | integer | yes | The lock id (numeric). |
List access groups (who-can-open-what bundles of doors). Filter by place or by a lock to see which groups open that door. GET /groups.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | no | Free-text search over group name. |
| place_id | integer | no | Only groups of this place. |
| lock_id | integer | no | Only groups that include this lock. |
| scope | string | no | Organization-wide or place-scoped groups. |
| ids | string | no | Comma-separated list of ids to fetch. |
| sort | string | no | Sort order. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
One access group by id (name, description, place, member/lock counts, restrictions). GET /groups/{id}.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| group_id | integer | yes | The group id (numeric). |
The locks/doors an access group opens. GET /group_locks?group_id=.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| group_id | integer | yes | The group id (numeric). |
| query | string | no | Free-text search over lock name. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
List users (members) of the organization. Filter by group or place (users with access there), email, or free text over name/email/notes. Sort by last unlock. GET /users.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | no | Free-text search over user email, name and notes. |
| string | no | Exact email filter. | |
| group_id | integer | no | Only members of this group. |
| place_id | integer | no | Only users with access to this place. |
| ids | string | no | Comma-separated list of ids to fetch. |
| sort | string | no | Sort order; 'unlock' = by last unlock. |
| limit | integer | no | Max results to return (1-100). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
One user by id. GET /users/{id}.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| user_id | integer | yes | The user id (numeric). |
Who holds which role where: a user/team/guest's role on the organization, a place or a group (group members = door access). Filter by user, group, place or role. GET /role_assignments.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| user_id | integer | no | Only assignments of this user. |
| group_id | integer | no | Only assignments on this group. |
| place_id | integer | no | Only assignments on this place. |
| role_id | string | no | Filter by role id, e.g. group_basic, group_manager, place_owner, organization_administrator. |
| scope | string | no | Filter by scope. |
| query | string | no | Free-text search over user email and name. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
List access cards with status (activated/deactivated/unassigned), assignee and last use. GET /cards.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| user_id | integer | no | Only cards of this user. |
| status | string | no | Filter by status. |
| sort | string | no | Sort by last use. |
| ids | string | no | Comma-separated list of ids to fetch. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
Who was present at a place on a given day (derived from unlocks): actor, first/last unlock, last door. GET /presences.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| place_id | integer | yes | The place id (numeric). |
| date | string | yes | The day: a date (2026-10-08) or an RFC 3339 date-time with offset (2026-10-08T09:00:00+02:00). Kisi reads it as a day in the place's time zone; a bare date is sent as noon UTC of that day. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
Time rules: when a group's access is allowed, when doors auto-unlock (unlock timer), first-to-arrive, elevator permit timers. Filter by consequence or by the group/lock it applies to. GET /schedules.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| consequence | string | no | Filter by what the schedule does. |
| scheduleable_type | string | no | Type of the object (use with scheduleable_id). |
| scheduleable_id | integer | no | Id of the group/lock/elevator stop (use with scheduleable_type). |
| ids | string | no | Comma-separated list of ids to fetch. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
Kisi controllers (door hardware hubs) with online/offline status. Filter by place, lock or status. GET /controllers.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| place_id | integer | no | Only controllers in this place. |
| lock_id | integer | no | Only the controller of this lock. |
| status | string | no | Filter by status. |
| query | string | no | Free-text search over name, device id and token. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
Kisi readers (card/phone readers at doors) with model and online/offline status. GET /readers.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| place_id | integer | no | Only readers in this place. |
| lock_id | integer | no | Only readers of this lock. |
| status | string | no | Filter by status. |
| query | string | no | Free-text search over name, device id and token. |
| limit | integer | no | Max results to return (1-250). |
| offset | integer | no | Results to skip (offset paging; use pagination.next_offset). |
Search the access log (unlocks, denied attempts, lockdowns, admin changes) and return the first page. This CREATES a temporary saved search in Kisi (an event set, cursor-paginated, kept ~24 h); it changes no door, user or access right. Defaults to the past 90 days, the maximum width. If status is still in_progress or cursor is set, call kisi_get_event_set with the returned id. POST /event_sets.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| interval | string | no | ISO 8601 interval on event time, max 90 days: start/end (2026-10-01T00:00:00Z/2026-10-08T00:00:00Z), start/duration (2026-10-01T00:00:00Z/P7D) or duration/end (P1D/2026-10-08T00:00:00Z). |
| type | string | no | Event type(s), comma-separated, e.g. lock.unlock (see kisi_list_event_types). |
| success | boolean | no | Only successful (true) or failed/denied (false) events. |
| place_id | integer | no | Only events at this place. |
| actor_type | string | no | Actor type (use with actor_id). |
| actor_id | integer | no | Only events by this actor (e.g. a user id). |
| object_type | string | no | Object type, e.g. Lock, Place, Group, User (use with object_id). |
| object_id | integer | no | Only events about this object (e.g. a lock id). |
Read an event set from kisi_search_events: its status and events. Pass the previous page's cursor for the next page. GET /event_sets/{id}.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| event_set_id | integer | yes | The event set id (numeric). |
| cursor | string | no | The cursor from the previous page. |
| limit | integer | no | Events per page (default 50). |
All event type names usable as the type filter of kisi_search_events (e.g. lock.unlock). GET /events/types.
No parameter schema on file.
- Every tool — any call limit is its publisher’s, not ours
- No card, and mcprush charges nothing for it
- Runs at its publisher’s own address — this marketplace is not in the path
- Nothing to cap, because mcprush bills nothing
What counts against your monthly calls
| Tool | Unit | Calls used | Out of the allowance |
|---|
Nothing here is billable: mcprush charges nothing to install Kisi MCP by usefulapi or to call it, at any volume.
Two independent axes, because powerful and malicious are different questions. The grade is threat only. The capability level is blast radius, and it is never a penalty on the grade — it is priced as one subtract-only term in the score, where you can see it.
This listing is an address its publisher runs, and you connect to it directly — this marketplace is not in the path. The scanner reads packages and public source, and an address is neither: the repository linked on this page is where this record was collected from, not a copy of what the address serves, so it is not graded in its place. So there is no grade — not a withheld one, an unmeasured one.
Release history
This is an address its publisher runs: which release it serves is theirs to choose, so there is nothing here to pin. The history below is for reading; the current release on file is 1.2.1.
No release note was published with this version.
One review per account, from a signed-in account that does not publish this listing. Nothing else is asked — you can say what you think before you install it. Publishers can reply once per review, and a review can be edited or deleted by whoever wrote it.
Any signed-in account that does not publish Kisi MCP by usefulapi can review it, once — before installing it or after. A review from an account that has installed it is marked as one.
Nobody has reviewed this listing. The rating on the card is the mean of the reviews written here and nothing else, so there is no rating until somebody writes the first — which takes a signed-in account that does not publish it, and nothing else.