daBongo LMS AI Training Courses

Getting Started with Model Context Protocol

Lesson 5: Connecting Claude to External Services via MCP

Lesson Objectives

By the end of this lesson, students should be able to:

  • Handle authentication for external APIs within an MCP server
  • Return meaningful error responses from tool handlers
  • Apply production-ready patterns for MCP server robustness
  • Connect a real external service to Claude via a complete MCP server

Lesson Content

Authentication in MCP servers.

MCP servers handle their own authentication with external services – the host and client do not see API keys or credentials. The server is the trust boundary. Patterns:

  • Environment variables: Server reads credentials from environment at startup (os.environ.get("GITHUB_TOKEN"))
  • Configuration files: Credentials in the MCP server config (use carefully – config files may be committed to version control)
  • Secrets manager: Server retrieves credentials from a secrets service at startup (recommended for production)

The server should fail loudly at startup if required credentials are missing – not silently at tool call time.

Meaningful error responses.

Tool handlers should return errors that Claude can communicate to the user:

python @app.call_tool() async def call_tool(name: str, arguments: dict): if name == "search_github": try: results = github_client.search(arguments["query"]) return [types.TextContent(type="text", text=format_results(results))] except github.GithubException as e: return [types.TextContent( type="text", text=f"GitHub search failed: {e.status} {e.data.get('message', 'Unknown error')}" )]

Returning the error as a TextContent block allows Claude to surface it to the user with context, rather than the session crashing on an unhandled exception.

Production server patterns.

  • Startup validation: Check all required credentials and dependencies at server start; fail immediately if any are missing
  • Request logging: Log every tool call (name, sanitized arguments, result status) for debugging
  • Timeout handling: External API calls can hang; implement timeouts to prevent the server from blocking indefinitely
  • Rate limit awareness: If the external service has rate limits, implement backoff in the server before the tool call fails

Complete server checklist before deployment.

  • [ ] All credentials loaded from environment or secrets manager – not hardcoded
  • [ ] All tool arguments validated and sanitized before use
  • [ ] Error responses return as TextContent (not unhandled exceptions)
  • [ ] Startup validation fails fast if dependencies unavailable
  • [ ] Tool descriptions are precise and specific
  • [ ] Server tested locally with Claude Code across happy path and error cases

Practical Example

A developer builds an MCP server wrapping an internal ticket system API.

He implements: credential loading from environment variables, argument validation (ticket IDs must match a specific pattern), error responses as TextContent, startup validation that tests the API connection and exits with an error message if it fails, and request logging.

He tests five tool calls in Claude Code – two error cases (invalid ticket ID, API timeout) and three happy path cases.

All five behave correctly and return intelligible responses.

He checks the deployment checklist: all items complete.

Server goes to production.

Safety Notes

MCP servers that connect to internal APIs or databases have elevated trust within your infrastructure. Treat MCP server code with the same security review rigor as any code with database or API access. A vulnerability in an MCP server can be exploited via crafted Claude prompts that produce tool calls with malicious parameters – known as prompt injection. The tool argument validation in every handler is the defense against this attack vector.

Log in and enroll to access lesson quizzes.

Scroll to Top