Skip to main content

MCP 2.7 Release Notes

Release date: October 2026

MCP 2.7 lets your assistant build a compliance program in Continuous Control Monitoring (CCM), not only read one. Fifteen new tools cover the whole authoring flow: check whether a standard is already covered, import a prebuilt framework or create a custom one, add its requirements and controls, write and prove each control test, run the tests, promote the controls to LIVE, and exempt the assets a test should not count. Two tools from the integration and rule groups fold into their siblings, so the server goes from 39 tools to 52, 21 of them for compliance.

Everything an assistant authors lands in DRAFT. Nothing counts toward a scorecard until you, or the assistant on your instruction, promote it with transition-controls. That is the one rule the whole release is built around: the assistant can do all of the work, and you decide when it goes live.

Do I need to do anything?

Remote server users: no. The hosted server runs 2.7, so the new tools appear in your connector's tool list. A client that caches the tool list picks them up when it next refreshes it.

Local server users: nothing beyond your usual update. npx @jupiterone/jupiterone-mcp picks up 2.7 on its next run. A global install updates with npm install -g @jupiterone/jupiterone-mcp.

If something of yours calls get-integration-job or get-raw-data-download-url by name, those two names are gone. See Two tools folded into their siblings.

If you built percentage Number widgets through the MCP before 2.6.2, check the figures they show. See Percentage widgets (2.6.2).

What is new in MCP 2.7​

MCP 2.7 adds fifteen compliance tools and updates the six that came in MCP 2.5. Together they cover all of CCM that an assistant works with: reading status, recording attestations, and authoring and running a framework.

ToolsIn 2.7What it means for you
Coverage check
check-compliance-coverage
NewBefore assessing a standard by hand or creating anything, your assistant learns whether the framework is loaded, importable from JupiterOne's library, or absent, and which existing controls already address a topic
Library import
import-framework
NewA prebuilt framework (CIS benchmarks, SOC 2, ISO 27001, NIST, PCI DSS, DORA) is queued for import by its library id; the summary shows the job while it runs
Framework building
create-framework, create-requirements, create-controls, link-controls, update-control
NewA custom framework is built one reviewed layer at a time, in your own wording and identifiers, reusing the controls you already have instead of duplicating them
Control tests
create-control-test, update-control-test, delete-control-test
NewEach test's J1QL is parsed and run before it is saved, so you see what it matches today before it counts; a query the engine rejects is refused
Evaluate and promote
evaluate-controls, transition-controls
NewDrafts prove their tests on demand, and a batch of controls, or a whole framework, moves between DRAFT, REVIEW, LIVE and RETIRED with every hop explained
Scoped delete
delete-control
NewA control created by mistake while authoring is removed; one that has been scored or attested keeps its history, and the refusal says what to do instead
Exemptions
create-exemptions, revoke-exemptions
NewSpecific assets are exempted from a control test with a reason, a justification and an optional expiry, and a filing reports any earlier exemption it replaced
Compliance status
get-compliance-summary, list-controls, get-control
UpdatedThe summary scores a chosen set of frameworks, lists a framework's requirements and shows imports in flight; list-controls says why each failing control fails and finds controls by test name; get-control lists each test's exemptions and flags tests whose last run failed
Attestations
create-attestation, update-attestation, revoke-attestation
UpdatedA control that is not LIVE is refused with the way to promote it (transition-controls), and a failed call names the step that failed

Across the whole release:

ChangeWhat it means for you
Two guided promptsAuthor a compliance framework and Promote a compliance framework walk the assistant through the flow; clients that support Skills over MCP get the same text as skills
Safe to repeatEvery write checks what already exists first, so repeating a call reports already_exists or already_linked instead of making a second copy. A call cut off by a time limit says whether anything was written; see Retries, time limits and partial runs
Errors that name the phaseA compliance call that fails mid-read says which read failed and how long each phase took, so the next call can be narrowed
Two tools foldedget-integration-job becomes a parameter of get-integration-jobs; get-raw-data-download-url becomes format: "downloadUrl" on get-rule-evaluation-query-results

Check coverage before you build​

check-compliance-coverage is the first call for any question that names a standard, benchmark or control topic. Given a framework name or fragment ("CIS AWS", "SOC 2", "PCI DSS 4") it reports a verdict:

  • covered: LIVE controls with tests exist for it.
  • partial: controls exist but are DRAFT, REVIEW or without tests. draftCount says how many are drafts, which is why a framework can read "0 passing, 0 failing" on the scorecard.
  • importable: not loaded, but JupiterOne's library has it. importable[] carries the source and sourceId that import-framework takes.
  • not_covered: nothing matched.

Given a topic ("MFA for console users", "S3 encryption") it lists up to 25 existing controls that address it, with their state, status, test count and frameworks. These are reuse candidates: a control can serve several requirements and frameworks, so link-controls attaches one to a new requirement instead of creating a duplicate. An empty list means nothing matched the words given, not that no related control exists, so the assistant tries another phrasing before creating.

Import a prebuilt framework​

import-framework queues one of JupiterOne's library frameworks by its source (J1 or UCF) and sourceId, as the coverage check reports them. The backend runs the import as a job. The response says the job is queued; a framework already loaded comes back as already_exists with its id and link, and one already importing as import_in_progress. Neither writes anything, so a repeat is harmless.

While the job runs, get-compliance-summary lists it in importJobs[] with its status and, if it failed, the backend's message. Imported controls arrive in DRAFT, like everything else the assistant authors, and are promoted with transition-controls.

Build a custom framework one layer at a time​

For a standard the library does not carry, or an internal program, the assistant builds the framework incrementally and shows you each layer before the next:

  1. create-framework creates the empty framework from a title and description. A framework with the same title already exists? The tool returns it as already_exists instead of a second one.
  2. create-requirements adds a batch of 1 to 50 requirements: each with the standard's own identifier and wording, grouped by section and ranked by priority. Requirements the framework already has, by identifier or title, come back as already_exists; nothing is duplicated.
  3. create-controls adds a batch of 1 to 25 controls under one requirement, in your words and identifiers. A control with the same name anywhere in the account comes back as already_exists with its state and frameworks, and the way to use it for this requirement is link-controls, which attaches up to 25 existing controls, JupiterOne-managed or your own, to a requirement.
  4. update-control changes a control's fields (name, description, identifier, catalog, owner, remediation, exception process, MITRE technique, resource group) and the requirements it serves: requirementIds with set, add or remove. set cannot be empty, since that would detach the control from every framework; detach with remove. A description or resource group can be replaced but not cleared.

link-controls and update-control check that CCM can see each requirement they add before writing. An id that does not exist is requirement_not_found. A requirement created moments ago that CCM cannot link to yet is not_ready, with nothing written; the same call works a minute later.

Each batch reports one outcome per item (created, already_exists, or refused with the backend's reason), the counts, and a nextStep. A batch the server's time limit cut short says what was left. create-requirements checks for duplicates against CCM itself, so it can be repeated as is. create-controls checks against data that trails a create by up to a minute, so it returns nextInputs holding only the items it never reached, and the assistant resends just those.

Everything lands in DRAFT and is excluded from every scorecard until it is LIVE.

Write a test and see what it matches​

A control test is one J1QL query plus whether its rows are GOOD (compliant assets; the test never fails, and zero rows is a pass on no data) or BAD (violations; any row fails the test). create-control-test adds one test to a control. Before saving it, the tool parses the query locally and, when it parses, runs it once within the call's budget. The response reports the rows it returned now, whether it saw any data, and whether the run happened (ran, skipped_deadline or error with a hint). It is there so you can judge the query on today's data before it counts: a GOOD test with zero rows proves nothing, and a BAD test with rows will fail the control once it is LIVE.

A query that cannot run is refused with invalid_input, and nothing is saved: a syntax error, a query that returns an alias from a negated (THAT !) step, or a run the query engine rejects outright. structuredContent.suggestion carries the fix, a ready-to-run query when the server knows it. A run that failed for any other reason does not block the create, but the test checks nothing until its query runs, and CCM scores the control from its other tests meanwhile, so the response's nextStep says how to find and fix the error. A query that names an entity type the account does not hold is saved, but reported as effective: false: it will pass on no data until the data exists.

update-control-test changes a test's query, verdict, name or description, with the same parse and run for a changed query. delete-control-test removes a test created by mistake or made obsolete by another.

Prove the drafts, then promote​

evaluate-controls runs the tests of 1 to 25 controls now instead of waiting for the daily run. Results take minutes and are read with get-control. On a DRAFT or REVIEW control the tests gain a status while the control itself stays unscored: get-control reports statusExplanation: "not_live" together with testsRan, testsPassing and testsFailing, the proof a draft carries before promotion. On a LIVE control the status follows the tests as before.

transition-controls moves controls between lifecycle states in a batch, by controlIds (1 to 25) or for a whole frameworkId (every control in one of fromStates, which defaults to DRAFT and REVIEW; with controlIds, fromStates is optional). CCM enforces the order DRAFT → REVIEW → LIVE, so a promotion from DRAFT to LIVE is made as two hops. RETIRED is accepted only with explicit ids, and a path that would pass through LIVE on the way to another state, such as retiring a draft, is not taken: promote to LIVE first if that is the intent. Every move is decided on the state CCM holds for the control at that moment, so a control already promoted is never sent back a step. The response lists each hop that was transitioned, what was skipped (already in the state, outside fromStates, a path through LIVE, not found, or an invalid transition) and what was refused with the backend's reason. The live-controls limit is enforced here: a refusal names the limit with its own numbers and stops the rest of the batch. A batch not finished within the call's budget reports remaining, lists the controls in remainingControlIds, and returns nextInputs, the calls that finish it: a control the call moved comes back by id with only the state it was left in, and a framework pass comes back as the framework, checked again control by control. A move the time limit cut off is listed in interrupted[]: it may still land, so wait about a minute and read those controls with get-control until their state stops changing before making their follow-up call.

Which state to go to is your decision. The description of each state is in the tool, and the Promote a compliance framework prompt walks through it.

Delete a mistake, retire the rest​

delete-control is a hard delete: the control and its tests are removed and any attestations on it are purged. It is accepted only for a DRAFT control that has never been scored and never attested, revoked attestations included. Anything else returns not_deletable with the reason (state, was_live or has_attestations) and a nextStep that fits the control's state:

  • LIVE: retire it with transition-controls to RETIRED, which keeps its history.
  • REVIEW: move it back to DRAFT with transition-controls, then delete it if it was never LIVE.
  • DRAFT with history: leave it as a DRAFT, which is never scored, or detach it from its requirements with update-control.

A control under the wrong requirement is moved with update-control, not deleted.

delete-control-test removes a test, and reports the deleted test's last result. On a LIVE control it keeps two tests: a failing one, whose removal would let the control pass on its next run, and the last one, whose removal would clear the control's status. Fix the query with update-control-test, exempt the assets with create-exemptions, or move the control to REVIEW first if the test really should go.

Exempt the assets a test should not count​

create-exemptions exempts specific assets from a control test so they stop failing it: a risk the organisation accepts, an asset the test does not apply to, a false positive, or one covered by a compensating control. One call records one decision for 1 to 50 assets, taken from the test's latest evaluation rows, with an exemptionReason, a justification an auditor can read, and an optional expiry. The assets' ids come from get-rule-evaluation-query-results on the test's latest rawDataKey, which get-control returns.

The exemption applies to evaluations of the query it was filed against, so a changed query needs a new evaluation before exemptions are eligible, and create-exemptions says so when it is too early.

An asset carries one exemption per test, so filing it again replaces the earlier one, whoever filed it. The response lists what it replaced in replaced[] (group id, reason, expiry and author), and the tool is marked as destructive so your client can ask before it runs.

revoke-exemptions withdraws exemptions on a test by decision (the groupId returned on create), by asset, or both. The assets fail the test again on its next run. A revoke is a hard delete, and by asset alone it removes whatever exemption those assets carry, so prefer the groupId. Filing the same assets again moves them to the new call's groupId, so check the test's exemptions on get-control before relying on an older group id. get-control lists each test's exemptions, with their group ids, reasons, status and expiry.

An attestation covers a whole control; an exemption covers assets within one test.

Retries, time limits and partial runs​

An assistant repeats calls, and the hosted server stops any call at 55 seconds. The authoring tools are built so neither leaves you guessing what happened:

  • Repeating a call does not duplicate. Every write first checks what already exists. A repeat reports already_exists (frameworks, requirements, controls, tests) or already_linked instead of making a second copy. CCM's search data trails a create by up to a minute, so after a batch cut short create-controls returns nextInputs holding only the items it never reached, and the assistant resends just those.
  • read_failed means nothing was written. A read the write depends on, such as the duplicate check or the control the test belongs to, did not finish within 20 seconds. The tool stops before writing; call again.
  • A cut-off read says so. If the 55-second limit lands while a tool is still reading, the error reads "while reading <phase>, before anything was written", and calling again is safe.
  • interrupted means the write may have landed. The limit cut off the write itself. Read the object back (get-control for controls, tests, exemptions and attestations, get-compliance-summary for frameworks and imports) before repeating it.
  • Batches report each item. A batch the time limit cut short lists what it did per item and what it did not reach, with remaining and the nextInputs that finish it. transition-controls lists moves that were cut off in interrupted[], and evaluate-controls marks runs that may already be queued, to read back before queueing again.

Two guided prompts​

Two prompts are registered with the server, and the same text is served as Skills over MCP to clients that support the skills extension:

  • Author a compliance framework (author-compliance-framework) takes the standard's name and, optionally, where its text comes from, and walks the assistant through coverage check, import or incremental build, test authoring with proof, and the hand-off to review. It never promotes.
  • Promote a compliance framework (promote-compliance-framework) takes a framework and walks through evaluating its drafts, reading the results, explaining each state, and transitioning the controls you choose.

The framework-authoring manual, read on demand through get-reference, carries the full reference for the flow: the lifecycle, what each outcome means, the exemption model, and the recipes.

Summary and list improvements​

  • A chosen set of frameworks. get-compliance-summary takes frameworkIds (1 to 25) and scores only those, in one counts read instead of one per framework in the account. Ids that match no framework come back in frameworkIdsNotFound with a warning.
  • A framework's requirement list. includeRequirements with a drilled framework adds requirementList[] (id, identifier, title, section, priority), critical first, then by section and identifier. It is the list create-controls and link-controls take requirement ids from. requirementListSkipped says when it could not be read.
  • Imports in flight. importJobs[] lists framework imports running or failed, with the backend's message on failure.
  • Why a control fails. Each list-controls row with status FAIL carries a failReason: failing_test, no_failing_test (a LIVE control with no failing test, which an expired attestation or a status CCM has not re-scored explains, as get-control shows), not_live, or tests_unread.
  • Search by test name. search on list-controls still reads control name, description, identifier and id; controls whose test names contain the text now come back separately in testNameMatches, failing tests first, with testNameSearch saying whether the search ran or why not.
  • Tests whose runs fail. get-control counts tests whose latest evaluation failed (failedEvaluationTests) and says why it matters: CCM leaves a test with no result out of the control's score, so the control can pass while that test checks nothing.
  • Errors that name the phase. A compliance call that fails mid-read now reads <context> (failed in <phase>): <message>, with the phases finished so far and their milliseconds at the end, so the next call can be narrowed by that phase. The attestation tools report their phases too.
  • Attesting a control that is not LIVE. create-attestation still refuses it with not_live, and now says how to fix it: promote the control with transition-controls (it then counts against the live-controls limit), then attest.

Two tools folded into their siblings​

Two tools whose whole job was a parameter of a sibling are gone, and their names are no longer in the tool list:

RemovedUse instead
get-integration-jobget-integration-jobs with integrationJobId and integrationInstanceId, which returns that run alone as a one-row list in the same row shape
get-raw-data-download-urlget-rule-evaluation-query-results with format: "downloadUrl", which returns the signed link for the whole set instead of rows

An assistant picks the new form up from the tool list. Only a script or a saved workflow that calls the old names needs changing.

Query and list fixes​

  • A negated step cannot be returned. A query that returns an alias declared on or after a negated step, such as FIND qualys_host THAT !HAS qualys_host_finding AS h RETURN h, always failed in the query engine: the negated step matches what is absent, so the alias binds to nothing. execute-j1ql-query, the widget and rule tools and the control-test tools now refuse it before it runs. When the alias can only mean the first entity, the refusal carries the query rewritten to return it, FIND qualys_host AS h THAT !HAS qualys_host_finding RETURN h. Filtering or ordering by a negated step works as before.
  • List sizes the API accepts. get-integration-jobs takes a size of up to 100 and list-rule-evaluations a limit of up to 250, the most each API returns. Larger values used to fail with a validation error after the call.

Access and permissions​

The authoring tools are available on every connection, and JupiterOne checks access on each call.

  • Every compliance tool needs the Continuous Control Monitoring entitlement on the account and control read permission.
  • Writes need edit permission on the control's resource group; creating or importing a framework needs framework create permission.
  • Exemptions need edit permission on the control the test belongs to.

An access-denied error names the missing entitlement or permission; re-authenticating will not help, and an account admin can grant it.

Getting started​

Remote server: nothing to do. Your connector already runs 2.7.

Local server: restart your AI client. npx picks up the new version automatically.

Verify the upgrade. Ask your assistant:

"Test my JupiterOne connection"

test-connection reports the package version alongside your identity and permissions. Then try:

"Do we already cover PCI DSS 4.0, or can we import it?"

More prompts are in the Compliance (CCM) tab of the prompt templates, and every tool is listed under Available Tools. For CCM itself, see Continuous Control Monitoring and the custom framework JSON upload for the UI path. For the previous compliance release, see What's new in MCP 2.5.