Scenario-Based AI Engineering Questions

Course Content

Scenario-Based AI Engineering Questions

26 sections · 146 lessons

How would you expose internal Jira, Confluence and Snowflake data to many AI clients without writing a separate integration for each?


Three servers instead of nine integrationsClients: IDE, chat tool, support agentMCP: one protocol, OAuth per end userjira-mcp, docs-mcp, warehouse-mcpDownstream calls with the user's access
Each server acts with the caller's permissions, never a shared account, so an agent cannot see more than the person using it.

What you need to know

Without MCP, three clients and three data sources mean up to nine custom integrations. With MCP, you write three servers and each client speaks the same protocol.

Design decisions to defend

DecisionChoiceWhy
Server boundariesOne per domain: jira-mcp, docs-mcp, warehouse-mcpSeparate deploys, permissions and blast radius
Transportstdio for a local developer tool; Streamable HTTP for a shared remote serverstdio runs as a local process; HTTP serves many users
IdentityOAuth for the end user; downstream calls made with that user's permissionsThe agent never sees more than the person using it
Tool surfaceFew, narrow, typed toolsModels choose well from a small, well-described set
ResultsCompact, bounded payloads with idsRaw API JSON wastes context and hurts accuracy

Identity, stated carefully

The server must know who is asking. The client gets an OAuth token for the MCP server. The server then calls Jira or Snowflake on that user's behalf, using a downstream credential issued for that user, for example through a token exchange or a separate OAuth grant to Jira.

Two things to avoid. First, a shared service account: the agent would inherit the union of everyone's access, so an intern's question could read the board's documents. Second, "token passthrough", where the server forwards the token it received straight to another API. The MCP security guidance forbids it, because it breaks audit trails and lets a token meant for one service be replayed against another.

Narrow tools beat generic ones

Python
from mcp.server.fastmcp import FastMCPmcp = FastMCP("jira")@mcp.tool()def search_issues(project: str, status: str = "open", updated_after: str | None = None) -> list[dict]:    """Find Jira issues in one project. Use for questions about bugs, tasks or their status.    Returns at most 20 issues with key, title, status and assignee."""    issues = jira_for_current_user().search(project=project, status=status,                                            updated_after=updated_after, limit=20)    return [{"key": i.key, "title": i.title, "status": i.status, "assignee": i.assignee}            for i in issues]

search_issues(project, status, updated_after) is safer and more accurate than a generic run_jql(query). The model fills three clear fields instead of writing a query language, and the result is capped at 20 compact rows.

Rollout plan

  1. Read-only first — search and fetch tools only.
  2. Audit everything — caller, tool, arguments, result size, latency.
  3. Rate-limit per user — an agent in a loop should not hammer Snowflake.
  4. Writes behind confirmation — creating or editing issues asks the user before running.

A real-life example

Scenario (illustrative numbers). A fintech's platform team gets requests from three groups: developers want Jira in their IDE assistant, analysts want Snowflake in a chat tool, and support wants Confluence answers inside their agent. Building each by hand would be nine integrations.

They build three MCP servers. The warehouse server exposes two tools, list_tables(schema) and run_readonly_query(sql), and every query runs under the analyst's own Snowflake role with a row limit of 500. In the first month, audit logs show 11,000 tool calls. One logged call tried to read a salary table and was denied by the user's own role, which is the permission model working as designed. Adding a fourth client later took an afternoon of configuration and no new code.

Follow-up questions to expect

  • "Why not one server for everything?" — One compromise or outage would take out all data access, and every tool would share one permission model and one deploy cycle.
  • "How do you stop prompt injection from a Confluence page?" — Treat fetched content as data, keep write tools behind confirmation, and never let a tool result grant new permissions.
  • "How many tools per server?" — As few as cover the tasks; if a client loads many servers, the total tool count is what hurts selection accuracy.