Skip to content

Implement tsh mcp db config#55781

Merged
gabrielcorado merged 7 commits intomasterfrom
gabrielcorado/mcp-db-config
Jun 25, 2025
Merged

Implement tsh mcp db config#55781
gabrielcorado merged 7 commits intomasterfrom
gabrielcorado/mcp-db-config

Conversation

@gabrielcorado
Copy link
Copy Markdown
Contributor

@gabrielcorado gabrielcorado commented Jun 16, 2025

This command generates the MCP client configuration for MCP database access. For now, only Claude Desktop is supported.

This command follows the same flags and usage flow as tsh mcp config command with some differences:

  • Running the command multiple times updates the config. So if you executed tsh mcp db config db1 and then tsh mcp db config db2, the second database will be added to the configuration file.
  • Running the command for a database already on the config will cause its configuration to be updated.
Usage examples

Print JSON format with hint:

❯ tsh mcp db config --db-user=postgres --db-name=postgres pg-dev
Here is a sample JSON configuration for launching Teleport MCP servers:
{
  "mcpServers": {
    "teleport-databases": {
      "command": "/path/to/tsh",
      "args": [
        "mcp",
        "db",
        "start",
        "teleport://clusters/root.teleport.dev/databases/pg-dev?dbName=postgres&dbUser=postgres"
      ]
    }
  }
}

Tip: use --client-config=claude to update your Claude Desktop configuration.
You can also specify a custom config path with --client-config=<path> to update
a config file compatible with the "mcpServer" mapping.

Update Claude Desktop config:

❯ tsh mcp db config --db-user=postgres --db-name=postgres pg-dev --client-config=claude
Updated database "pg-dev" on the client configuration at:
/Users/gabrielcorado/Library/Application Support/Claude/claude_desktop_config.json

Teleport database access MCP server is named "teleport-databases" in this configuration.

You may need to restart your client to reload these new configurations.

Update Claude Desktop config with environment variables "conflict":

❯ tsh mcp db config --db-user=postgres --db-name=postgres pg-dev --client-config=claude
Updated database "pg-dev" on the client configuration at:
/Users/gabrielcorado/Library/Application Support/Claude/claude_desktop_config.json

Teleport database access MCP server is named "teleport-databases" in this configuration.

You may need to restart your client to reload these new configurations.

Environment variables have changed, but existing values will be preserved.
To overwrite them, rerun this command with the --overwrite flag.

@gabrielcorado gabrielcorado added the no-changelog Indicates that a PR does not require a changelog entry label Jun 16, 2025
@github-actions github-actions Bot added size/md tsh tsh - Teleport's command line tool for logging into nodes running Teleport. labels Jun 16, 2025
@github-actions github-actions Bot requested review from juliaogris and nklaassen June 16, 2025 19:33
Comment thread lib/client/mcp/claude/config_test.go Outdated
Comment thread lib/client/mcp/uri.go Outdated
Comment on lines +148 to +155
// StringWithParams returns the string representation of the resource URI
// including the query params.
func (u ResourceURI) StringWithParams() string {
return u.url.String()
}

// Equal returns true if both resources represent the same Teleport resource.
func (u ResourceURI) Equal(b ResourceURI) bool {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: instead of implementing the function twice (like with query and without query), maybe we could implement a function that returns a new ResourceURI without the query params like fullURI.WithoutQuery().String() == wantedURI. That way we can keep String simple, and no need to implement Equal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the ResourceURI following your suggestion.

Comment thread tool/tsh/common/mcp_db.go Outdated
Comment thread tool/tsh/common/mcp_db.go Outdated
Comment on lines +366 to +367
server.Command = existentServer.Command
server.Envs = existentServer.Envs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should just overwrite these with new values instead of using old values. if we want to be on the safe side, lets check if they have changed and prompt user for overwrite.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this command is just making the smallest change possible to avoid disrupting any manual modifications the users might have made.

We could introduce another command to validate those entries or have a --fix argument so we don't set the expectation that this command will automatically fix any problem the config might have. What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new flag is also fine. Instead of --fix, how about --overwrite?

If not specified, but the content is different, print something like:

Environment variables have changed, but existing values will be preserved.
To overwrite them, rerun this command with the --overwrite flag.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I've added the flag and the message.

Comment thread tool/tsh/common/help.go
Copy link
Copy Markdown
Contributor

@Tener Tener left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with @greedy52 comments. Also, could you add more usage examples in the issue description? It would be worth to see all the different modes in action.

@gabrielcorado
Copy link
Copy Markdown
Contributor Author

@Tener I've added more usage examples on the issue description. Let me know if you want me to show something else.

Comment thread tool/tsh/common/mcp_db.go Outdated
Comment thread tool/tsh/common/mcp_db.go Outdated
Comment thread tool/tsh/common/mcp_db.go Outdated
Comment thread lib/client/mcp/uri.go Outdated
// characters like `&` causing the final URI to be harder to read.
var b bytes.Buffer
enc := json.NewEncoder(&b)
enc.SetEscapeHTML(false)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, I didn't know that. Seems surprising that this is the default.

Comment thread lib/client/mcp/claude/config.go
Comment thread lib/client/mcp/uri.go Outdated

// NewDatabaseResourceURI creates a new database resource URI with connect
// params.
func NewDatabaseResourceURIWithConnectParams(cluster, databaseName, dbUser, dbName string) ResourceURI {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:
Is it possible that there will be other parameters in the future, then maybe functional options is a better choice (and would only require one function name).

if it is unlikely that there will be other connect parameters, maybe it should be WithUser or so?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can have at least one other parameter (database roles). Thanks for the suggestion. I've updated it to use a single function and provide the parameters as options.

Comment thread tool/tsh/common/mcp_db.go Outdated
@juliaogris
Copy link
Copy Markdown
Contributor

sorry, I had this review pending from the very beginning - never clicked the button apparently, feel free to ignore.

@gabrielcorado gabrielcorado requested review from Tener and greedy52 June 25, 2025 12:59
@gabrielcorado gabrielcorado added this pull request to the merge queue Jun 25, 2025
Merged via the queue into master with commit 95f596e Jun 25, 2025
40 checks passed
@gabrielcorado gabrielcorado deleted the gabrielcorado/mcp-db-config branch June 25, 2025 20:37
greedy52 pushed a commit that referenced this pull request Jun 26, 2025
* feat(tsh): add `tsh mcp db config` subcommand

* chore(claude): fix lint

* refactor: code review suggestions

* refactor: code review suggestions

* test(tsh): add missing option on test case

* chore(tsh): add message on manually adding database URI
@greedy52 greedy52 mentioned this pull request Jun 26, 2025
github-merge-queue Bot pushed a commit that referenced this pull request Jul 21, 2025
* Initial PostgreSQL MCP support (#54431)

* feat(mcp): initial postgres mcp

* test(postgres): fix missing mock function

* fix(gomod): go mod tidy all

* refactor: code review suggestions

* fix(tsh): mcp init missing logger

* chore(tsh): missing other route to database field

* refactor: use in-memory net listener

* test(tsh): add mcp db command test

* chore: fix license

* refactor(tsh): move logger init

* test(mcp): sort slices to avoid flakiness

* chore: fix lint

* test(mcp): sort the resources before assertion

* fix(mcp): update error handler for better message

* refactor: code review suggestions

* feat: add external error retriever for more accurate error messages

* refactor: use the same logger init for mcp purposes

* refactor: code review suggestions

* refactor(tsh): rename command to `tsh mcp db start`

* refactor(mcp): protect database resources with rw mutex

* chore: update server godocs

* chore: go mod tidy

* refactor: update command to take list of databases

* chore(mcp): license

* chore(tsh): remove unused function

* refactor: code review suggestions

* refactor(tsh): validate duplicated databases in MCP configuration

* refactor(tsh): rename files to mcp_db

* feat(mcp): add cluster name to the database resource

* fix(tsh): update InitLogger return type (#55479)

* MCP access part 1: update app definition and config (#54706)

* MCP access part 1: update app definition and config

* address feedback

* make -C integrations/operator crd

* MCP access part 2: new role options, access checker, role editor (#54734)

* MCP access part 2: new role options, access checker, role editor

* catch unsupported mcp fields

* simplify mcpToolsToModel

* MCP access part 3: audit events and reporting (#54779)

* MCP access part 3: audit events and reporting

* add new icon, storybook, format

* MCP access part 4: mcputils (#54880)

* MCP access part 4: mcp helpers

* address feedback

* address comment, minor edits

* update mcp-go

* MCP access part 5: Claude desktop config parser (#55179)

* claude desktop config

* rework

* split Config to Config and FileConfig

* add a comment on unofficial linux

* MCP access part 6: "tsh mcp ls" (#55292)

* MCP access part 6: "tsh mcp ls"

* address feedback

* MCP access part 7: MCP app in Web UI (#55306)

* MCP access part 7: MCP app in Web UI

* Make spacing in modal closer to what's in database modal

* add mcp app to ResourceActionButton.story.tsx

* move AppSubKind to shared/services/types.

* remove --format claude (not needed see part 8)

* add jsdoc

---------

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>

* MCP access part 8: tsh mcp config (#55370)

* MCP access part 8: tsh mcp login/logout

* change to --format and --config-file

* switch to config and drop logout

* enable debug by default

* remove unused ut functions

* MCP access part 9: tsh mcp connect, stub server, integration test (#55547)

* MCP access part 9: tsh mcp connect, stub server, integration test

* fix tests and lint

* MCP access part 10: server handler (#55644)

* MCP access part 10: server handler

* address feedback and fix docker tests

* add more comments

* minor lint fix

* move set logger default after other checks

* Implement `tsh mcp db config` (#55781)

* feat(tsh): add `tsh mcp db config` subcommand

* chore(claude): fix lint

* refactor: code review suggestions

* refactor: code review suggestions

* test(tsh): add missing option on test case

* chore(tsh): add message on manually adding database URI

* Refactor MCP database access to dial ALPN proxy directly (#55836)

* refactor: dial database instead of using local proxy for MCP servers

* refactor: review suggestions

* manual fixes

* tctl users add/update to support mcp tools trait (#56771)

* tctl users add/update to support mcp tools trait

* revert empty slice capability

* Enhances MCP servers usage with Cursor (#56474)

* feat(mcp): enhances MCP servers usage with Cursor

* refactor: code review suggestions

* mcputils refactor and new mcptest package (#56010)

* mcp server and mcputils refactor

* mcptest package

* allow testing in mcptest

* Teleport MCP demo server (#56637)

* Teleport MCP demo server

* replace guide tool with session tool, and switch to resource label

* add new flag to teleport configure

* replace teleport_session_id with mcp_transport_type

* feat(gomod): update mcp-go to v0.32.0

* eslint-disable-next-line (same in master)

---------

Co-authored-by: Gabriel Corado <gabriel.oliveira@goteleport.com>
Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a PR does not require a changelog entry size/md tsh tsh - Teleport's command line tool for logging into nodes running Teleport.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants