THINKINGOS
A I L a b o r a t o r y
Blog materials reflect our practical experience and R&D hypotheses. Where effects are mentioned, outcomes depend on project context, data quality, architecture, and implementation process.
Back to blog
Security
October 14, 2026 10 min
MCP Security AI Agents Secrets TaoCoder GitGuardian

How We Made Coding Agents Safer : Automatic Secret Extraction from MCP Configs

29 million hardcoded secrets in GitHub, 24,000 in MCP configs. We implemented automatic secret extraction at the IDE level: user enters a key → it's automatically protected via OS encryption.

How We Made Coding Agents Safer: Automatic Secret Extraction from MCP Configs

AI coding agents work with external tools through MCP servers. These server configurations store API keys and tokens — almost always in plaintext. According to GitGuardian, 29 million hardcoded secrets were found in public GitHub commits in 2025, with approximately 24,000 of those in MCP configuration files specifically. Commits involving AI assistants leak credentials at twice the rate of regular commits.

We faced this problem directly and implemented automatic secret extraction — a built-in mechanism for protecting MCP configurations at the IDE level. Below is a breakdown of the problem, a market comparison, and the architecture of our solution.

1) The Scale of the Problem: Secrets in MCP Are Not a Theoretical Risk

MCP (Model Context Protocol) has become the standard for connecting AI agents to external tools. Every MCP server may require an API key — for database access, search engines, payment systems, cloud storage.

When a developer sets up an MCP server, they write the key directly into a configuration file:

{
  "mcpServers": {
    "my-server": {
      "command": "npx",
      "args": ["-y", "@my/mcp-server"],
      "env": {
        "API_KEY": "sk-ant-api07-very-secret-key-here"
      }
    }
  }
}

This file can:

  • end up in Git alongside the project;
  • be read by another VS Code extension;
  • sit on disk in plaintext;
  • be synced through cloud storage.

GitGuardian’s data (“State of Secrets Sprawl 2026” report) shows the scale:

  • 28.65 million new hardcoded secrets in public GitHub commits in 2025 (+34% year-over-year)
  • 24,008 unique secrets found specifically in MCP configuration files
  • 2,117 of those were valid credentials that actually worked
  • AI service secrets: 1,275,105 leaks (+81% year-over-year)
  • 3.2% of commits with AI assistants contain leaks — vs. 1.5% baseline across all of GitHub

Notably, MCP documentation itself encourages insecure patterns. Setup guides recommend putting API keys directly into configuration files.

2) How Others Handle It: Plaintext Everywhere

We checked the major AI coding agents and IDEs:

ToolConfig FileApproach to Secrets
Cursor.cursor/mcp.json (project) + ~/.cursor/mcp.json (user)Plaintext in env/headers
Windsurfmcp_config.jsonPlaintext, same approach
Cline (original)mcp_settings.jsonPlaintext, no extraction mechanism
Roo CodeCline forkNo improvements in this area
Claude Desktopclaude_desktop_config.jsonPlaintext; login token in OS keychain (macOS), but MCP secrets — in file
VS Code Copilot~/.copilot/mcp-config.jsonSupports inputs (prompt at runtime), but no automatic extraction from configs

Third-party solutions (1Password, GitGuardian, Knostic) offer vault management or post-facto leak detection. But no IDE automatically extracts secrets from MCP configs at the editor level.

The problem is compounded by the fact that existing controls (repository scanners, IdP/IAM/PAM, secrets managers) don’t see the endpoint level. When a developer adds an MCP server in minutes, security review simply can’t keep up with the pace of change.

3) Our Approach: Automatic Secret Extraction

We implemented SecretExtractor — the industry’s first built-in mechanism for protecting MCP configs at the IDE level. The principle is simple: the user shouldn’t have to do anything to protect their keys. Enter a key in config → it’s automatically protected.

How It Works

User enters API key in config (plaintext)
    ↓
SecretExtractor automatically scans env vars and headers
    ↓
Key is saved to VS Code SecretStorage (OS-level encryption)
    ↓
Config gets a placeholder: {{SECRET:my-server_env_0}}
    ↓
UI shows a mask: [🔒 my-server_env_0]
    ↓
On server connection, runtime resolver substitutes the real value
    ↓
MCP server receives the real key and works normally

Key Properties

  1. Automatic — the user doesn’t need to do anything. Enter the key → it’s already protected.
  2. Deduplication — if the same value is already saved, the existing key is reused. No duplicates in storage.
  3. Secure storage — VS Code SecretStorage uses OS-level encryption (Keychain on macOS, DPAPI on Windows).
  4. UI mask — the JSON editor shows [🔒 key_name] instead of the real value. The key isn’t visible when browsing the config.
  5. Runtime resolver — on server connection, {{SECRET:KEY}} placeholders are automatically replaced with real values. The MCP server is unaware of the substitution.
  6. Backward compatibility — existing plaintext configs are automatically migrated on first connection.
  7. Leak-free logging — only counters and server names go into logs, never secret values.

4) Architecture: What’s Under the Hood

The system consists of several components, each responsible for its part of the pipeline:

┌─────────────────────────────────────────────────────┐
│  mcp_settings.json                                  │
│  "env": { "API_KEY": "{{SECRET:my-server_env_0}}" } │
└──────────────────────┬──────────────────────────────┘
                       │
          ┌────────────▼────────────┐
          │   SecretExtractor       │
          │   (extraction + dedup)  │
          └────────────┬────────────┘
                       │
          ┌────────────▼────────────┐
          │   VS Code SecretStorage │
          │   (OS encryption)       │
          └────────────┬────────────┘
                       │
          ┌────────────▼────────────┐
          │   SecretsResolver       │
          │   (runtime substitution)│
          └────────────┬────────────┘
                       │
          ┌────────────▼────────────┐
          │   MCP Server            │
          │   (receives the real    │
          │    API key)             │
          └─────────────────────────┘

SecretExtractor (331 lines) — scans env vars (stdio transport) and headers (sse/streamableHttp transport), generates key names using the ${serverName}_${fieldType}_${index} template, deduplicates via StateManager.getSecretKey().

SecretsResolver — recursive replacement of {{SECRET:KEY}} with real values from StateManager. Works transparently for the MCP server.

McpHub — integration point: extraction triggers on updateServerConnections() and connectToServer().

saveMcpSettingsJson — extraction on config write to disk. If a user manually adds a plaintext key, it will be extracted on the next save.

UI components — maskSecretsForDisplay() and unmaskSecretsForSave() for MCP and REST API JSON editors. The user sees masks, but placeholders are handled correctly on save.

5) Five Layers of MCP Risk and Where This Protection Fits

Aembit’s MCP security guide (2026) identifies five layers of risk:

  1. Transport & communications — missing TLS/mTLS, DNS rebinding, replay attacks
  2. Authentication & identity — static API keys, long-lived tokens in configs, hardcoded secrets
  3. Context integrity — agent context poisoning, data leakage into unrelated workflows
  4. Authorization & privileges — excessive permissions, privilege escalation
  5. Supply chain — malicious tool descriptors, repository pollution, shadow servers

Our solution covers the second layer — authentication & identity. This is a critical area: it’s where secrets end up in configs and from there — in Git, logs, cloud syncs.

But it’s important to understand: secret extraction is necessary but not sufficient. Full MCP protection requires:

  • transport control (TLS, mTLS);
  • context validation at every boundary;
  • least privilege for each MCP server;
  • runtime anomaly monitoring;
  • supply chain verification (signed artifacts, integrity hashes).

We’re working on extending protection in these directions — as part of the overall execution layer architecture (see our TaoBridge execution layer breakdown).

6) Test Coverage

We don’t trust security without tests. SecretExtractor is covered by:

  • 46 unit tests for SecretExtractor — all extraction, deduplication, and naming scenarios
  • 14 integration tests for the MCP secrets pipeline — full cycle from config write to runtime resolution
  • 232 lines of integration tests for StateManager custom secrets
  • Full cycle: Save → Extract → Placeholders → Load → Resolve → Real values → Round-trip

Every commit passes CI with these tests. If something breaks — deployment is blocked.

7) Why This Matters

Three factors make this problem especially relevant right now:

MCP is the new standard. Every AI agent connects to external tools through MCP. Every MCP server may require an API key. The number of secrets in configs grows linearly with the number of integrations.

Configs end up in Git. Developers often commit mcp.json alongside the project. Even if the file is in .gitignore, it can be read by another extension, synced through the cloud, or simply sit on disk in plaintext.

AI agents double the risk. According to GitGuardian, commits with AI assistants leak at twice the rate. Shadow AI scales faster than security policy: teams add agents and MCP servers in minutes, while security review operates on a different timescale.

Conclusion

TAO·CODER is the first coding agent that natively prevents secret leaks from MCP configs. Users get protection out of the box — no need to configure vaults, hooks, or third-party tools.

This isn’t marketing — this is engineering. Secrets shouldn’t live in plaintext. Period.

Key numbers:

  • 29 million hardcoded secrets in public GitHub commits in 2025
  • 24,000 secrets in MCP configs
  • 46 unit tests + 14 integration tests
  • 0 lines of plaintext after automatic extraction

Technical details:

  • SecretExtractor: vendor/cline/src/services/mcp/SecretExtractor.ts
  • SecretsResolver: vendor/cline/src/taocoder/runtime/secretsResolver.ts
  • StateManager custom secrets: vendor/cline/src/core/storage/StateManager.ts
  • UI mask: vendor/cline/webview-ui/src/components/mcp/configuration/tabs/JsonEditorScreen.tsx

References

AI Security

Need a similar system?

Share the task, and we will suggest an architecture, control layer, and rollout path.

Discuss a project