MCP server

Connect AI clients to Noru over MCP with OAuth or API keys, and understand which tools each scope and role unlocks.

What it is

The MCP server lets an AI client such as Cursor, Claude, or ChatGPT read your compliance program and, when you allow it, change it: list controls, link evidence, draft policies, create risks, push a data map. It runs inside the same API as the REST routes, so a tool call goes through the same permission checks and lands in the same activity log as a click in the app.

Endpoint and transport

PropertyValue
URLPOST https://api.noru.tech/v1/mcp
TransportStreamable HTTP, stateless
GET or DELETE on the endpoint405 (there is no session to resume or end)
AuthenticationAuthorization: Bearer with an OAuth access token or an API key
Protected-resource metadatahttps://api.noru.tech/.well-known/oauth-protected-resource/v1/mcp
Authorization server metadatahttps://app.noru.tech/.well-known/oauth-authorization-server
OAuth resource valuehttps://api.noru.tech/v1/mcp

Authentication

OAuth (interactive clients)

Clients that can open a browser sign in with OAuth. You never handle a secret, and the token is tied to you, your role, and one organization.

Add https://api.noru.tech/v1/mcp as a remote MCP server in the client.
The client reads the protected-resource and authorization-server metadata, then registers itself, either with Dynamic Client Registration or by presenting a Client ID Metadata Document (an HTTPS URL as client_id).
The client opens the authorization page. If you are not signed in, Noru signs you in first and returns you to the consent screen.
On the consent screen, check the client name and host, pick the organization the client should act in (your active organization is preselected), and tick the permissions it needs. Permissions above your role are disabled.
Leave Remember this approval on if you want to skip this screen next time for the same client, user, and organization. Click Authorize (or Deny).
Noru returns an authorization code that the client exchanges for a 1-hour access token and a 30-day refresh token. Refresh happens in the background; each refresh rotates the refresh token.
DetailValue
PKCERequired, S256 only
Grant typesauthorization_code, refresh_token
Client authentication at the token endpointnone, client_secret_basic, client_secret_post
Authorization code lifetime60 seconds
Pending authorization lifetime10 minutes
Access token lifetime1 hour
Refresh token lifetime30 days, rotated on every use
Endpoints on the issuer (app.noru.tech)/api/oauth/mcp/register, /api/oauth/mcp/authorize, /api/oauth/mcp/token, /api/oauth/mcp/revoke
Aliases on api.noru.tech/register, /token, /revoke, and /authorize (redirects to the app)

The consent screen refuses with "You must belong to a Noru organization to authorize MCP access." if your account has no membership yet, and it rejects an authorization that was started by a different signed-in user.

API keys (headless)

Clients that cannot open a browser, stdio bridges, CI, and scripts, send an API key in the same Authorization: Bearer header. The key carries its own scopes and acts as the admin who created it. The MCP client setup guides show a key-based config for every supported client.

Scopes and roles

A scope unlocks a group of tools. The scope list is shared with the REST API and documented on the API keys page. OAuth tokens are capped by the approving user's role:

RoleScopes an OAuth token may hold
AdminAll read and write scopes
EditorAll read and write scopes
ViewerRead scopes only

The cap applies on the consent screen, on token issue, on every token validation, and on refresh, so a user demoted to viewer loses write tools on the next request without re-authorizing. A remembered approval is re-narrowed to the current role each time it is reused. The protocol scope offline_access (refresh tokens) is not a permission and is available to every role.

If a client calls a tool outside its scopes it receives a 403 with an insufficient_scope challenge naming the missing scope, and a well-behaved client will send you back to the consent screen to add it.

What the server exposes

Tools are filtered by scope when the client lists them, so a read-only token never sees write tools. Write tools re-check the scope when they run. The server's instructions ask the model to call getMcpCapabilities first; it reports the active organization, the granted scopes, and the exact tools visible on that connection.

Organization, users, and frameworks

ScopeTools
read:organizationfindOrganization, getMcpCapabilities
read:usersgetUser
read:frameworksgetAllFrameworks, getOrganizationFrameworks
write:compliancecreateCompliancePlan, suggestComplianceTasks

Controls and evidence

ScopeTools
read:controlsgetOrganizationControls, getPendingControls, getControlStatus, getControlContext
write:controlsupdateControl, setControlStatus, setControlOwner
read:evidencegetOrganizationEvidence, getEvidenceItems, getEvidenceForControl
write:evidencecreateEvidence, updateEvidence, deleteEvidence, linkEvidenceToControl, unlinkEvidenceFromControl

getControlContext returns a control's status, owner, linked evidence, policies, risks, review logs, framework mappings, and coverage in one call; prefer it over chaining list tools. Control ids are lowercase (sm-01); the uppercase display id is accepted too.

Policies

ScopeTools
read:policiesgetOrganizationPolicies, getPolicyDetails, getPolicyLogs, getPolicyControlMappings
write:policiescreatePolicy, generatePolicies, linkPolicyToControl, setPolicyApprover, setPolicyStatus, setPolicyVersion, updatePolicy

Risks and security findings

ScopeTools
read:risksgetOrganizationRisks, getRiskDetails, getRiskTreatments, getRiskControlMappings, getRiskLogs, getHighRiskItems, getRiskStatus, getSecurityFindings
write:riskscreateRisk, updateRisk, deleteRisk, setRiskOwner, setRiskStatus, linkRiskToControl, unlinkRiskFromControl, createSecurityFinding, updateSecurityFinding, deleteSecurityFinding, linkSecurityFindingToRisk, unlinkSecurityFindingFromRisk, bulkLinkSecurityFindingsToRisk, createRiskTreatment, deleteRiskTreatment, setRiskTreatmentStatus, updateRiskTreatment

Vendors and assets

ScopeTools
read:vendorsgetOrganizationVendors, getVendorDetails, getMergedVendors, getVendorContacts, getVendorEvidence, getVendorLogs, getVendorPersonnel
write:vendorscreateVendor, updateVendor, deleteVendor, mergeVendors, unmergeVendor, addVendorContact, removeVendorContact, removeVendorEvidence, setVendorOwner, setVendorStatus, updateVendorContact
read:assetsgetOrganizationAssets
write:assetscreateAsset, updateAsset, deleteAsset

Personnel and training

ScopeTools
read:personnelgetOrganizationPersonnel, listTrainingPlans, getTrainingPlanDetails, listTrainingCampaigns, getTrainingCampaignDetails, listMissingPolicyAcknowledgements, listTrainingPolicyOptions
write:personnelcreatePersonnel, updatePersonnel, deletePersonnel, recordManualTrainingCompletion, recordManualPolicyAcknowledgement, assignTraining, requestPolicyAcknowledgement, createTrainingPlan, updateTrainingPlan, deleteTrainingPlan, activateTrainingPlan, syncTrainingCampaignAssignmentStatuses, sendTrainingCampaignReminders, archiveTrainingCampaign, bulkArchiveTrainingCampaigns, deleteTrainingCampaign

Privacy data map and AI inventory

These tools additionally require the privacy customer segment; on a compliance-only organization they are not listed even with the scope.

ScopeTools
read:datamapsgetAiRegister, getPrivacyAssessment, getPrivacyDataMap, getPrivacyDataSource, getPrivacyOverview, getPrivacyReviewItem, getPrivacySettings, getPrivacyTaxonomy, getProcessingActivity, getRegulationCoverage, getRopa, listAssessableRecords, listPrivacyAssessments, listPrivacyDataSources, listPrivacyDatasets, listPrivacyReviewItems, listPrivacySecurityMeasures, listPrivacySystems, listProcessingActivities
write:datamapsarchivePrivacySecurityMeasure, archiveProcessingActivity, createPrivacyAssessment, createPrivacySecurityMeasure, createProcessingActivity, deletePrivacyAssessment, deletePrivacyDataSource, ingestDatamap, linkPrivacyAssessmentRisk, reviewActivityAiSuggestion, setProcessingActivityMeasures, setProcessingActivityRetentionRules, setProcessingActivityTransfers, unlinkPrivacyAssessmentRisk, updateCoveredRegulations, updatePrivacyAssessment, updatePrivacyDataSource, updatePrivacySecurityMeasure, updatePrivacySettings, updatePrivacySystem, updateProcessingActivity
write:ai-inventoryingestAiInventory, reviewAiClassification, reviewAiFinding

Internal audits

ScopeTools
read:internal-auditsgetInternalAudit, getInternalAuditReport, listInternalAudits
write:internal-auditsaddInternalAuditFinding, completeInternalAudit, createInternalAudit, updateInternalAuditFindingStatus, updateInternalAuditReport

Resources and prompts

KindNameWhat it gives the model
Resourcenoru://frameworks/compliance-overviewFramework Compliance Overview: enabled frameworks and their coverage
Resourcenoru://policies/review-queuePolicies Requiring Attention: policies in draft or review
PromptassessFrameworkGaps (argument frameworkName)A structured gap assessment for one framework
PromptpolicyReviewSummary (argument policyId)A review summary for one policy

Tool lists may be cached by the client for 60 seconds, prompt and resource lists for 5 minutes, and server discovery for an hour; all caches are private to the credential.

Confirmations for destructive tools

Tools that delete, archive, merge, or remove records, plus generatePolicies and the ingest* tools, ask you to confirm before running. The first call returns a form; the client shows it, and retries with your answer. The confirmation is bound to your credential and the exact call, and expires after 10 minutes. Declining returns the error code CANCELLED. Only clients that declare the elicitation capability are asked; other clients run the tool directly. Noru does not otherwise confirm writes: updateRisk or setControlStatus apply immediately.

A write scope on an MCP token lets the model change data exactly as you could in the app. Read what the client is about to do before you approve it, and give headless keys only the write scopes their job needs.

Errors

Tool failures are returned as results with isError: true and a JSON body holding an error object with code and message; they never surface as JSON-RPC protocol errors, so the model can read them and correct course.

CodeWhen
NOT_FOUNDNo record with that id in this organization
FORBIDDENThe credential lacks the scope; the body also names the required scope
INVALID_REQUESTArguments failed validation
DUPLICATE_EXTERNAL_ID, DUPLICATE_EMAILA unique field is already taken
ASSIGNEE_MUST_BE_USERThe owner or assignee must be a user, not a personnel record
ALREADY_LINKEDThe link you asked for already exists
CREATE_FAILED, UPDATE_FAILED, DELETE_FAILED, LINK_FAILED, UNLINK_FAILED, BULK_LINK_FAILEDThe service rejected the write; the message explains why
CANCELLEDYou declined a destructive-tool confirmation
INTERNALAn exception the tool did not map

HTTP-level responses follow the REST error envelope: 401 with a WWW-Authenticate challenge that lists the scopes, 403 insufficient_scope, 429 RATE_LIMITED under the same 500 requests per 10 minutes budget, and 402 PAYMENT_REQUIRED for evidence tools when billing is not active.

Activity and revocation

Every tool call is recorded in the organization's activity log with source mcp and the calling user or key as actor, so an AI-made change is as traceable as a manual one.

To stopDo this
One client you authorized with OAuthRemove the Noru server from that client, or have the client POST its token to the revocation endpoint (https://app.noru.tech/api/oauth/mcp/revoke or https://api.noru.tech/revoke). Refresh tokens stop working immediately; an access token already issued lasts at most another hour.
A headless client using an API keyRevoke the key under SettingsDeveloper.
Future re-use of a remembered approvalRevoke as above; the next connection shows the consent screen again if the client re-registers.

There is no list of OAuth tokens in Settings today. Revoking an API key never affects OAuth tokens, and revoking an OAuth token never affects keys. If you cannot reach the client that holds a token, contact support to invalidate it.

What the MCP server does not do

  • It cannot upload files. Tool arguments are JSON; use POST /v1/evidence/upload on the REST API and then linkEvidenceToControl.
  • It cannot create or delete controls; those come from your enabled frameworks.
  • It never crosses organizations. One token, one organization; switch by re-authorizing and picking another in the consent screen.
  • It does not implement roots, sampling, server logging notifications, tasks, or the legacy HTTP+SSE transport. A client that sends GET to open an event stream gets 405.
  • A tool never bypasses your role. A viewer's token cannot write, however the client is configured.
  • It does not restrict the browser origin a client connects from; the API host holds no cookies or ambient credentials, so every call must carry its own bearer token.

Last updated on