Problem Statement
The user wants a new web application that acts as a project copilot for engineering work across Jira and Azure DevOps. Existing MCP-powered experiences in tools like VS Code and Claude Code prove the value of this workflow, but the user wants their own dedicated product with persistent chat history, authenticated integrations, structured approvals for risky actions, and a product experience tailored to project questions and operational workflows.
From the user’s perspective, the current problem is not that Jira or Azure DevOps lack data. The problem is that project knowledge is fragmented across systems, difficult to query conversationally, and cumbersome to act on safely. A user may know the information exists in Jira boards, work items, pull requests, wiki pages, or pipelines, but still spend too much time hunting for it, correlating it, and turning it into the next action. The user wants a single assistant interface that can answer questions about their projects, persist context across time, and eventually help take action inside these tools with explicit safety checks.
The user also wants the product to be built on a modern TypeScript stack they prefer: Next.js App Router in src/, Better Auth with Google sign-in, Drizzle, Postgres via DATABASE_URL, Biome, shadcn/ui, AI Elements, and Gemini as the primary model family. They want strong module boundaries from the start and high-confidence tests and evaluations around the agentic behaviors.
Solution
Build a per-user project copilot web app that lets each signed-in user connect one Jira site and one Azure DevOps organization, then ask questions or request actions through a persistent chat interface. The app will use Google sign-in through Better Auth, store chat history and encrypted integration credentials in Postgres, and use deep backend modules to separate authentication, persistence, provider connections, MCP orchestration, tool routing, approval policies, and chat execution.
The product experience will start with three primary pages: Chat, Integrations, and History. The Integrations page will provide durable connect, reconnect, disconnect, and status management for Jira and Azure DevOps. Chat will auto-route tool usage to Jira or Azure DevOps based on the prompt and the user’s connected accounts, with a manual override control when the user wants to force one system. History will let the user return to prior threads with full message and approval context.
The assistant will use Gemini through the direct Google provider package in the AI SDK. The implementation will include configuration placeholders for a future Azure model fallback path, but only Google models will be active in v1. The assistant will support reads immediately and full write-capable architecture in v1, but risky operations will pause for explicit human confirmation before execution. Reads will not require confirmation. This creates a path to real utility without giving up safety.
Jira and Azure DevOps will both be treated as MCP-backed integrations in the product design. Jira is straightforward. Azure DevOps remote MCP will be pursued directly despite current Microsoft caveats for custom client support, and the product must explicitly model and surface connection-blocked states rather than silently substituting a different transport.
User Stories
- As a signed-in user, I want to log into the app with Google, so that I can access my personal workspace securely.
- As a signed-in user, I want my own workspace, so that my chat history and connected systems are isolated from other users.
- As a signed-in user, I want to connect my Jira site, so that the assistant can answer questions about my Jira data.
- As a signed-in user, I want to connect my Azure DevOps organization, so that the assistant can answer questions about my Azure DevOps data.
- As a signed-in user, I want to see whether each integration is connected, disconnected, expired, or blocked, so that I understand what the assistant can access.
- As a signed-in user, I want to reconnect an integration when credentials expire, so that I can restore functionality without losing history.
- As a signed-in user, I want to disconnect an integration, so that I can revoke access when I no longer want the assistant to use that system.
- As a signed-in user, I want the app to remember my prior conversations, so that I can continue work over time.
- As a signed-in user, I want to open a prior thread from history, so that I can resume an earlier investigation or workflow.
- As a signed-in user, I want the assistant to infer whether I mean Jira or Azure DevOps, so that I do not have to specify the system every time.
- As a signed-in user, I want to override the assistant’s integration choice, so that I can force a request to run against Jira or Azure DevOps explicitly.
- As a signed-in user, I want to ask what is blocked in my current sprint, so that I can quickly identify project risk.
- As a signed-in user, I want to ask which work items are assigned to me, so that I can prioritize my next actions.
- As a signed-in user, I want to ask which pull requests need my review, so that I can handle review work efficiently.
- As a signed-in user, I want to ask for a summary of project status across systems, so that I can prepare updates faster.
- As a signed-in user, I want to ask about wiki or documentation content, so that I can retrieve project knowledge without manual searching.
- As a signed-in user, I want to ask about pipeline status and recent failures, so that I can identify delivery issues faster.
- As a signed-in user, I want to ask what changed recently in a project, so that I can catch up quickly after time away.
- As a signed-in user, I want the assistant to correlate information across issues, work items, pull requests, and documentation, so that I can get higher-level answers than a single system query provides.
- As a signed-in user, I want the assistant to explain where an answer came from, so that I can trust or verify it.
- As a signed-in user, I want chat responses to render cleanly with markdown, tool results, and reasoning states, so that the interface feels reliable and readable.
- As a signed-in user, I want to see when the assistant is calling tools, so that I understand what it is doing on my behalf.
- As a signed-in user, I want to see when the assistant is waiting for approval, so that I know a risky action is paused rather than failed.
- As a signed-in user, I want to approve a risky action from the chat experience, so that I can continue the workflow without leaving context.
- As a signed-in user, I want to deny a risky action, so that I stay in control of project changes.
- As a signed-in user, I want approvals to survive refreshes or navigation, so that I do not lose control state when the page changes.
- As a signed-in user, I want read-only questions to execute immediately, so that the product feels fast for common queries.
- As a signed-in user, I want risky writes like creating, updating, deleting, commenting, transitioning, or triggering runs to require explicit confirmation, so that accidental mutations do not happen silently.
- As a signed-in user, I want to ask the assistant to create or update work artifacts eventually, so that the app can become an operational copilot instead of only a reporting tool.
- As a signed-in user, I want the product to clearly distinguish safe reads from risky writes, so that I understand when confirmation is necessary.
- As a signed-in user, I want to connect integrations from a dedicated Integrations page, so that I can manage access deliberately.
- As a signed-in user, I want to be prompted to connect an integration when needed in chat, so that I can recover from missing setup without breaking flow.
- As a signed-in user, I want one Jira site in v1, so that the UI and routing remain simple.
- As a signed-in user, I want one Azure DevOps organization in v1, so that the UI and routing remain simple.
- As a signed-in user, I want the system to prevent ambiguous multi-site or multi-org behavior in v1, so that responses remain predictable.
- As a product owner, I want per-user persistence for credentials and chat history, so that the product supports real daily usage rather than demo-only sessions.
- As a product owner, I want encrypted token storage, so that external integration secrets are protected at rest.
- As a product owner, I want deep module boundaries, so that the implementation remains maintainable as features expand.
- As a product owner, I want provider-specific integration logic isolated behind stable interfaces, so that future transport changes do not leak into the chat or UI layers.
- As a product owner, I want approval policy logic separated from integration adapters, so that safety rules can evolve independently of transport code.
- As a product owner, I want model configuration isolated behind a provider registry, so that future Google model updates or Azure fallback work do not require broad code churn.
- As a product owner, I want the product to explicitly surface Azure DevOps remote MCP auth limitations, so that user trust is not damaged by opaque failures.
- As a product owner, I want the first version to be robust even if Azure DevOps remote MCP is partially blocked for custom clients, so that the product can still explain the failure state correctly.
- As an engineer implementing the product, I want a clear schema for users, sessions, threads, messages, connections, and approvals, so that the app can be built without product ambiguity.
- As an engineer implementing the product, I want integration status modeled explicitly, so that retries and reconnect flows are deterministic.
- As an engineer implementing the product, I want a stable way to classify tool calls by risk, so that approval behavior is testable.
- As an engineer implementing the product, I want automatic chat routing and manual override to use the same routing core, so that behavior is consistent and testable.
- As an engineer implementing the product, I want message persistence to store the structured UI message form, so that history replay and approvals can be reconstructed accurately.
- As an engineer implementing the product, I want the chat experience to remain provider-agnostic at the UI level, so that model changes do not force client rewrites.
- As an engineer implementing the product, I want agentic evaluation coverage for routing, approval, and tool usage behavior, so that model-level regressions are caught before release.
- As a security-conscious user, I want writes to be explicit and reviewable, so that I can trust the assistant with higher privileges.
- As a security-conscious user, I want the app to avoid leaking provider tokens to the browser, so that my external accounts remain protected.
- As a user returning after time away, I want to see thread titles and timestamps in history, so that I can find the right conversation quickly.
- As a user working across multiple project tasks, I want separate threads, so that contexts do not collapse into one noisy conversation.
- As a user asking a vague question, I want the system to ask for clarification or let me override the target integration, so that it does not confidently choose the wrong system.
- As a user making a risky request, I want the approval prompt to summarize the intended action, so that I can make a good decision quickly.
- As a user whose integration is expired, I want the assistant to explain why it cannot proceed and guide me to reconnect, so that failures are actionable.
- As a user whose Azure DevOps remote MCP auth is unsupported in the current environment, I want the UI to say that clearly, so that I do not waste time debugging a hidden limitation.
- As a maintainer, I want a clear separation between product UX decisions and provider transport details, so that future versions can grow without architectural drift.
- As a maintainer, I want the app shell and page structure to be simple and stable, so that feature additions land in predictable places.
- As a maintainer, I want evaluation datasets for agentic flows, so that routing and approval behavior can be improved deliberately over time.
- As a maintainer, I want end-to-end tests around the most important user journeys, so that the product remains trustworthy as integrations evolve.
Implementation Decisions
- The product will be a new web application built on Next.js App Router with the
src/ directory layout.
- The stack will include TypeScript, Tailwind CSS, Biome, shadcn/ui, AI Elements, Drizzle, Postgres via
DATABASE_URL, Better Auth, and the AI SDK.
- Authentication will use Better Auth with Google as the only implemented sign-in provider in v1.
- The product will use a per-user workspace model. Shared or team workspaces are out of scope for v1.
- The app will start with three top-level product surfaces: Chat, Integrations, and History.
- Chat history and provider connections will be durable from day one. The product will not use ephemeral demo-only chat sessions.
- Persistent storage will include user auth/session state, integration connections, chat threads, chat messages, and approval records.
- External integration tokens will be stored server-side only and encrypted at rest before database persistence.
- Each user may connect one Jira site in v1.
- Each user may connect one Azure DevOps organization in v1.
- The connection UX must exist in both places: a dedicated Integrations management surface and in-context on-demand prompts from chat.
- Jira will be integrated through remote MCP.
- Azure DevOps will also target remote MCP in v1, despite known Microsoft caveats for custom clients outside VS Code and Visual Studio.
- Azure DevOps connection behavior must explicitly represent unsupported or blocked remote auth states instead of silently replacing the transport or pretending the integration succeeded.
- The assistant will use Gemini models through the direct Google AI SDK provider package, not AI Gateway.
- The model layer will still be abstracted so that Azure provider fallback can be configured later.
- Azure model fallback is not implemented in v1. Only configuration placeholders and provider abstraction boundaries are required.
- The product will support both automatic integration routing and manual integration override.
- Automatic routing will consider the user’s connected accounts and the user’s prompt intent.
- Manual override must be able to force Jira or Azure DevOps for a given interaction or thread context.
- AI output in the browser must be rendered with AI Elements rather than custom markdown rendering.
- The product should preserve structured assistant responses, including tool activity and approval states, in persisted chat history.
- The implementation should use deep modules rather than a thin app-first structure.
- The core modules should include:
- auth and session management
- integration connection vault
- MCP client orchestration
- chat orchestration and persistence
- tool routing and provider selection
- approval policy and approval execution state
- app shell and user-facing product surfaces
- These modules should expose simple, stable interfaces and hide provider and persistence complexity behind them.
- Risk classification must be centralized rather than encoded ad hoc inside UI code or provider adapters.
- Reads should execute without approval.
- Risky actions should require explicit approval before execution.
- Risky actions include creates, updates, deletes, transitions, comments, bulk actions, and pipeline or run triggers.
- Approval records must be durable and resumable so that refreshes and navigation do not lose pending decision state.
- The product is architected for full write capability in v1, with confirmation as the main safety rail rather than a read-only restriction.
- The implementation should preserve enough metadata around tool calls and approvals to support auditing and trustworthy UX.
- The product should be designed so that future expansion to multiple sites, multiple orgs, additional auth providers, and broader toolsets is possible without collapsing the core abstractions.
Testing Decisions
- Good tests should validate external behavior and user-visible outcomes rather than internal implementation details.
- Good tests should verify stable contracts: authentication behavior, persistence behavior, connection state transitions, routing decisions, approval requirements, tool execution lifecycle, and chat continuity.
- Good tests should avoid coupling to transient component structure, internal helper names, or provider-specific incidental details that are not part of the contract.
- The implementation should include critical coverage across both traditional tests and agentic evaluations.
- Required module-level test focus includes:
- auth and session behavior
- encrypted connection persistence
- integration status transitions
- chat thread and message persistence
- integration routing behavior
- approval policy behavior
- approval lifecycle behavior
- provider adapter behavior at the contract level
- UI and end-to-end coverage should include:
- Google sign-in and protected navigation
- connect and reconnect flows from Integrations
- on-demand connect prompts from Chat
- thread creation and history resume
- manual integration override
- risky action approval and denial flows
- blocked or unsupported Azure DevOps remote MCP states
- Agentic portions of the product should also be evaluated with Evalite.
- Evalite coverage should focus on:
- integration selection and auto-routing quality
- manual override correctness
- risk classification consistency
- approval triggering behavior
- response grounding and tool-use behavior in representative project prompts
- The evaluation suite should contain realistic prompt sets for Jira questions, Azure DevOps questions, cross-system questions, safe reads, and risky writes.
- There is no useful local prior art in the repository yet because the codebase is effectively empty. The PRD should therefore assume that testing conventions must be established from first principles rather than copied from existing project tests.
Out of Scope
- Shared team workspaces in v1.
- Multiple Jira sites per user in v1.
- Multiple Azure DevOps organizations per user in v1.
- Non-Google sign-in providers in v1.
- Fully implemented Azure model fallback in v1.
- Silent substitution of Azure DevOps REST or local MCP transport in place of the remote MCP target.
- Broad provider-agnostic multi-model strategy in v1 beyond the Google-first abstraction and Azure placeholders.
- Advanced analytics, dashboards, or data warehousing beyond what is required for core chat persistence and operational behavior.
- A memory or indexing system that ingests project data into a separate search corpus in v1.
- Anonymous or unauthenticated product usage.
- Team administration, role management, or enterprise tenant controls in v1.
Further Notes
- Azure DevOps remote MCP is a deliberate risk area. The product should treat it as a first-class product constraint rather than a minor implementation detail.
- The first implementation should prioritize trustworthy UX over magical behavior. When an integration is disconnected, expired, blocked, or unsupported, the app should say so clearly and guide the user toward the next step.
- The product should be optimized for future extension, but the v1 user experience should remain intentionally narrow and comprehensible.
Problem Statement
The user wants a new web application that acts as a project copilot for engineering work across Jira and Azure DevOps. Existing MCP-powered experiences in tools like VS Code and Claude Code prove the value of this workflow, but the user wants their own dedicated product with persistent chat history, authenticated integrations, structured approvals for risky actions, and a product experience tailored to project questions and operational workflows.
From the user’s perspective, the current problem is not that Jira or Azure DevOps lack data. The problem is that project knowledge is fragmented across systems, difficult to query conversationally, and cumbersome to act on safely. A user may know the information exists in Jira boards, work items, pull requests, wiki pages, or pipelines, but still spend too much time hunting for it, correlating it, and turning it into the next action. The user wants a single assistant interface that can answer questions about their projects, persist context across time, and eventually help take action inside these tools with explicit safety checks.
The user also wants the product to be built on a modern TypeScript stack they prefer: Next.js App Router in
src/, Better Auth with Google sign-in, Drizzle, Postgres viaDATABASE_URL, Biome, shadcn/ui, AI Elements, and Gemini as the primary model family. They want strong module boundaries from the start and high-confidence tests and evaluations around the agentic behaviors.Solution
Build a per-user project copilot web app that lets each signed-in user connect one Jira site and one Azure DevOps organization, then ask questions or request actions through a persistent chat interface. The app will use Google sign-in through Better Auth, store chat history and encrypted integration credentials in Postgres, and use deep backend modules to separate authentication, persistence, provider connections, MCP orchestration, tool routing, approval policies, and chat execution.
The product experience will start with three primary pages: Chat, Integrations, and History. The Integrations page will provide durable connect, reconnect, disconnect, and status management for Jira and Azure DevOps. Chat will auto-route tool usage to Jira or Azure DevOps based on the prompt and the user’s connected accounts, with a manual override control when the user wants to force one system. History will let the user return to prior threads with full message and approval context.
The assistant will use Gemini through the direct Google provider package in the AI SDK. The implementation will include configuration placeholders for a future Azure model fallback path, but only Google models will be active in v1. The assistant will support reads immediately and full write-capable architecture in v1, but risky operations will pause for explicit human confirmation before execution. Reads will not require confirmation. This creates a path to real utility without giving up safety.
Jira and Azure DevOps will both be treated as MCP-backed integrations in the product design. Jira is straightforward. Azure DevOps remote MCP will be pursued directly despite current Microsoft caveats for custom client support, and the product must explicitly model and surface connection-blocked states rather than silently substituting a different transport.
User Stories
Implementation Decisions
src/directory layout.DATABASE_URL, Better Auth, and the AI SDK.Testing Decisions
Out of Scope
Further Notes