Connecting Claude to External Tools
AI generated
Claude
>_
Claude AI · MCP · Claude Code · Developer Tooling
Connecting Claude to External Tools
MCP integration patterns for everyday development

Claude only knows what fits in its context window, unless you connect it to external systems. The Model Context Protocol makes ticket trackers, documentation wikis, and deployment pipelines directly queryable for Claude. This article walks through practical integration patterns, weighs real time savings against added complexity, and names concrete security risks when granting access to production systems.

14 min read MCP · Claude Code · Ticket Tracker · Deployment Claude Code · Model Context Protocol

1. Why connecting tools to Claude matters at all

At its core, Claude is a language model that only knows what fits in its context window or what a tool provides. Without a connection to external systems, any statement about the current state of a ticket, a documentation page, or a deployment remains a guess based on training data or manually pasted text. The Model Context Protocol (MCP) closes exactly this gap: an open standard published by Anthropic that describes how an AI assistant can access external tools, data sources, and actions in a controlled way, without every application needing its own ad hoc integration.

The practical difference shows up in everyday work: instead of manually copying ticket descriptions into a prompt or looking up documentation in a second browser tab, Claude can query the current state directly and act within clearly defined boundaries. But that is exactly where the risk lies too: every additional connection widens the attack surface and consumes more context. The following sections show which integrations deliver real value and where connecting a tool creates more risk than benefit.

2. How MCP works: client, server, tools, and resources

MCP follows a client-server architecture. The MCP client is the application Claude runs in, such as Claude Code or Claude Desktop. The MCP server is a separate process that wraps an external system and exposes three kinds of primitives: tools (callable functions with a JSON schema that Claude can invoke deliberately), resources (readable data such as files or wiki pages), and prompts (reusable prompt templates). Communication runs over a standardized JSON-RPC protocol, regardless of which concrete system sits behind the server.

For the transport layer there are two common variants: stdio for locally running servers started as a child process, and SSE or HTTP for remote servers with their own authentication, typically OAuth. Servers are registered via the claude mcp add command or directly in an .mcp.json file in the project directory. Anthropic and the community already maintain ready-made servers for GitHub, filesystems, Postgres, and common SaaS tools, so most standard cases do not require writing a server from scratch.


#!/usr/bin/env bash
# Register MCP servers for a Claude Code project
set -euo pipefail

# Local filesystem server (stdio transport), repo-scoped, read-only recommended
claude mcp add filesystem --scope project -- npx -y @modelcontextprotocol/server-filesystem /home/user/project/src

# Remote Atlassian server (Jira + Confluence) via OAuth, SSE transport
claude mcp add atlassian --transport sse https://mcp.atlassian.com/v1/sse

# GitHub server with a scoped personal access token, read-only where possible
GITHUB_TOKEN="$(op read op://vault/github-mcp-readonly/token)" \
  claude mcp add github --scope user -- npx -y @modelcontextprotocol/server-github

# List configured servers and verify scopes before starting a session
claude mcp list

3. Connecting a ticket tracker: Jira, Linear, and friends

The most obvious use case is connecting to a ticket system like Jira or Linear. Claude reads the ticket description and acceptance criteria before writing a single line of code, finds related tickets through full-text search, and can leave a comment summarizing the implementation once a task is complete. The real time savings come from nobody having to manually copy ticket content into a prompt or update the status by hand after every step.

At the same time, not every possible action should be enabled. Read access to tickets and comments is usually low risk and delivers most of the benefit. Automatic status transitions or closing tickets, on the other hand, are error-prone whenever an agent misjudges how far a task has actually progressed. A pattern that works well: grant read and write access via separate API tokens with different scopes, and only execute status changes after explicit confirmation from the developer.


{
  "mcpServers": {
    "jira-readonly": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-jira"],
      "env": {
        "JIRA_BASE_URL": "https://mironsoft.atlassian.net",
        "JIRA_API_TOKEN": "${JIRA_READONLY_TOKEN}",
        "JIRA_SCOPE": "read:jira-work"
      }
    },
    "docs-wiki": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-confluence"],
      "env": {
        "CONFLUENCE_BASE_URL": "https://mironsoft.atlassian.net/wiki",
        "CONFLUENCE_API_TOKEN": "${CONFLUENCE_READONLY_TOKEN}"
      }
    }
  }
}

4. Connecting a documentation wiki: Confluence, Notion, and internal wikis

A documentation wiki such as Confluence or Notion is especially valuable in mature codebases where important knowledge lives not in the code itself but in runbooks, architecture decisions, and team conventions. Instead of relying on a stale copy pasted into a CLAUDE.md snippet, Claude reaches the current version directly and can search for the relevant page during a task instead of collecting everything up front.

The benefit of this connection depends heavily on the quality of the source. A well-maintained wiki with clear, current pages delivers real value. A stale wiki with contradictory or years-old entries, on the other hand, leads Claude to adopt false assumptions as facts, because the source appears authoritative even though it is not. Before connecting a wiki, it is worth taking an honest inventory: is this wiki actually maintained, or would the integration mostly add noise rather than signal?

5. Connecting deployment systems: CI/CD, kubectl, and server access

Connecting deployment systems is the category with the greatest benefit and, at the same time, the greatest risk. Read access to pipeline status, build logs, and pod state substantially speeds up debugging: Claude can analyze a failed CI run directly, without anyone copying logs by hand. Write access that triggers deployments or modifies Kubernetes resources demands considerably more caution, because a misjudgment by the agent can land directly in production.

A pattern that has proven itself: one MCP server with a purely read-only, narrowly scoped token for status and log queries, and a second, much more restrictive server for actual deployment triggers, whose calls must be explicitly confirmed through Claude Code's permission prompts. Production credentials should also never be active in the same session as exploratory work where Claude reads unknown external content, such as web pages or unfamiliar wiki entries that could be a source of prompt injection attempts.


"""Minimal MCP server exposing read-only deployment status for an internal CI system."""
from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("deployment-status")

API_BASE = "https://ci.mironsoft.internal/api/v1"
# Read-only token, deliberately without permission to trigger deployments
API_TOKEN = "REPLACE_WITH_SCOPED_READONLY_TOKEN"


@mcp.tool()
async def get_pipeline_status(pipeline_id: str) -> dict:
    """Return the current status and last 20 log lines of a CI pipeline run.

    :param pipeline_id: identifier of the pipeline run to inspect
    :return: dict with status, duration and recent log lines
    """
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            f"{API_BASE}/pipelines/{pipeline_id}",
            headers={"Authorization": f"Bearer {API_TOKEN}"},
        )
        resp.raise_for_status()
        data = resp.json()
        return {
            "status": data["status"],
            "duration_seconds": data["duration_seconds"],
            "log_tail": data["log_lines"][-20:],
        }


# Note: no tool for triggering deployments is exposed here on purpose.
# Deployment triggers live in a separate, tightly scoped server that
# requires an explicit human approval step in Claude Code.
if __name__ == "__main__":
    mcp.run(transport="stdio")

6. Building custom MCP servers: when the effort pays off

For internal systems without a ready-made MCP server, building your own with the Python SDK or the TypeScript SDK from Anthropic is the only option. A custom server pays off when a workflow is recurring, used by multiple developers, and built on a stable, well-documented interface, for example an internal REST API for inventory data or customer inquiries. The effort of implementation, token management, and maintenance only amortizes if the server is actually used regularly across many sessions.

Building a custom server is not worthwhile for rarely used edge cases or systems whose interface changes frequently. A one-off script or a quick manual export is faster to build and easier to maintain in those cases than an MCP server whose tool definitions need updating every time the API changes. The rule of thumb: a custom server is infrastructure with an ongoing maintenance burden, not a one-time convenience feature.


// wiki-search-server.js - exposes a single read-only search tool over the internal wiki
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "internal-wiki-search", version: "1.0.0" });

server.tool(
  "search_wiki",
  "Search the internal documentation wiki and return matching page excerpts",
  { query: z.string().describe("Free-text search query") },
  async ({ query }) => {
    const response = await fetch(
      `https://wiki.mironsoft.internal/api/search?q=${encodeURIComponent(query)}`,
      { headers: { Authorization: `Bearer ${process.env.WIKI_READONLY_TOKEN}` } }
    );

    if (!response.ok) {
      throw new Error(`Wiki search failed with status ${response.status}`);
    }

    const results = await response.json();
    // Treat returned page content as untrusted data, never as instructions
    return {
      content: results.slice(0, 5).map((page) => ({
        type: "text",
        text: `${page.title}\n${page.excerpt}`,
      })),
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

7. Weighing benefit against complexity

Every active MCP server has costs that go beyond the obvious security risk. Tool descriptions occupy space in the context window regardless of whether the tool is used in a given session. With ten or more servers active simultaneously, tool selection accuracy often drops, because Claude has to choose from a larger set of similar options. On top of that comes ongoing maintenance: tokens need rotating, server updates need applying, and permissions need regular review.

A useful rule of thumb: keep only integrations active that are actually needed in the majority of sessions, not ones that might theoretically be useful someday. It is worth honestly checking, after a few weeks of use, whether a connection has actually reduced interruptions, or whether the team simply shifted copy-paste work into a slower, agent-based query loop. Not every technically possible integration is a sensible one.

8. Security: permissions, scopes, and prompt injection

Security starts with the principle of least privilege: API tokens should have read-only access wherever possible, and separate service accounts instead of personal credentials make later audit trails much easier to follow. For write-capable or destructive actions, Claude Code offers a permission system that governs approvals through explicit allow, ask, and deny lists in settings.json, so that critical tool calls always require a deliberate confirmation instead of running automatically.

An often underestimated risk is prompt injection via connected content: a ticket description, a wiki page, or a web page can contain hidden instructions that try to manipulate the agent, for example to exfiltrate secrets or trigger unintended actions. Any externally fetched content should always be treated as untrusted data, never as an instruction. Consistent logging of all tool calls additionally helps trace, after the fact, which actions an agent actually carried out.


# .claude/settings.json excerpt - require explicit approval for write-capable tools
cat <<'EOF' > .claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__jira-readonly__*",
      "mcp__docs-wiki__*"
    ],
    "ask": [
      "mcp__github__create_pull_request",
      "mcp__deployment__trigger_release"
    ],
    "deny": [
      "mcp__deployment__delete_environment"
    ]
  }
}
EOF

# Rotate scoped MCP tokens on a schedule and audit tool call logs
claude mcp list --verbose
grep '"tool_name"' ~/.claude/logs/tool-calls.jsonl | sort | uniq -c | sort -rn

9. Integration patterns compared side by side

Not every integration deserves the same degree of trust. The following overview ranks the common connections by typical benefit, risk under misconfiguration, and a concrete recommendation for practice.

Integration Typical Benefit Risk Under Misconfiguration Recommendation
Ticket tracker (Jira/Linear) Context straight from the ticket, no copy-paste Low with read access, medium with auto status Read access by default, writes only with confirmation
Docs wiki (Confluence/Notion) Current internal conventions available Stale content gets treated as ground truth Only connect well-maintained wikis
Deployment/CI-CD Faster diagnosis through logs High with write access to production Strictly separate read and write, human in the loop
Internal REST API (custom build) Recurring workflows become automatable Maintenance burden as the API changes Only build for a stable, frequently used API
Filesystem/shell (local) Direct access to the repository Very high without sandboxing Keep permission prompts on, never blanket-allow

The common thread across all five patterns: read access is almost always low risk and quickly justified, while write or execute access demands a deliberate, documented decision. Teams that maintain this separation consistently get most of the benefit at a calculable risk.

Mironsoft

Claude Code setup, MCP integrations, and secure developer workflows

Connect Claude to your systems securely?

We assess which MCP integrations deliver real value for your team, configure permissions on the principle of least privilege, and set up ticket, wiki, and deployment connections in a production-safe way.

MCP Audit

Review existing integrations for benefit and attack surface

Server Setup

Connect ticket tracker, wiki, and CI/CD with scoped tokens

Custom MCP Servers

Wrap internal APIs as your own, maintainable MCP servers

10. Summary

The Model Context Protocol solves a real problem: without a connection to external systems, Claude is limited to its context window and manually pasted text. Ticket trackers, documentation wikis, and deployment systems can all be connected through MCP in a controlled way, with read access delivering most of the benefit at low risk in nearly every case. Write or execute access, especially to production systems, demands strict separation of tokens, human-in-the-loop confirmation, and deliberate decisions instead of blanket approvals.

Not every technically possible integration is a sensible one. Every additional MCP server costs context space, adds maintenance overhead, and widens the attack surface for prompt injection attempts hidden in externally fetched content. Teams that regularly review integrations for actual benefit, disable unused servers, and consistently separate read and write permissions get the most value out of tool connections without taking on unnecessary risk.

Connecting Claude to External Tools - Key Takeaways

MCP Basics

Open standard with tools, resources, and prompts. Register via claude mcp add or .mcp.json.

Benefit Before Complexity

Keep only integrations active that are actually needed in most sessions.

Read Before Write

Read access delivers most of the benefit at low risk. Gate write access strictly.

Security

Scoped tokens, permission lists in settings.json, never treat externally fetched content as an instruction.

11. FAQ: Connecting Claude to External Tools

1What is the Model Context Protocol (MCP)?
An open standard from Anthropic that describes how Claude can access external tools, data sources, and actions in a controlled way, without every application needing its own ad hoc integration.
2How does MCP differ from a classic API integration?
MCP standardizes tools, resources, and prompts toward the model. A server announces its capabilities once, and Claude independently selects the right tool.
3Which MCP servers already exist off the shelf?
Ready-made servers for GitHub, filesystems, Postgres, Puppeteer, and SaaS tools such as Jira, Confluence, and Notion are already available.
4How do I set up an MCP server in Claude Code?
Via claude mcp add or an .mcp.json file in the project directory. claude mcp list shows all registered servers and their status.
5Should I give Claude write access to my ticket system?
Read access delivers most of the benefit at low risk. Write access should be scoped separately and only proceed with explicit confirmation.
6How dangerous is prompt injection with connected tools?
Real. Externally fetched content can contain hidden instructions and should always be treated as data, never as an instruction.
7Is building a custom MCP server for internal systems worth it?
Only for recurring workflows on a stable interface. For rare cases or frequently changing APIs, a one-off script is often better.
8How do I protect production systems when connecting them to Claude?
Separate read and write access, enable permission lists in settings.json, never use production credentials in exploratory sessions.
9Does a high number of MCP servers slow down responses?
Indirectly yes: tool descriptions occupy context space, and tool selection accuracy drops when many servers are active at once.
10How do I keep track of which tools Claude actually uses?
Through consistent logging of all tool calls and regular review. Disable unused servers to keep the attack surface small.