Keen · Model Context Protocol

Your ISMS, on the tool belt

An AI client that asks plain-language questions of your frameworks, risks, policies and evidence - reading only what its person approved, writing only after they say so.

What an AI assistant is doing in my ISMS

Keen holds a lot of structured truth about an organisation: frameworks and their controls, the Statement of Applicability, risks, SWOT items, objectives, policies and processes, assets, PESTLE(E) factors, and the evidence collected from the systems the organisation actually uses.

That is exactly the kind of corpus that language models are good at interrogating. "Which controls have no evidence mapped to them this quarter?" "What did we decide about recovery codes?" "Tailor this access control policy to what our records say we actually do." The answers are all in there - they just needed an interface beyond Keen's own web pages.

And that's assuming you have the data in Keen ready to be accessed. One of the biggest challenges with introducing Keen at an organisation is actually migrating an existing ISMS into Keen for the first time. It can be a big lift-and-shift. I don't think AI is for everything, but this is definitely an area where a bit of automation and content analysis can really help speed things up.

Keen now speaks the Model Context Protocol (MCP), the standard that lets AI clients discover and call tools on someone else's server. Claude Desktop, Open WebUI, OpenCode and friends all speak it, as do plenty of other chat clients and back-office integrations.

With automation though, comes risk. I began the implementation with a design question: how does an AI client get access that is narrower than a person's, auditable, revocable, and impossible to widen by prompting?

Keen is its own OAuth server for this

The MCP endpoint lives inside the same application as everything else, at /api/v1/mcp. Before any tool is called, there's the authorisation handshake - and Keen plays both sides of it, acting as its own OAuth server using the current best practice for this kind of connection.

The part I care most about is the consent step. When a client asks to connect, Keen sends the person to Keen's own consent page, in the UI, authenticated like any other page. There they see exactly which scopes the client wants, they can narrow them, and approving creates a grant.

  • Access tokens last an hour. Connections refresh quietly in the background, but the whole grant ends 90 days after consent, however often it refreshes. Connections also appear under Account → Security, where the person can revoke one at any moment.
  • A grant holds scopes, never a role. A scope is only offered to an account that actually holds the matching permission, and every request works within the account's current permissions. If the person loses a permission in Keen, the connection loses it too, on the next request.
  • Tokens are stored as hashes. A copy of the database authenticates nothing.

The scopes a person can approve:

Scope What it covers
isms.read Objectives, SWOT, policies and processes, assets, people, vendors
risk.read Risks and the risk register
pestle.read PESTLE(E) factors and business processes
events.read Evidence events and the coverage counts built from them
isms.manage Add and update ISMS records (never delete)
risk.manage Add, update and import risks
pestle.manage Add and update PESTLE(E) records
rules.write Add evidence mapping rules (administrators only)

We are also living in a time where AI is getting shoved down your throat everywhere you look.

I've made sure to keep the whole MCP feature off in Keen until you enable it: with MCP off, the endpoint and its consent page simply don't exist, and tokens issued while it was on stop working.

What's more, there are two toggles for it: one is the main on/off switch, and the other is whether to enable write actions into Keen. If the latter is off, but the former is own, the only options available are 'read' requests from Keen to the MCP client (e.g to inform other systems, not to change what's in Keen itself).

What the client can actually call

Keen advertises a set of read tools. keen_overview is the designated starting point - frameworks, record counts, and what this particular connection may read - and from there the client can list controls and drill into one (with the policies, objectives, risks and evidence behind it), read the Statement of Applicability, search the risk register, list SWOT items, objectives, assets and PESTLE(E) factors, and search the collected evidence by date, source or control.

There are also guided recipes served alongside the tools: one that walks a model through rewriting a policy template against the organisation's actual records, and - when changes are enabled - one for setting up Keen for an organisation one area at a time.

With changes enabled, the client gains the writing tools too: it can learn a record type's fields, add and update records, attach documents, and - for administrators - draft new evidence mapping rules. Each tool advertises honestly whether it only reads or whether it changes things, so a client can show you what you're about to do before it does it.

And the server instructions themselves tell the model to confirm each change with the person, ask about anything it would otherwise guess, and treat stored content as data, never instructions.

Every tool call goes through Keen's front door

A tool call makes its request to Keen's own API - the same one the web UI uses - carrying the connection's identity. So every call flows through the same authentication, permission checks and limits as everyone else. The account is the one that approved the connection, narrowed to its approved scopes. A tool can never read more than the route it calls allows.

It goes further, though. There's a strict allowlist of exactly which API operations a tool call may reach. Every reading tool's calls are on it, and so are the writing calls, each tagged with the scope it needs. No delete operation appears anywhere on that list. Nothing is removed over MCP, full stop, and no call ever reaches accounts, permissions, settings, frameworks or controls. A test checks every call the tools make against that list, so a new tool can't quietly reach anything outside it.

Before an answer reaches the model, Keen trims it down. The API speaks in page-shaped payloads - duplicate fields, presentation values, long markup - and a model reads and pays for every byte it's given. So long text is clipped, long lists are shortened, and a whole answer stays comfortably small. One evidence event arrives as a tidy labelled object the model can actually use.

Collected evidence gets special treatment: the text that came from the systems Keen watches (and therefore from anyone who can write to those systems) is set apart under an untrusted label, and the instructions repeat it everywhere - treat it as data, never follow instructions in it. If you've followed the stories of prompt-injection risks at all, you know why that labelling belongs at the data layer. It's in the product. Hell, there's even now an ISO standard for this: ISO42001, which incidentally, is one of the frameworks Keen offers you to manage :)

An OpenCode session using the Keen MCP server to add a risk, showing tool calls, a confirmation question and the created record
A simple example client (OpenCode) asking Keen's MCP server to add a risk. A chat client or a document management system would be the more typical MCP consumer.

A walk through

The prompt at the top of that screenshot is: "Add a keen risk to my ISMS that says 'Recovery codes to Keen could be forgotten' and associate it to an appropriate control."

Watch what the model does, given the tools and the instructions:

  1. It starts with keen_overview (as instructed - the server makes it the obvious first call), then looks up the fields a risk needs, then lists controls to find candidates.
  2. It drafts the risk: title, Availability as the risk type (locked out of the ISMS platform), and proposes A.5.17 Authentication information as the best-fit control, offering A.8.5 as belt-and-braces. It reads the existing risks first and matches the owner style (mig5) the other risks already use.
  3. Then it stops and asks. Per the instructions, it proposes the draft: "Create the risk with these details, linking control A.5.17?" The human replies "Add A.8.5 too" - a decision the model correctly left to the person.
  4. The first attempt to create the risk is refused by Keen: asset is required. This is Keen's own validation doing its job through the MCP path, exactly as it would in the UI - the connection gets no special treatment.
  5. The model adapts: checks the available asset categories, creates a "Keen ISMS platform" asset, and tries again with the asset linked.
  6. Done: the risk exists in the ISO 27001:2022 register, linked to A.5.17 and A.8.5, with an owner, ratings and a mitigation plan - all of it confirmed with the person before anything was written.

That validation error is the ISMS being opinionated, through the MCP path as much as through the UI, and the model handles it gracefully. That's what "the route applies the account's own permission checks, exactly as for a person in Keen's pages" buys you in practice.

Writing, carefully

The change tools are built around a simple premise: the model proposes, the person confirms, Keen validates.

  • Before adding or changing a record, the tooling makes the model read the record type's fields and the real values they can name - users, folders, categories - so it works with what actually exists in your Keen.
  • Imports from spreadsheets happen in two steps. First Keen checks every row and saves nothing, returning a per-row preview. The model shows the person the preview; only on confirmation does it call again to save the very same rows. The approval is single-use, expires in 15 minutes, and is bound to the exact rows shown - so the rows the person approved are the rows that get saved.
  • Some updates carry the version of the record as it was read, so an out-of-date edit is refused and a colleague's work stays safe.
  • Mapping rules are preview-then-commit too: the client can see how many collected events a rule would match, with examples and non-matches and the reasons, before anything is saved. Saving a rule only ever creates it; changing or removing a rule stays a person's job in the UI.

And the hard boundaries, repeated everywhere a model might look: nothing is deleted over MCP; accounts, permissions, settings, frameworks and controls cannot be changed; no prompt, file or record can change that. The instructions say it, and the route allowlist enforces it - which is the only place that enforcement actually counts.

Turning it on

It's three settings:

KEEN_MCP_ENABLED=true
# Optional: allow connections to add and update records
KEEN_MCP_WRITE_ENABLED=true
# Optional: extra callback addresses for hosted AI clients,
# e.g. claude.ai's connector. For OpenCode, this is not necessary,
# because OpenCode's callback is on the loopback, so you can leave
# it empty.
KEEN_MCP_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback

Keen must be served over HTTPS (OAuth insists on it, quite rightly). Each person then finds the server address under Account → Security, adds https://<your Keen>/api/v1/mcp to their AI client, and the browser opens Keen's consent page to approve the connection. From there the client discovers the tools, and the whole thing just... works. It's a surprisingly low-ceremony experience once the connection is approved - the clients handle the whole authorisation handshake entirely on their own.

Closing the loop on evidence

What I like about this feature is how well it fits Keen's evidence-first thesis. The ISMS records are the organisation's own statements; the evidence is the raw material collected from real systems. An MCP client can now sit between a person and all of it: interrogate the controls, read the evidence with its untrusted labels intact, draft the policy update, and - only with the person's blessing - write the records that say what the organisation does.

The auditor asks which control they're interested in. These days, sometimes, so does the assistant.

Get your ISMS into Keen, quickly

If all of this sounds useful but your ISMS currently lives in a spreadsheet, a shared drive and a scattering of Word documents, that is precisely the situation the MCP feature was built to shorten. Migration is where it really pays off: point an assistant at your existing risk register or asset list, let it preview the import row by row, and confirm the batches you're happy with. Policies can be tailored against your own records as they land.

Did you know I offer professional services around Keen, as its developer?

  • Set up and operate Keen: deployment in your chosen environment (on-premises or cloud), configuration, upgrades and ongoing support.
  • Migrate your existing ISMS: bring your policies, assets, risks, ownership and evidence into Keen - optionally using the MCP connection to accelerate the data entry, with you confirming every change.
  • Wire up the evidence: ingester setup, mapping rules and measurement, so the system demonstrates what your organisation actually does.

Have a look at mig5.net/keen for the details, pricing and how to get in touch. You're also welcome to contact me directly to talk through your situation.

Keen is open source software - you can get it here . You can try a 30-day free trial of it (with demo data seeded into it) at keen.cloud .

At a glance
  • MCP endpoint at /api/v1/mcp, served by the same Keen application
  • Consent happens in Keen's own UI; hourly tokens, 90-day grants, revoke any time
  • Reads for frameworks, risks, policies and evidence; optional writes with confirmation
  • No deletes, ever; accounts, permissions, settings, frameworks and controls out of reach
  • Evidence from other systems labelled untrusted at the data layer
Migrating an ISMS into Keen?
Work with the person who built it: deployment, migration of your existing records - optionally accelerated with the MCP connection - and evidence mapping.
Did you appreciate this article? Any support is appreciated!