diff --git a/docs/cspell.json b/docs/cspell.json index 9fe48caab0d..7a250f7ce28 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -782,6 +782,7 @@ "norc", "nosql", "notifempty", + "notionhq", "nowait", "ntauth", "nvme", diff --git a/docs/img/mcp-access/grafana-claude.png b/docs/img/mcp-access/grafana-claude.png new file mode 100644 index 00000000000..beb06ff39a5 Binary files /dev/null and b/docs/img/mcp-access/grafana-claude.png differ diff --git a/docs/img/mcp-access/grafana-create-sa.png b/docs/img/mcp-access/grafana-create-sa.png new file mode 100644 index 00000000000..a65b5fa2224 Binary files /dev/null and b/docs/img/mcp-access/grafana-create-sa.png differ diff --git a/docs/img/mcp-access/notion-access.png b/docs/img/mcp-access/notion-access.png new file mode 100644 index 00000000000..eed6004f013 Binary files /dev/null and b/docs/img/mcp-access/notion-access.png differ diff --git a/docs/img/mcp-access/notion-claude.png b/docs/img/mcp-access/notion-claude.png new file mode 100644 index 00000000000..c3c5ccaabd0 Binary files /dev/null and b/docs/img/mcp-access/notion-claude.png differ diff --git a/docs/img/mcp-access/notion-integration.png b/docs/img/mcp-access/notion-integration.png new file mode 100644 index 00000000000..3a4920c96cc Binary files /dev/null and b/docs/img/mcp-access/notion-integration.png differ diff --git a/docs/pages/enroll-resources/application-access/jwt/grafana.mdx b/docs/pages/enroll-resources/application-access/jwt/grafana.mdx index faf6c741d11..5621bb8b02d 100644 --- a/docs/pages/enroll-resources/application-access/jwt/grafana.mdx +++ b/docs/pages/enroll-resources/application-access/jwt/grafana.mdx @@ -28,37 +28,7 @@ Teleport-signed token. ## Step 1/3. Configure JWT authentication in Grafana -Add an `auth.jwt` section in Grafana’s main configuration file. Replace with the domain name of your Teleport cluster: -```ini -[auth.jwt] -enabled = true - -# HTTP header to look into to get a JWT token. -header_name = Authorization - -# JSON Web Key Set (JWKS) URL from your Teleport cluster. -jwk_set_url = https:///.well-known/jwks.json - -# Teleport username can be found in "sub" or "username" claims. -username_claim = sub - -# Map Teleport users to Grafana organization roles based on their Teleport -# roles. Adjust accordingly. -# -# In this example, if the user's Teleport role list (the "roles" claim) contains -# "editor", assign them the Grafana "Editor" role. All other users get the -# "Viewer" role. -# -# Teleport user traits are also available in the "traits" claim and can be -# used in expressions in the same way as roles. -role_attribute_path = contains(roles[*], 'editor') && 'Editor' || 'Viewer' - -# auto-create users if they are not already matched. -auto_sign_up = true -``` - -Restart your Grafana instance after updating the config. +(!docs/pages/includes/application-access/jwt-grafana-config.mdx!) ## Step 2/3. Register a Grafana application in Teleport diff --git a/docs/pages/enroll-resources/mcp-access/integration-guides/github.mdx b/docs/pages/enroll-resources/mcp-access/integration-guides/github.mdx index 3c16d6768a2..b57359b7b1c 100644 --- a/docs/pages/enroll-resources/mcp-access/integration-guides/github.mdx +++ b/docs/pages/enroll-resources/mcp-access/integration-guides/github.mdx @@ -8,24 +8,24 @@ tags: - zero-trust --- -This guide demonstrates how to run a GitHub MCP server and connect it via -Teleport. +(!docs/pages/includes/mcp-access/integration-intro.mdx serviceName="GitHub" !) ## How it works The [GitHub MCP server](https://github.com/github/github-mcp-server) uses a personal access token of a service account to access GitHub and -[`mcp-proxy`](https://github.com/sparfenyuk/mcp-proxy) exposes it to Teleport -over a streamable-HTTP endpoint by translating the original transport. Teleport -proxies all client requests to the server, which interacts with GitHub using the -permissions granted to the service account. +[`mcp-proxy`](https://github.com/sparfenyuk/mcp-proxy) exposes it to the +Teleport Application Service over a streamable-HTTP endpoint by translating the +original transport. Teleport proxies all client requests to the server, which +interacts with GitHub using the permissions granted to the service account. ## Prerequisites (!docs/pages/includes/edition-prereqs-tabs.mdx edition="Teleport (v18.3.0 or higher)" clients="\`tsh\` client"!) - Access to a service account to your GitHub organization. - A host to run the MCP server that is reachable by the Teleport Application Service. -- Running [Teleport Application Service](../getting-started.mdx). +- A running Teleport Application Service. If you have not yet done this, follow + the [Getting Started guide](../getting-started.mdx). - A Teleport user with sufficient permissions (e.g. role `mcp-user`) to access MCP servers. @@ -113,7 +113,7 @@ token for the `Authorization` header: $ tsh mcp config github-mcp --client-config claude --header "Authorization: Bearer " ``` -## Next Steps +## Next steps - Review [Enroll a Streamable-HTTP MCP Server](../enrolling-mcp-servers/streamable-http.mdx). - See the [dynamic registration](../dynamic-registration.mdx) guide. diff --git a/docs/pages/enroll-resources/mcp-access/integration-guides/grafana.mdx b/docs/pages/enroll-resources/mcp-access/integration-guides/grafana.mdx new file mode 100644 index 00000000000..75547c37af0 --- /dev/null +++ b/docs/pages/enroll-resources/mcp-access/integration-guides/grafana.mdx @@ -0,0 +1,137 @@ +--- +title: Connect a Grafana MCP Server to Teleport +sidebar_label: Grafana +description: Set up a Grafana MCP server for access through Teleport +tags: +- how-to +- mcp +- zero-trust +--- + +(!docs/pages/includes/mcp-access/integration-intro.mdx serviceName="Grafana" !) + +## How it works + +The [Grafana MCP server](https://github.com/grafana/mcp-grafana) +forwards JWT tokens signed by Teleport to access Grafana and runs on a local +endpoint reachable by the Teleport Application Service. Teleport proxies all +client requests to the server, which interacts with Grafana using permissions +mapped by [JWT authentication](https://grafana.com/docs/grafana/latest/setup-grafana/configure-access/configure-authentication/jwt/). + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx edition="Teleport (v18.3.0 or higher)" clients="\`tsh\` client"!) +- Ability to configure your Grafana instance. +- A host to run the MCP server that is reachable by the Teleport Application Service. +- A running Teleport Application Service. If you have not yet done this, follow + the [Getting Started guide](../getting-started.mdx). +- A Teleport user with sufficient permissions (e.g. role `mcp-user`) to access + MCP servers. + +## Step 1/3. Configure JWT authentication in Grafana + +(!docs/pages/includes/application-access/jwt-grafana-config.mdx!) + +## Step 2/3. Run the Grafana MCP server + +The Grafana MCP Server can be run either as a compiled binary or via the +official Docker image: + + + +Run the MCP server in streamable-HTTP transport. Assign to the URL of your Grafana +instance and to the hostname +of the host machine running the MCP server: +```code +$ export GRAFANA_URL= +$ ./mcp-grafana --transport streamable-http --address :8000 +``` + + + +Run the MCP server in streamable-HTTP transport. Assign to the URL of your Grafana +instance: +```code +$ docker run -d -p 8000:8000 \ + -e GRAFANA_URL= \ + mcp/grafana --transport streamable-http +``` + + + +The Grafana MCP Server now exposes a streamable-HTTP endpoint at `http://:8000/mcp`. + +## Step 3/3. Connect via Teleport + +(!docs/pages/includes/mcp-access/integration-teleport-app-rewrite.mdx service="grafana" serviceName="Grafana" port="8000" headerName="X-Grafana-API-Key" headerValue="{{internal.jwt}}" !) + +The header rewrite configuration above will replace the `{{internal.jwt}}` +template variable with a Teleport-signed JWT token in each request. The Grafana +MCP server will use this token as a bearer token in "Authorization" header when +connecting to Grafana. + +(!docs/pages/includes/mcp-access/integration-limit-tools.mdx!) +```yaml +kind: role +version: v8 +metadata: + name: grafana-mcp-readonly +spec: + allow: + app_labels: + 'service': 'grafana' + mcp: + tools: + - ^(get|query|list|search|find)_.*$ +``` + +(!docs/pages/includes/mcp-access/integration-tsh.mdx service="grafana" serviceName="Grafana" !) + +![Grafana Claude](../../../../img/mcp-access/grafana-claude.png) + +## Connect to Grafana using a service account + +Instead of accessing Grafana with JWT authentication, you can also use a service +account. + +Navigate to Administrators > Users and Accounts > Service Accounts, and then +click **Create Service Account**: + +![Grafana Service Account](../../../../img/mcp-access/grafana-create-sa.png) + +Assign the **Viewer** role to keep the service account limited to read-only +access. + +After the service account is created, click **Add service account +token** to generate a new token. Use this token when +starting the Grafana MCP server: +```code +$ docker run -d -p 8000:8000 \ + -e GRAFANA_URL= \ + -e GRAFANA_SERVICE_ACCOUNT_TOKEN= \ + mcp/grafana --transport streamable-http +``` + +Lastly, you don’t need to configure any header rewrites in the Teleport +application: +```yaml +app_service: + enabled: "yes" + apps: + - name: "grafana-mcp" + uri: "mcp+http://:8000/mcp" + labels: + env: dev + service: grafana +``` + +## Next steps + +- Read more on accessing Grafana through Teleport with [JWT authentication](../../application-access/jwt/grafana.mdx). +- Review [Enroll a Streamable-HTTP MCP Server](../enrolling-mcp-servers/streamable-http.mdx). +- See the [dynamic registration](../dynamic-registration.mdx) guide. +- Learn more about [mcp-grafana](https://github.com/grafana/mcp-grafana). +- Connect your [MCP clients](../../../connect-your-client/model-context-protocol/mcp-access.mdx). diff --git a/docs/pages/enroll-resources/mcp-access/integration-guides/notion.mdx b/docs/pages/enroll-resources/mcp-access/integration-guides/notion.mdx new file mode 100644 index 00000000000..10323869773 --- /dev/null +++ b/docs/pages/enroll-resources/mcp-access/integration-guides/notion.mdx @@ -0,0 +1,97 @@ +--- +title: Connect a Notion MCP Server to Teleport +sidebar_label: Notion +description: Set up a Notion MCP server for access through Teleport +tags: +- how-to +- mcp +- zero-trust +--- + +(!docs/pages/includes/mcp-access/integration-intro.mdx serviceName="Notion" !) + +## How it works + +The [Notion MCP server](https://github.com/makenotion/notion-mcp-server) +uses an integration token to access Notion and runs on a local endpoint +reachable by the Teleport Application Service. Teleport proxies all client +requests to the server, which interacts with Notion using the permissions +granted to the integration. + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx edition="Teleport (v18.3.0 or higher)" clients="\`tsh\` client"!) +- Access to your Notion workspace and sufficient privileges to manage integrations. +- A host to run the MCP server that is reachable by the Teleport Application Service. +- A running Teleport Application Service. If you have not yet done this, follow + the [Getting Started guide](../getting-started.mdx). +- A Teleport user with sufficient permissions (e.g. role `mcp-user`) to access + MCP servers. + +## Step 1/3. Create an integration in Notion + +Go to https://www.notion.so/profile/integrations and create a new **internal +integration**. + +![Notion integration](../../../../img/mcp-access/notion-integration.png) + +To limit the scope available to LLMs, disable all permissions except "Read +Content" in the "Capabilities" section. + +Next, open "Access" tab and select the pages you want the integration to be able +to access. + +![Notion access](../../../../img/mcp-access/notion-access.png) + +Finally, return to the "Configuration" tab, copy the "Internal Integration +Secret" for use in the next step. + +## Step 2/3. Run the Notion MCP server + +Start the Notion MCP server using your Notion integration token : +```code +$ export NOTION_TOKEN= +$ npx @notionhq/notion-mcp-server --transport http --port 8000 --auth-token teleport-local-connection +``` + +The MCP server listens on all network interfaces by default. Run it on a private +network and ensure the hostname is +reachable by the Teleport Application Service. + +The `--auth-token` value is the shared secret Teleport uses to authenticate to +the MCP server. Since the MCP server is not publicly accessible, using a fixed +value is acceptable. + +## Step 3/3. Connect via Teleport + +(!docs/pages/includes/mcp-access/integration-teleport-app.mdx service="notion" serviceName="Notion" port="8000" !) + +(!docs/pages/includes/mcp-access/integration-limit-tools.mdx!) +```yaml +kind: role +version: v8 +metadata: + name: notion-mcp-readonly +spec: + allow: + app_labels: + 'service': 'notion' + mcp: + tools: + - API-get-* + - API-retrieve-* + - API-post-database-query + - API-post-search +``` + +(!docs/pages/includes/mcp-access/integration-tsh.mdx service="notion" serviceName="Notion" !) + +![Notion Claude](../../../../img/mcp-access/notion-claude.png) + +## Next steps + +- Review [Enroll a Streamable-HTTP MCP Server](../enrolling-mcp-servers/streamable-http.mdx). +- See the [dynamic registration](../dynamic-registration.mdx) guide. +- Learn more about [notion-mcp-server](https://github.com/makenotion/notion-mcp-server). +- Connect your [MCP clients](../../../connect-your-client/model-context-protocol/mcp-access.mdx). diff --git a/docs/pages/enroll-resources/mcp-access/integration-guides/vault.mdx b/docs/pages/enroll-resources/mcp-access/integration-guides/vault.mdx index 3fd64b1454b..8771ad82898 100644 --- a/docs/pages/enroll-resources/mcp-access/integration-guides/vault.mdx +++ b/docs/pages/enroll-resources/mcp-access/integration-guides/vault.mdx @@ -1,5 +1,5 @@ --- -title: Connect a HashiCorp Vault MCP server to Teleport +title: Connect a HashiCorp Vault MCP Server to Teleport sidebar_label: HashiCorp Vault description: Set up a HashiCorp Vault MCP server for access through Teleport tags: @@ -8,23 +8,23 @@ tags: - zero-trust --- -This guide demonstrates how to run a HashiCorp MCP server and connect it via -Teleport. +(!docs/pages/includes/mcp-access/integration-intro.mdx serviceName="HashiCorp Vault" !) ## How it works The [HashiCorp Vault MCP server](https://github.com/hashicorp/vault-mcp-server) uses a service token to access HashiCorp Vault and runs on a local endpoint -reachable by Teleport. Teleport proxies all client requests to the server, which -interacts with HashiCorp Vault using the permissions granted by the policy bound -to the token. +reachable by the Teleport Application Service. Teleport proxies all client +requests to the server, which interacts with HashiCorp Vault using the +permissions granted by the policy bound to the token. ## Prerequisites (!docs/pages/includes/edition-prereqs-tabs.mdx edition="Teleport (v18.3.0 or higher)" clients="\`tsh\` client"!) - Access to your Vault instance and sufficient privileges to manage policies. - A host to run the MCP server that is reachable by the Teleport Application Service. -- Running [Teleport Application Service](../getting-started.mdx). +- A running Teleport Application Service. If you have not yet done this, follow + the [Getting Started guide](../getting-started.mdx). - A Teleport user with sufficient permissions (e.g. role `mcp-user`) to access MCP servers. @@ -117,7 +117,7 @@ spec: ![Vault Claude](../../../../img/mcp-access/vault-claude.png) -## Next Steps +## Next steps - Review [Enroll a Streamable-HTTP MCP Server](../enrolling-mcp-servers/streamable-http.mdx). - See the [dynamic registration](../dynamic-registration.mdx) guide. diff --git a/docs/pages/enroll-resources/mcp-access/mcp-access.mdx b/docs/pages/enroll-resources/mcp-access/mcp-access.mdx index 709e90b3754..c00566d9683 100644 --- a/docs/pages/enroll-resources/mcp-access/mcp-access.mdx +++ b/docs/pages/enroll-resources/mcp-access/mcp-access.mdx @@ -17,6 +17,8 @@ import databaseSvg from "@site/src/components/Icon/teleport-svg/database.svg"; import kubernetesSvg from "@site/src/components/Icon/svg/kubernetes2.svg"; import githubSvg from "@site/src/components/Icon/svg/github.svg"; import vaultSvg from "@site/src/components/Icon/svg/hashicorp-vault.svg"; +import notionSvg from "@site/src/components/Icon/svg/notion.svg"; +import grafanaSvg from "@site/src/components/Icon/svg/grafana.svg"; \ No newline at end of file diff --git a/docs/pages/includes/application-access/jwt-grafana-config.mdx b/docs/pages/includes/application-access/jwt-grafana-config.mdx new file mode 100644 index 00000000000..546f44fbc61 --- /dev/null +++ b/docs/pages/includes/application-access/jwt-grafana-config.mdx @@ -0,0 +1,31 @@ +Add an `auth.jwt` section in Grafana’s main configuration file. Replace with the domain name of your Teleport cluster: +```ini +[auth.jwt] +enabled = true + +# HTTP header to look into to get a JWT token. +header_name = Authorization + +# JSON Web Key Set (JWKS) URL from your Teleport cluster. +jwk_set_url = https:///.well-known/jwks.json + +# Teleport username can be found in "sub" or "username" claims. +username_claim = sub + +# Map Teleport users to Grafana organization roles based on their Teleport +# roles. Adjust accordingly. +# +# In this example, if the user's Teleport role list (the "roles" claim) contains +# "editor", assign them the Grafana "Editor" role. All other users get the +# "Viewer" role. +# +# Teleport user traits are also available in the "traits" claim and can be +# used in expressions in the same way as roles. +role_attribute_path = contains(roles[*], 'editor') && 'Editor' || 'Viewer' + +# auto-create users if they are not already matched. +auto_sign_up = true +``` + +Restart your Grafana instance after updating the config. diff --git a/docs/pages/includes/mcp-access/integration-intro.mdx b/docs/pages/includes/mcp-access/integration-intro.mdx new file mode 100644 index 00000000000..29b94752baa --- /dev/null +++ b/docs/pages/includes/mcp-access/integration-intro.mdx @@ -0,0 +1,7 @@ +Teleport can provide secure access to MCP servers via Teleport Application +Service. + +In this guide, you will: +1. Configure your {{ serviceName }} service for access by the MCP server. +1. Run the {{ serviceName }} MCP Server. +1. Enroll the MCP server into your Teleport cluster and connect to it. diff --git a/docs/pages/includes/mcp-access/integration-teleport-app-rewrite.mdx b/docs/pages/includes/mcp-access/integration-teleport-app-rewrite.mdx new file mode 100644 index 00000000000..1ca5a65e82a --- /dev/null +++ b/docs/pages/includes/mcp-access/integration-teleport-app-rewrite.mdx @@ -0,0 +1,83 @@ +You can register an MCP application in Teleport by defining it in your Teleport +Application Service configuration, or by using dynamic registration with `tctl` +or Terraform: + + + +Replace with the host running the {{serviceName}} MCP server: +```yaml +app_service: + enabled: "yes" + apps: + - name: "{{service}}-mcp" + uri: "mcp+http://:{{port}}/mcp" + labels: + env: dev + service: {{service}} + rewrite: + headers: + - "{{headerName}}: {{headerValue}}" +``` + +Restart the Application Service. + + + +Create an `app` resource definition file named `app-{{service}}-mcp.yaml`. Replace + with the host running the {{serviceName}} MCP server: +```yaml +# app-{{service}}-mcp.yaml +kind: app +version: v3 +metadata: + name: {{service}}-mcp + labels: + env: dev + service: {{service}} + rewrite: + headers: + - name: "{{headerName}}" + value: "{{headerValue}}" +spec: + uri: "mcp+http://:{{port}}/mcp" +``` + +Create the `app` resource with: +```code +$ tctl create -f app-{{service}}-app.yaml +``` + + + +Create a `teleport_app` resource in terraform. Replace +with the host running the {{serviceName}} MCP server: +```hcl +resource "teleport_app" "grafana" { + version = "v3" + metadata = { + name = "grafana" + labels = { + "teleport.dev/origin" = "dynamic" + "env" = "dev" + "service" = "{{service}}" + } + } + + spec = { + uri = "mcp+http://:{{port}}/mcp" + rewrite = { + headers = [{ + name = "{{headerName}}" + value = "{{headerValue}}" + }] + } + } +} +``` +Apply the configuration: +```code +$ terraform apply +``` + + + \ No newline at end of file diff --git a/docs/pages/includes/mcp-access/integration-teleport-app.mdx b/docs/pages/includes/mcp-access/integration-teleport-app.mdx index 3b94f6c1a59..25fcd4000cf 100644 --- a/docs/pages/includes/mcp-access/integration-teleport-app.mdx +++ b/docs/pages/includes/mcp-access/integration-teleport-app.mdx @@ -52,7 +52,7 @@ resource "teleport_app" "grafana" { labels = { "teleport.dev/origin" = "dynamic" "env" = "dev" - "service" = ""{{service}}"" + "service" = "{{service}}" } }