diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Deployments/IAIDeploymentStore.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Deployments/IAIDeploymentStore.cs
new file mode 100644
index 00000000..1152310e
--- /dev/null
+++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Deployments/IAIDeploymentStore.cs
@@ -0,0 +1,12 @@
+using CrestApps.Core.AI.Models;
+using CrestApps.Core.Services;
+
+namespace CrestApps.Core.AI.Deployments;
+
+///
+/// Provides persisted storage for AI deployments while preserving the standard
+/// named-and-sourced catalog operations used by deployment managers and editors.
+///
+public interface IAIDeploymentStore : INamedSourceCatalog
+{
+}
diff --git a/src/CrestApps.Core.Docs/docs/changelog/v1.0.0.md b/src/CrestApps.Core.Docs/docs/changelog/v1.0.0.md
index b545fd30..97262e73 100644
--- a/src/CrestApps.Core.Docs/docs/changelog/v1.0.0.md
+++ b/src/CrestApps.Core.Docs/docs/changelog/v1.0.0.md
@@ -25,3 +25,6 @@ description: Initial standalone release notes for the CrestApps.Core repository.
- evaluates every configured AI connection and deployment section when importing appsettings records, including provider-grouped connection sections and deployment entries that reference shared `ConnectionName` values
- adds shared `JsonNode` support extensions for common string, boolean, and raw-value extraction so AI configuration parsing and Elasticsearch document readers reuse one implementation instead of duplicating private helpers
- replaces removed obsolete connection-level deployment-name helpers with non-obsolete legacy lookup extensions for `AIProviderConnectionEntry`, keeping backward-compatible fallback resolution without depending on deleted APIs
+- clarifies deployment-store registration by introducing `IAIDeploymentStore` for persisted deployments, moves Chat Interactions ahead of AI Profiles / AI Chat in the MVC sample onboarding flow, and adds dedicated AI Profile documentation that explains how profiles power reusable chat, agents, orchestration, retrieval, and session processing
+- centralizes reusable MCP runtime registration in `AddCoreAIMcpServices()`, moves the shared MCP metadata, capability-resolution, tool-registry, SSE settings-handler, and invoke-function services into `CrestApps.Core.AI.Mcp`, and splits optional StdIO transport registration so hosts can enable it only where needed
+- treats aborted and canceled request-stream failures in the Aspire AppHost as observed task exceptions so local development no longer floods the console with benign unobserved-task noise
diff --git a/src/CrestApps.Core.Docs/docs/core/ai-core.md b/src/CrestApps.Core.Docs/docs/core/ai-core.md
index bb57c1a4..a7a2b371 100644
--- a/src/CrestApps.Core.Docs/docs/core/ai-core.md
+++ b/src/CrestApps.Core.Docs/docs/core/ai-core.md
@@ -25,6 +25,14 @@ AI applications need to work with multiple LLM providers (OpenAI, Azure, Ollama,
## Core Concepts
+### AI Profile
+
+An **AI Profile** is the reusable runtime definition that ties deployments, prompts, orchestration, tools, retrieval, memory, and session behavior together. It is the main contract used by higher-level features such as AI Chat and agents.
+
+Use Chat Interactions when you want fast ad hoc testing. Use an AI Profile when you want a named, reusable experience that multiple sessions, users, or orchestrators can share.
+
+See [AI Profiles](./ai-profiles.md) for the full conceptual model and guidance.
+
### Deployment
A **deployment** maps a logical name to a specific model on a specific provider connection. For example, deployment `"gpt-4o"` might map to the `gpt-4o` model on your OpenAI connection. The orchestrator resolves deployments at runtime using a fallback chain:
@@ -129,7 +137,7 @@ public interface IAICompletionClient
### `AIOptions`
-Central options class for registering profile sources, deployment providers, connection sources, and template sources.
+Central options class for registering profile sources, deployment providers, connection sources, and template sources. By default, connections are loaded from `CrestApps:AI:Connections` and deployments are loaded from `CrestApps:AI:Deployments`.
```csharp
services.Configure(options =>
diff --git a/src/CrestApps.Core.Docs/docs/core/ai-profiles.md b/src/CrestApps.Core.Docs/docs/core/ai-profiles.md
new file mode 100644
index 00000000..80347e41
--- /dev/null
+++ b/src/CrestApps.Core.Docs/docs/core/ai-profiles.md
@@ -0,0 +1,192 @@
+---
+sidebar_label: AI Profiles
+sidebar_position: 4
+title: AI Profiles
+description: Understand AI Profiles as the reusable runtime contract that powers chat, agents, orchestration, memory, and retrieval across CrestApps.Core.
+---
+
+# AI Profiles
+
+> The reusable contract that tells CrestApps.Core **how an AI experience should behave**, not just which model to call.
+
+An **AI Profile** is the main composition unit for higher-level AI features in `CrestApps.Core`. It groups the instructions, deployments, orchestrator choice, tools, knowledge, and session-processing rules that define a reusable AI experience.
+
+If a deployment answers **"which model should run?"**, an AI Profile answers **"how should this experience behave from start to finish?"**
+
+## Why AI Profiles matter
+
+Profiles are used across many parts of the framework because they let you define AI behavior once and reuse it consistently:
+
+- **AI Chat** uses a profile as the session contract for reusable conversations
+- **Agents** use profiles to describe specialized behavior and routing intent
+- **Orchestration** reads the profile to decide how prompts, tools, and downstream steps should run
+- **Knowledge-aware chat** uses profile-attached documents and data sources for retrieval
+- **Memory and analytics** use profile settings to control long-lived personalization and post-session processing
+- **Templates** can prefill or stamp profile behavior so teams do not repeat the same configuration manually
+
+## AI Profile vs. other AI building blocks
+
+| Concept | Purpose | Best way to think about it |
+| --- | --- | --- |
+| **AI Connection** | Stores provider credentials and endpoint details | "How do I talk to a provider?" |
+| **AI Deployment** | Maps a logical deployment name to a concrete model on a provider/connection | "Which model should be used?" |
+| **Chat Interactions** | Playground-style or ad hoc conversations with directly chosen parameters | "Let me test this setup quickly." |
+| **AI Profile** | Reusable runtime behavior for chat, agents, orchestration, knowledge, and processing | "How should this AI experience behave?" |
+| **AI Chat** | Session-driven chat experience built around a selected profile | "Run ongoing conversations from this reusable profile." |
+
+## When to use Chat Interactions vs. AI Profiles
+
+Start with **Chat Interactions** when you want the fastest validation path for a new provider connection and deployment.
+
+Move to **AI Profiles** when you want any of the following:
+
+- a reusable system prompt or welcome experience
+- a stable deployment choice for repeated sessions
+- orchestration and tool usage
+- knowledge retrieval from documents or data sources
+- memory, analytics, extraction, or post-session behavior
+- agent-style routing or specialized assistant identities
+
+## What an AI Profile contains
+
+The exact fields depend on enabled features, but a profile can act as the home for:
+
+### 1. Identity and purpose
+
+- technical name
+- display title
+- profile type
+- description, especially for agent profiles
+
+This gives the runtime and UI a stable identity for the experience.
+
+### 2. Deployment selection
+
+A profile can point to:
+
+- a **chat deployment** for primary conversational responses
+- a **utility deployment** for supporting tasks such as planning, extraction, or summarization
+
+That lets the same profile use different models for different responsibilities.
+
+### 3. Prompt and conversation behavior
+
+Profiles can define:
+
+- system instructions
+- welcome message
+- initial assistant prompt
+- prompt subject
+- prompt templates
+- completion settings such as temperature, top-p, penalties, token limits, and past-message depth
+
+This is where you shape tone, constraints, and conversation style.
+
+### 4. Orchestration and tool usage
+
+Profiles can select:
+
+- an orchestrator
+- local tools
+- agent references
+- remote A2A connections
+- remote MCP connections
+
+This is why profiles are broader than plain chat presets. They can define how the AI experience coordinates work, not just how it talks.
+
+### 5. Knowledge and retrieval
+
+Profiles can be linked to:
+
+- uploaded profile documents
+- session document behavior
+- index-backed data sources
+- retrieval tuning such as strictness, top-N, scope, and filters
+
+This makes the profile the reusable knowledge boundary for RAG-oriented experiences.
+
+### 6. Session and outcome processing
+
+Profiles can enable:
+
+- extracted data definitions
+- session metrics
+- AI resolution detection
+- conversion goals
+- post-session processing tasks
+
+That turns a profile into more than a prompt container. It becomes the contract for what should happen during and after a session.
+
+### 7. Memory and personalization
+
+Profiles can opt into user memory so experiences can carry durable context forward between sessions instead of starting from zero every time.
+
+## Profile types
+
+`AIProfile.Type` lets one model support different runtime roles.
+
+Common examples:
+
+- **Chat** for reusable conversational assistants
+- **Agent** for specialized routed behavior that an orchestrator can call when appropriate
+- **TemplatePrompt** when the profile is oriented around prompt generation or reusable prompt-driven tasks
+
+The important idea is that the profile type changes how the framework interprets and uses the same underlying profile record.
+
+## Typical lifecycle
+
+1. Create a provider connection.
+2. Create one or more deployments.
+3. Use **Chat Interactions** to verify the model behaves correctly.
+4. Create an AI Profile once you want a reusable behavior contract.
+5. Attach tools, documents, data sources, memory, or post-session rules as needed.
+6. Use the profile from AI Chat, agents, orchestrators, or other runtime features.
+
+## Practical examples
+
+### Example 1: Reusable support assistant
+
+Use an AI Profile when you want:
+
+- a fixed support tone
+- a shared knowledge base
+- extracted contact or issue fields
+- post-session resolution analysis
+
+This profile can then power every support chat session consistently.
+
+### Example 2: Specialized agent
+
+Use an AI Profile when you want:
+
+- a description that explains what the agent is good at
+- a specific deployment and tool set
+- orchestration-based routing into that agent
+
+The profile becomes the unit the orchestrator can reason about and invoke.
+
+### Example 3: Knowledge-aware internal assistant
+
+Use an AI Profile when you want:
+
+- indexed data sources
+- attached profile documents
+- stricter retrieval settings
+- user memory for returning employees
+
+That profile can then serve as a reusable internal assistant instead of rebuilding the configuration per session.
+
+## Design guidance
+
+- Use **deployments** to separate model selection from behavior.
+- Use **profiles** to capture reusable behavior and lifecycle rules.
+- Use **Chat Interactions** for fast testing and experimentation.
+- Use **AI Chat** when you want repeatable session-based experiences built on top of a profile.
+
+## Related docs
+
+- [AI Core](./ai-core.md)
+- [Chat Interactions](./chat.md)
+- [AI Templates](./ai-templates.md)
+- [AI Agents](./agents.md)
+- [MVC Example](./mvc-example.md)
diff --git a/src/CrestApps.Core.Docs/docs/core/chat.md b/src/CrestApps.Core.Docs/docs/core/chat.md
index 64ea22e4..688ecec8 100644
--- a/src/CrestApps.Core.Docs/docs/core/chat.md
+++ b/src/CrestApps.Core.Docs/docs/core/chat.md
@@ -9,7 +9,7 @@ description: Chat session management, interaction handlers, and response routing
> Manages chat sessions, routes responses through pluggable handlers, and tracks interaction history.
-If you want the easiest playground-style UI for a new host, start here after you have one provider connection, one deployment, and one AI profile configured.
+If you want the easiest playground-style UI for a new host, start here after you have one provider connection and one deployment configured. Unlike AI Chat, Chat Interactions do not require an AI Profile to get started.
## Quick Start
@@ -22,6 +22,8 @@ builder.Services.AddCrestAppsCore(crestApps => crestApps
By default, connections are discovered from `CrestApps:AI:Connections` and deployments are discovered from `CrestApps:AI:Deployments`. Connection-based deployments can reference a shared `ConnectionName`, while contained-connection deployments can embed provider-specific settings directly in the deployment entry.
+When you are ready to turn an ad hoc interaction into a reusable runtime contract, move that setup into an [AI Profile](./ai-profiles.md).
+
## Problem & Solution
A chat experience involves more than sending messages to an LLM:
diff --git a/src/CrestApps.Core.Docs/docs/core/index.md b/src/CrestApps.Core.Docs/docs/core/index.md
index 180c5401..a49b6f97 100644
--- a/src/CrestApps.Core.Docs/docs/core/index.md
+++ b/src/CrestApps.Core.Docs/docs/core/index.md
@@ -48,7 +48,7 @@ By default:
- connections are loaded from `CrestApps:AI:Connections`
- deployments are loaded from `CrestApps:AI:Deployments`
-The quickest way to validate the setup is to create an AI profile and use **Chat Interactions** as your first playground-style UI.
+The quickest way to validate the setup is to use **Chat Interactions** first, then create an [AI Profile](./ai-profiles.md) when you want reusable chat, agent, or orchestration behavior.
## Package map
diff --git a/src/CrestApps.Core.Docs/docs/mcp/client.md b/src/CrestApps.Core.Docs/docs/mcp/client.md
index d3cff9ae..3f19e5ab 100644
--- a/src/CrestApps.Core.Docs/docs/mcp/client.md
+++ b/src/CrestApps.Core.Docs/docs/mcp/client.md
@@ -18,7 +18,9 @@ builder.Services
.AddCoreAIMcpClient();
```
-This registers transport providers, OAuth2 support, the core `McpService` that manages connections to remote MCP servers, and the shared AI-profile completion-context handler that flows selected MCP connection IDs into the completion request.
+This registers the shared MCP runtime services, the default SSE and StdIO transport providers, the core `McpService` that manages connections to remote MCP servers, the MCP tool-registry provider, and the shared AI-profile completion-context handler that flows selected MCP connection IDs into the completion request.
+
+If your host needs the shared MCP runtime registrations without automatically enabling the StdIO transport, call `AddCoreAIMcpServices()` and then opt into transports explicitly, or call `AddCoreAIMcpClient(includeStdIoTransport: false)`.
## Problem & Solution
@@ -40,9 +42,14 @@ The MCP client framework:
|---------|---------------|----------|---------|
| `McpService` | — | Scoped | Creates MCP clients for configured connections |
| `IOAuth2TokenService` | `DefaultOAuth2TokenService` | Scoped | OAuth2 token acquisition and caching |
+| `IMcpMetadataPromptGenerator` | `DefaultMcpMetadataPromptGenerator` | Singleton | Builds prompt text from remote MCP metadata |
+| `IMcpCapabilityEmbeddingCacheProvider` | `InMemoryMcpCapabilityEmbeddingCacheProvider` | Singleton | Caches capability embeddings for hybrid MCP resolution |
+| `IMcpServerMetadataCacheProvider` | `DefaultMcpServerMetadataProvider` | Scoped | Loads and caches remote MCP server metadata |
+| `IMcpCapabilityResolver` | `DefaultMcpCapabilityResolver` | Scoped | Resolves likely MCP capabilities for a prompt |
| `IMcpClientTransportProvider` | `SseClientTransportProvider` | Scoped | Server-Sent Events transport |
| `IMcpClientTransportProvider` | `StdioClientTransportProvider` | Scoped | Standard I/O transport |
| `IAICompletionContextBuilderHandler` | `McpAICompletionContextBuilderHandler` | Scoped | Copies selected MCP connection IDs from AI profile metadata into the completion context |
+| `IToolRegistryProvider` | `McpToolRegistryProvider` | Scoped | Publishes remote MCP tools into the AI tool registry |
Two transport types are automatically registered in `McpClientAIOptions`:
diff --git a/src/CrestApps.Core.Docs/docs/mcp/server.md b/src/CrestApps.Core.Docs/docs/mcp/server.md
index 678204af..46f39639 100644
--- a/src/CrestApps.Core.Docs/docs/mcp/server.md
+++ b/src/CrestApps.Core.Docs/docs/mcp/server.md
@@ -22,6 +22,8 @@ builder.Services
`AddCoreAIMcpServer()` registers the shared prompt and resource services. FTP and SFTP resource handlers now live in the optional `CrestApps.Core.AI.Ftp` and `CrestApps.Core.AI.Sftp` packages, so hosts opt into those transport dependencies explicitly.
+When the same host also acts as an MCP client, use `AddCoreAIMcpServices()` or `AddCoreAIMcpClient(...)` once for the shared runtime pieces, then layer `AddCoreAIMcpServer()` on top for the prompt and resource services.
+
## Problem & Solution
External AI clients — IDE assistants, chat agents, orchestration frameworks — need a standardized way to discover and call your application's tools, read your prompts, and access your resources. The [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) provides that standard.
diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/CrestApps.Core.AI.Mcp.csproj b/src/Primitives/CrestApps.Core.AI.Mcp/CrestApps.Core.AI.Mcp.csproj
index ec93d284..7589f490 100644
--- a/src/Primitives/CrestApps.Core.AI.Mcp/CrestApps.Core.AI.Mcp.csproj
+++ b/src/Primitives/CrestApps.Core.AI.Mcp/CrestApps.Core.AI.Mcp.csproj
@@ -21,6 +21,8 @@ Model Context Protocol (MCP) implementation for CrestApps AI services.
+
+
diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Functions/McpInvokeFunction.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Functions/McpInvokeFunction.cs
new file mode 100644
index 00000000..25f4887c
--- /dev/null
+++ b/src/Primitives/CrestApps.Core.AI.Mcp/Functions/McpInvokeFunction.cs
@@ -0,0 +1,289 @@
+using System.Text.Json;
+using CrestApps.Core.AI.Mcp.Models;
+using CrestApps.Core.Services;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using ModelContextProtocol.Client;
+
+namespace CrestApps.Core.AI.Mcp.Functions;
+
+internal sealed class McpInvokeFunction : AIFunction
+{
+ public const string FunctionName = "mcp_invoke";
+
+ private static readonly JsonElement _jsonSchema = JsonSerializer.Deserialize(
+ """
+ {
+ "type": "object",
+ "properties": {
+ "clientId": {
+ "type": "string",
+ "description": "The MCP server connection identifier."
+ },
+ "type": {
+ "type": "string",
+ "enum": ["tool", "prompt", "resource"],
+ "description": "The type of MCP capability to invoke."
+ },
+ "id": {
+ "type": "string",
+ "description": "For tools and prompts, this is the capability name. For resources, this MUST be the fully-resolved resource URI."
+ },
+ "inputs": {
+ "type": "object",
+ "description": "The input arguments for the invocation. For tools, these MUST match the tool's Parameters schema exactly."
+ }
+ },
+ "required": ["clientId", "type", "id"],
+ "additionalProperties": false
+ }
+ """);
+
+ public override string Name => FunctionName;
+ public override string Description => "Invoke an MCP server capability (tool, prompt, or resource) by specifying the server, capability type, and identifier.";
+ public override JsonElement JsonSchema => _jsonSchema;
+
+ public override IReadOnlyDictionary AdditionalProperties { get; } = new Dictionary
+ {
+ ["Strict"] = false,
+ };
+
+ protected override async ValueTask