Skip to main content
Glama

turva-mcp

turva-mcp on Glama

A public, read-only Model Context Protocol server for turva.dev. It lets an AI client look up the site's published information, including contact details and dated measurement evidence.

For example, a client can use get_contact when someone asks how to reach me. The reply explains how to start. The server answers questions about turva.dev itself. It does not scan another domain, run an audit or perform transactions.

Connect

Streamable HTTP endpoint:

https://mcp.turva.dev/mcp

Connect to the hosted server directly. No npm installation, authentication or API key is required. Set the endpoint in an MCP client with Streamable HTTP support. Clients that use a URL-based mcpServers configuration commonly accept this shape:

{
  "mcpServers": {
    "turva": {
      "url": "https://mcp.turva.dev/mcp"
    }
  }
}

The endpoint expects MCP POST requests. Opening /mcp in a browser returns 405. Check reachability through the discovery document instead:

curl https://mcp.turva.dev/

In Windows PowerShell, use curl.exe if curl resolves to Invoke-WebRequest.

The server is listed in the official MCP registry as dev.turva/turva-mcp and in the Glama MCP directory.

Related MCP server: fedramp-docs-mcp

Try a tool

Once connected, call get_contact with an empty argument object. In an MCP client SDK, the call is:

const result = await client.callTool({ name: "get_contact", arguments: {} });
const contact = JSON.parse(result.content[0].text);
console.log(contact.email, contact.first_reply);

Here client is your connected MCP client. This excerpt from the decoded response shows the contact fields maintained in src/index.ts:

{
  "email": "info@turva.dev",
  "location": "Tampere, Finland",
  "engagement": "async_only",
  "first_reply": "Within one business day, in writing."
}

The full response also includes other contact channels and instructions for starting an engagement.

Tools

Five read-only tools, each idempotent and returning JSON as text content. There are no write tools or transaction tools.

Tool

Returns

get_services

The engagement model, the service catalog (Shopify agent storefront check, audit, advisory, implementation, agent operations and MCP server design) and pricing (four fixed list prices and two on request)

get_agent_readiness

turva.dev's agent-readiness score, category scores, measurement date and verification link

get_security_evidence

Public Hardenize and Internet.nl results for turva.dev, with their measurement date

get_principles

The principles covering written work, access and verification

get_contact

Contact channels, the first-reply time and what access an audit needs

Evidence

Tool responses come from static TypeScript objects bundled with the Worker. They do not depend on a live upstream request. The measurement tools include a measured_at date and public verification links, so compare the recorded values with a fresh scan when current status matters.

The bundled snapshot dated 2026-09-14 records 100/100, Level 5 Agent-Native on isitagentready.com, all 24 categories passed on Hardenize, 98/100 on the Internet.nl website test and 90/100 on its email test. These are third-party readings of turva.dev, not scores produced by this server.

Endpoints

Method and path

Behavior

POST /mcp

MCP over Streamable HTTP

GET /mcp, DELETE /mcp

405. No GET stream or session teardown

OPTIONS /mcp

200 for an accepted MCP preflight, 403 when the browser Origin is not allowed

GET /

Minimal discovery JSON with the server name, transport and endpoint

GET /.well-known/mcp

The same discovery JSON

GET /.well-known/glama.json

Glama domain-verification document

OPTIONS on any other path

204 discovery CORS preflight

POST, PUT, DELETE or PATCH on any path other than /mcp

405 with Allow: GET, HEAD, OPTIONS

GET or HEAD on any other path

404

The full signed MCP server card is published at turva.dev/.well-known/mcp/server-card.json.

Protocol and implementation

A single Cloudflare Worker built on the Cloudflare Agents SDK serves the endpoint through createMcpHandler. A fresh McpServer is created for each request. There is no Durable Object or persistent MCP session.

The current protocol lane uses revision 2026-07-28. The SDK's legacy compatibility lane remains available at the same endpoint. On the current lane the handler validates MCP-Protocol-Version and Mcp-Method, plus Mcp-Name for tools/call. Standard MCP clients handle these details. server/discover is supplied by the SDK.

The discovery documents and tool data are compiled into the Worker. This Worker is separate from the main turva.dev Worker, so changes here do not change the website.

Security and operating limits

  • Public and unauthenticated by design. Every exposed value is already public.

  • Read-only MCP annotations on every tool. No destructive or open-world operation is declared.

  • Rate limit: 100 requests per 60 seconds per client IP, with 429 and Retry-After: 60 after the limit. The endpoint fails open if the rate-limiter binding is missing or errors.

  • Browser CORS on /mcp allows only https://turva.dev as Origin. Other origins receive 403. Non-browser MCP clients normally send no Origin header and can connect directly. Discovery documents use open CORS so directories can read them.

  • The code does not store request bodies, client identities or tool inputs. Cloudflare Workers observability is disabled. A rate-limiter failure writes a diagnostic error without request data.

  • Security headers are applied to MCP and discovery responses.

For private vulnerability reports, see SECURITY.md or email info@turva.dev.

The two checks below are separate tools. They are not MCP tools, and this server does not run them. For checks against another website, use the standalone npm packages:

Both run with npx. The validator needs Node.js 18.17 or newer, and the comparison needs Node.js 22 or newer. Their validator instructions and comparison instructions explain the arguments and exit codes.

Deploy your own copy

This repository is MIT licensed and can be adapted for another site. Before deploying a fork:

  1. Replace the static service and evidence objects in src/index.ts with your own published data.

  2. Replace the hard-coded turva.dev domain, MCP endpoint, browser origin and verification links with values you control.

  3. Give the Worker a unique name and a rate-limit namespace_id that is not shared with another Worker in your Cloudflare account.

  4. Attach your own custom domain. workers_dev is disabled in wrangler.jsonc.

Use Node.js 22 or 24, matching the repository's CI. From the root of your clone, install dependencies, run the tests and check the types before deploying with your Cloudflare account:

npm ci
npm test
npm run typecheck
npm run deploy

Configure the custom domain under Workers & Pages, your Worker, Settings, Domains & Routes. Use your own hostname and update the discovery endpoint in src/index.ts to match it.

Maintainer

Built by Erik Rekola at turva.dev. Questions about the implementation can go to info@turva.dev. I work in writing.

The business registration is available in the Finnish Business Information System.

License

MIT.

Related MCP Connectors

Related MCP Servers