Commit Graph

153 Commits

Author SHA1 Message Date
Marc Nuri
209e8434d5 feat(mcp): toolset definitions completely agnostic from underlying MCP impl (#322)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-09-12 11:56:22 +02:00
Marc Nuri
2b6c886d95 refactor(mcp): toolset Tools definition is agnostic of MCP impl (#319)
Initial PR to make the toolsets agnostic of the usd MCP implementation (migration to go-sdk).
The decoupling will also be needed to move the different toolsets to separate nested packages (toolsets).

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-09-12 09:58:54 +02:00
Marc Nuri
ea641e6796 test(mcp): toolset metadata assertion (#318)
This test ensures that any tool definition refactoring
preserves the current behavior.

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-09-11 10:31:39 +02:00
Samuel Masuy
6c573f31c8 feat(kubernetes): add support for previousPod container logs (#256)
Add 'previous' parameter to pods_log tool to retrieve logs from terminated containers, equivalent to kubectl logs --previous functionality.
This enables debugging of containers that have restarted due to crashes or updates.

Signed-off-by: Samuel Masuy <samuel.masuy@goto.com>
Co-authored-by: opencode <noreply@opencode.ai>
2025-09-11 09:29:51 +02:00
Marc Nuri
10c82f7bff refactor(toolsets): renamed Profile to Toolset (#309)
As a prior step to providing support for toolsets
this change repurposes the current work in profiles
which partially aligns with the toolsets expected features

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-09-11 09:25:09 +02:00
Marc Nuri
1bd0b32976 test: misc fixes and typos (#284)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-26 15:38:05 +02:00
Marc Nuri
0ec2599bd8 fix:test: prevent usage of real cluster in tests (#282)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-26 14:52:27 +02:00
Marc Nuri
19a92418e4 feat(auth): support for VSCode auth flow (#258)
Adds DisableDynamicClientRegistration and OAuthScopes to be able to override
the values proxied from the configured authorization server.

DisableDynamicClientRegistration removes the registration_endpoint field from
the well-known authorization resource metadata.
This forces VSCode to show a for to input the Client ID and Client Secret since
these can't be discovered.

The OAuthScopes allows to override the scopes_supported field.
VSCode automatically makes an auth request for all of the
supported scopes.
In many cases, this is not supported by the auth server.
By providing this configuration, the user (MCP Server administrator)
is able to set which scopes are effectively supported and
force VSCode to only request these.

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-11 14:39:27 +03:00
Marc Nuri
90d4bb03f3 feat(auth): token exchange auth workflow (#255)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-08 15:30:33 +03:00
Marc Nuri
58c47dc95c refactor(auth): temporarily disable scope authorization (#254)
It's unclear how the scopes are going to be populated in the JWT.
Disable scope authorization for the time being.

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-08 12:46:45 +03:00
Marc Nuri
fde4b1dc0f test(auth): complete test cases for token validation (#253)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-08 10:31:50 +03:00
Marc Nuri
dfcecd5089 feat(auth): configurable Kubernetes API token validation (#252)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-08 10:23:12 +03:00
Marc Nuri
7b11c1667a feat(auth): configurable audience validation (#251)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-08 08:50:50 +03:00
Marc Nuri
b0da9fb459 feat(auth): implemented SecurityTokenService to handle token exchange (#250)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-08 06:03:23 +03:00
Marc Nuri
cfc42b3bd3 test(auth): complete test scenarios for raw token and oidc (#248)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-07 16:04:12 +03:00
Marc Nuri
43744f2978 test: extract mock-server for reutilization (#247)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-07 15:32:20 +03:00
Marc Nuri
9ec5c829db feat(auth): .well-known endpoints delegated to auth server (#246)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-07 10:49:21 +03:00
Marc Nuri
aba5f548d8 feat(auth): implement proxied /.well-known/oauth-authorization-server (#244)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-06 15:51:45 +03:00
Marc Nuri
94b85990e3 fix(npm): child process exits gracefully on SIGxxx (#243)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-06 14:31:33 +03:00
Marc Nuri
4dcede178b refactor(auth): consolidate JWT validation into single method (#238)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-06 13:17:44 +03:00
Marc Nuri
c1af9c0335 fix(npm): child process exits gracefully on SIGxxx (#241)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-05 16:39:48 +03:00
Marc Nuri
29b65fd565 fix: linting issues (#240)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-08-05 16:14:00 +03:00
Marc Nuri
9cc7192d4d feat(mcp): log tool call (hide sensitive HTTP headers) (#225)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-31 15:36:34 +02:00
Arda Güçlü
be80db1a01 feat(auth): introduce scoped based authorization
Signed-off-by: Arda Güçlü <aguclu@redhat.com>
2025-07-31 11:01:26 +02:00
Marc Nuri
49dcff3f21 feat(mcp): log tool call (HTTP headers) (#221)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-30 15:25:07 +02:00
Marc Nuri
1f670ebec6 test(auth): complete test suite for unauthorized scenarios (#220)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-29 13:32:31 +02:00
Marc Nuri
cad863ff22 fix(migration): rebranded from manusa/kubernetes-mcp-server to containers/kubernetes-mcp-server (#202)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-25 09:53:04 +02:00
Arda Güçlü
0ad8726d01 feat(auth): introduce jwks url flag to be published in oauth metadata (#197) 2025-07-23 09:48:21 +02:00
Marc Nuri
ca0aa4648d feat(mcp): log tool call (function name + arguments)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-22 14:35:19 +02:00
Marc Nuri
3fbfd8d7cb fix(lint): add golangci-lint make target + lint
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-22 14:22:19 +02:00
Marc Nuri
a3e8818ffe test(http): logging middleware verifications
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-22 14:21:39 +02:00
Marc Nuri
775fa21bd1 fix(auth): delegate JWT parsing to github.com/go-jose/go-jose (189)
fix(auth): delegate JWT parsing to github.com/golang-jwt/jwt

Signed-off-by: Marc Nuri <marc@marcnuri.com>
---
fix(auth): delegate JWT parsing to go-jose

Signed-off-by: Marc Nuri <marc@marcnuri.com>
---
fix(auth): delegate JWT parsing to go-jose - review comment

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-18 13:01:55 +02:00
Arda Güçlü
73e9e845c4 refactor(auth): carry oidc provider directly instead of mcpServer 2025-07-18 12:52:51 +02:00
Marc Nuri
cb9f296566 test(mcp): speed up tests by not setting the fake kubeconfig master to example.com
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-18 10:46:32 +02:00
Marc Nuri
f6e9702009 chore(http): use constants for endpoints
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-17 13:07:54 +02:00
Marc Nuri
e4a8f604a1 test:fix: age expectation regex for minutes-no-seconds (42m)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-17 07:27:59 +02:00
Marc Nuri
bfa699049e test(http): bootstrap tests for HTTP server (177)
test(http): bootstrap tests for HTTP server

Contains tests for the main endpoints (proxied and handled)
- /sse
- /message
- /mcp
- /healthz
- /.well-known/oauth-protected-resource

Verifies graceful shutdown works as expected

Signed-off-by: Marc Nuri <marc@marcnuri.com>
---
fix: empty config for CI

Signed-off-by: Marc Nuri <marc@marcnuri.com>
2025-07-16 14:46:11 +02:00
Arda Güçlü
77671617df feat(auth): introduce OIDC token verification if authorization-url is specified (176)
Pass correct audience
---
Validate server and authorization url via url.Parse
---
Import go-oidc/v3
---
Wire initialized oidc provider if authorization url is set
---
Wire oidc issuer validation
2025-07-16 14:45:18 +02:00
Marc Nuri
5c753275ab test(mcp): refactor tool filtering tests
- Prevent declaring tools that are both read-only and destructive
- Remove redundant tests and preserve those behavioral and semantic
2025-07-14 11:36:01 +02:00
Arda Güçlü
275b91a00d feat(auth): introduce require-oauth flag to comply with OAuth in MCP specification (170)
Introduce require-oauth flag

When this flag is enabled, authorization middleware will be turned on.
When this flag is enabled, Derived which is generated based on the client
token will not be used.
---
Wire Authorization middleware to http mux

This commit adds authorization middleware. Additionally, this commit
rejects the requests if the bearer token is absent in Authorization
header of the request.
---
Add offline token validation for expiration and audience

Per Model Context Protocol specification, MCP Servers must check the
audience field of the token to ensure that they are generated specifically
for them.

This commits parses the JWT token and asserts that audience is correct
and token is not expired.
---
Add online token verification via TokenReview request to API Server

This commit sends online token verification by sending request to
TokenReview endpoint of API Server with the token and expected audience.

If API Server returns the status as authenticated, that means this token
can be used to generate a new ad hoc token for MCP Server.

If API Server returns the status as not authenticated, that means this token
is invalid and MCP Server returns 401 to force the client to initiate OAuth flow.
---
Serve oauth protected resource metadata endpoint
---
Introduce server-url to be represented in protected resource metadata
---
Add error return type in Derived function
---
Return error if error occurs in Derived, when require-oauth
---
Add test cases for authorization-url and server-url
---
Wire server-url to audience, if it is set
---
Remove redundant ssebaseurl parameter from http
2025-07-14 06:31:17 +02:00
Arda Güçlü
114726fb7c test(config): add new test case to increase the test coverage of Derived Config (167)
Add new unit tests to check the values in Derived config
---
Rely on kubeconfig in staticConfig instead of a separate but equal one
2025-07-08 06:07:18 +02:00
Marc Nuri
c5b2223249 test(config): explicit parsing tests 2025-07-08 06:03:37 +02:00
Arda Güçlü
42e8e3496f feat(http): add graceful shutdown of http server by catching interruption signals (164)
Move http serving under its specific dir
---
Add gracefully shutdown for http server
2025-07-08 06:02:54 +02:00
Arda Güçlü
00e4f1816f fix(auth): isolate bearer token config from kubeconfig 2025-07-07 07:09:26 +02:00
Arda Güçlü
9ffb818ab2 feat(auht): accept standard oauth authorization header by keeping the current header 2025-07-03 06:57:42 +02:00
Arda Güçlü
524e4f5d2a feat(http): introduce middleware for audit logs and authentication checks (157)
Introduce wrapper middleware to intercept http requests
---
Rename middleware to http
2025-07-02 15:08:17 +02:00
Arda Güçlü
ebe0ba9816 fix(kubernetes): wire static config to Derived object 2025-07-02 14:27:31 +02:00
Arda Güçlü
e6b19034aa feat(mcp): serve sse and streamable from a single port 2025-07-02 14:04:18 +02:00
Arda Güçlü
186f445ca2 feat(config): introduce enabled/disabled tool list in configuration file (155)
Introduce allow/deny tool functionality in toml config
---
Remove duplicate fields that already defined in staticConfig
---
Add unit tests to verify tool valid check
---
Wire staticConfig to fix unit tests
---
Rename to enabled/disabled instead of allowed/denied
2025-07-01 16:02:36 +02:00
Marc Nuri
af2a8cd19d feat(config): deny resources by using RESTMapper as an interceptor (149)
feat(config): deny resources by using RESTMapper as an interceptor

This approach ensures that resources in the deny list are **always**
processed regardless of the implementation.

The RESTMapper takes care of verifying that the requested Group Version Kind
complies with the deny list while checking for the REST endpoint.
---
feat(config): provide a limited clientset which check access
---
review: addressed PR comments
---
feat(config): provide a limited metrics clientset to check access
---
review: addressed PR comments regarding pods_exec
2025-07-01 14:44:22 +02:00