petergits commited on
Commit ·
a811242
1
Parent(s): 30a536d
this is the first checkin, probably don't need the node modules.
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +1 -0
- assets/add-tool-to-agent.png +3 -0
- assets/addaction.png +3 -0
- assets/addatool.png +3 -0
- assets/additionalpermissions.png +3 -0
- assets/azd-deploy-server.png +3 -0
- assets/azd-down-confirmation.png +3 -0
- assets/chucknorrisjoke.png +3 -0
- assets/configure.png +3 -0
- assets/connect.png +3 -0
- assets/connected.png +3 -0
- assets/continue.png +3 -0
- assets/create-connection-action-create.png +3 -0
- assets/create-connection-action.png +3 -0
- assets/dadjoke.png +3 -0
- assets/github-copilot-get-joke.png +3 -0
- assets/githubcreate.png +3 -0
- assets/githubcreaterepo.png +3 -0
- assets/githubreponame.png +3 -0
- assets/githubrepoowner.png +3 -0
- assets/githubusetemplate.png +3 -0
- assets/gotoresource.png +3 -0
- assets/import-from-github.png +3 -0
- assets/inresourcegrpcreate.png +3 -0
- assets/mcpsteps.png +3 -0
- assets/newagent.png +3 -0
- assets/newconnector.png +3 -0
- assets/newfeatures.png +3 -0
- assets/refreshtestingpane.png +3 -0
- assets/replaceswagger.png +3 -0
- assets/settings.png +3 -0
- assets/skiptoconfigure.png +3 -0
- assets/submitconnection.png +3 -0
- assets/tools-menu.png +3 -0
- assets/tools.png +3 -0
- assets/turnoffgeneralknowledge.png +3 -0
- assets/turnonorchestration.png +3 -0
- assets/usetemplate.png +3 -0
- assets/vscode-terminal-ports-forward.png +3 -0
- assets/vscode-terminal-ports-setup.png +3 -0
- assets/vscode-terminal-ports.png +3 -0
- assets/vscode-terminal-run-start.png +3 -0
- azure.yaml +12 -0
- dist/server.js +128 -0
- infra/abbreviations.json +136 -0
- infra/main.bicep +44 -0
- infra/main.parameters.json +18 -0
- infra/modules/fetch-container-image.bicep +8 -0
- infra/resources.bicep +122 -0
- node_modules/.bin/node-which +1 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
*.png filter=lfs diff=lfs merge=lfs -text
|
assets/add-tool-to-agent.png
ADDED
|
Git LFS Details
|
assets/addaction.png
ADDED
|
Git LFS Details
|
assets/addatool.png
ADDED
|
Git LFS Details
|
assets/additionalpermissions.png
ADDED
|
Git LFS Details
|
assets/azd-deploy-server.png
ADDED
|
Git LFS Details
|
assets/azd-down-confirmation.png
ADDED
|
Git LFS Details
|
assets/chucknorrisjoke.png
ADDED
|
Git LFS Details
|
assets/configure.png
ADDED
|
Git LFS Details
|
assets/connect.png
ADDED
|
Git LFS Details
|
assets/connected.png
ADDED
|
Git LFS Details
|
assets/continue.png
ADDED
|
Git LFS Details
|
assets/create-connection-action-create.png
ADDED
|
Git LFS Details
|
assets/create-connection-action.png
ADDED
|
Git LFS Details
|
assets/dadjoke.png
ADDED
|
Git LFS Details
|
assets/github-copilot-get-joke.png
ADDED
|
Git LFS Details
|
assets/githubcreate.png
ADDED
|
Git LFS Details
|
assets/githubcreaterepo.png
ADDED
|
Git LFS Details
|
assets/githubreponame.png
ADDED
|
Git LFS Details
|
assets/githubrepoowner.png
ADDED
|
Git LFS Details
|
assets/githubusetemplate.png
ADDED
|
Git LFS Details
|
assets/gotoresource.png
ADDED
|
Git LFS Details
|
assets/import-from-github.png
ADDED
|
Git LFS Details
|
assets/inresourcegrpcreate.png
ADDED
|
Git LFS Details
|
assets/mcpsteps.png
ADDED
|
Git LFS Details
|
assets/newagent.png
ADDED
|
Git LFS Details
|
assets/newconnector.png
ADDED
|
Git LFS Details
|
assets/newfeatures.png
ADDED
|
Git LFS Details
|
assets/refreshtestingpane.png
ADDED
|
Git LFS Details
|
assets/replaceswagger.png
ADDED
|
Git LFS Details
|
assets/settings.png
ADDED
|
Git LFS Details
|
assets/skiptoconfigure.png
ADDED
|
Git LFS Details
|
assets/submitconnection.png
ADDED
|
Git LFS Details
|
assets/tools-menu.png
ADDED
|
Git LFS Details
|
assets/tools.png
ADDED
|
Git LFS Details
|
assets/turnoffgeneralknowledge.png
ADDED
|
Git LFS Details
|
assets/turnonorchestration.png
ADDED
|
Git LFS Details
|
assets/usetemplate.png
ADDED
|
Git LFS Details
|
assets/vscode-terminal-ports-forward.png
ADDED
|
Git LFS Details
|
assets/vscode-terminal-ports-setup.png
ADDED
|
Git LFS Details
|
assets/vscode-terminal-ports.png
ADDED
|
Git LFS Details
|
assets/vscode-terminal-run-start.png
ADDED
|
Git LFS Details
|
azure.yaml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
|
| 2 |
+
|
| 3 |
+
name: jokesmcp-http-typescript
|
| 4 |
+
metadata:
|
| 5 |
+
template: azd-init@1.15.1
|
| 6 |
+
services:
|
| 7 |
+
jokesmcp-http-typescript:
|
| 8 |
+
project: .
|
| 9 |
+
host: containerapp
|
| 10 |
+
language: js
|
| 11 |
+
docker:
|
| 12 |
+
path: Dockerfile
|
dist/server.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import express from "express";
|
| 2 |
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
| 3 |
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
| 4 |
+
import { z } from "zod";
|
| 5 |
+
const server = new McpServer({
|
| 6 |
+
name: "mcp-streamable-http",
|
| 7 |
+
version: "1.0.0",
|
| 8 |
+
});
|
| 9 |
+
// Get Chuck Norris joke tool
|
| 10 |
+
const getChuckJoke = server.tool("get-chuck-joke", "Get a random Chuck Norris joke", async () => {
|
| 11 |
+
const response = await fetch("https://api.chucknorris.io/jokes/random");
|
| 12 |
+
const data = await response.json();
|
| 13 |
+
return {
|
| 14 |
+
content: [
|
| 15 |
+
{
|
| 16 |
+
type: "text",
|
| 17 |
+
text: data.value,
|
| 18 |
+
},
|
| 19 |
+
],
|
| 20 |
+
};
|
| 21 |
+
});
|
| 22 |
+
// Get Chuck Norris joke by category tool
|
| 23 |
+
const getChuckJokeByCategory = server.tool("get-chuck-joke-by-category", "Get a random Chuck Norris joke by category", {
|
| 24 |
+
category: z.string().describe("Category of the Chuck Norris joke"),
|
| 25 |
+
}, async (params) => {
|
| 26 |
+
const response = await fetch(`https://api.chucknorris.io/jokes/random?category=${params.category}`);
|
| 27 |
+
const data = await response.json();
|
| 28 |
+
return {
|
| 29 |
+
content: [
|
| 30 |
+
{
|
| 31 |
+
type: "text",
|
| 32 |
+
text: data.value,
|
| 33 |
+
},
|
| 34 |
+
],
|
| 35 |
+
};
|
| 36 |
+
});
|
| 37 |
+
// Get Chuck Norris joke categories tool
|
| 38 |
+
const getChuckCategories = server.tool("get-chuck-categories", "Get all available categories for Chuck Norris jokes", async () => {
|
| 39 |
+
const response = await fetch("https://api.chucknorris.io/jokes/categories");
|
| 40 |
+
const data = await response.json();
|
| 41 |
+
return {
|
| 42 |
+
content: [
|
| 43 |
+
{
|
| 44 |
+
type: "text",
|
| 45 |
+
text: data.join(", "),
|
| 46 |
+
},
|
| 47 |
+
],
|
| 48 |
+
};
|
| 49 |
+
});
|
| 50 |
+
// Get Dad joke tool
|
| 51 |
+
const getDadJoke = server.tool("get-dad-joke", "Get a random dad joke", async () => {
|
| 52 |
+
const response = await fetch("https://icanhazdadjoke.com/", {
|
| 53 |
+
headers: {
|
| 54 |
+
Accept: "application/json",
|
| 55 |
+
},
|
| 56 |
+
});
|
| 57 |
+
const data = await response.json();
|
| 58 |
+
return {
|
| 59 |
+
content: [
|
| 60 |
+
{
|
| 61 |
+
type: "text",
|
| 62 |
+
text: data.joke,
|
| 63 |
+
},
|
| 64 |
+
],
|
| 65 |
+
};
|
| 66 |
+
});
|
| 67 |
+
const app = express();
|
| 68 |
+
app.use(express.json());
|
| 69 |
+
const transport = new StreamableHTTPServerTransport({
|
| 70 |
+
sessionIdGenerator: undefined, // set to undefined for stateless servers
|
| 71 |
+
});
|
| 72 |
+
// Setup routes for the server
|
| 73 |
+
const setupServer = async () => {
|
| 74 |
+
await server.connect(transport);
|
| 75 |
+
};
|
| 76 |
+
app.post("/mcp", async (req, res) => {
|
| 77 |
+
console.log("Received MCP request:", req.body);
|
| 78 |
+
try {
|
| 79 |
+
await transport.handleRequest(req, res, req.body);
|
| 80 |
+
}
|
| 81 |
+
catch (error) {
|
| 82 |
+
console.error("Error handling MCP request:", error);
|
| 83 |
+
if (!res.headersSent) {
|
| 84 |
+
res.status(500).json({
|
| 85 |
+
jsonrpc: "2.0",
|
| 86 |
+
error: {
|
| 87 |
+
code: -32603,
|
| 88 |
+
message: "Internal server error",
|
| 89 |
+
},
|
| 90 |
+
id: null,
|
| 91 |
+
});
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
});
|
| 95 |
+
app.get("/mcp", async (req, res) => {
|
| 96 |
+
console.log("Received GET MCP request");
|
| 97 |
+
res.writeHead(405).end(JSON.stringify({
|
| 98 |
+
jsonrpc: "2.0",
|
| 99 |
+
error: {
|
| 100 |
+
code: -32000,
|
| 101 |
+
message: "Method not allowed.",
|
| 102 |
+
},
|
| 103 |
+
id: null,
|
| 104 |
+
}));
|
| 105 |
+
});
|
| 106 |
+
app.delete("/mcp", async (req, res) => {
|
| 107 |
+
console.log("Received DELETE MCP request");
|
| 108 |
+
res.writeHead(405).end(JSON.stringify({
|
| 109 |
+
jsonrpc: "2.0",
|
| 110 |
+
error: {
|
| 111 |
+
code: -32000,
|
| 112 |
+
message: "Method not allowed.",
|
| 113 |
+
},
|
| 114 |
+
id: null,
|
| 115 |
+
}));
|
| 116 |
+
});
|
| 117 |
+
// Start the server
|
| 118 |
+
const PORT = process.env.PORT || 3000;
|
| 119 |
+
setupServer()
|
| 120 |
+
.then(() => {
|
| 121 |
+
app.listen(PORT, () => {
|
| 122 |
+
console.log(`MCP Streamable HTTP Server listening on port ${PORT}`);
|
| 123 |
+
});
|
| 124 |
+
})
|
| 125 |
+
.catch((error) => {
|
| 126 |
+
console.error("Failed to set up the server:", error);
|
| 127 |
+
process.exit(1);
|
| 128 |
+
});
|
infra/abbreviations.json
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"analysisServicesServers": "as",
|
| 3 |
+
"apiManagementService": "apim-",
|
| 4 |
+
"appConfigurationStores": "appcs-",
|
| 5 |
+
"appManagedEnvironments": "cae-",
|
| 6 |
+
"appContainerApps": "ca-",
|
| 7 |
+
"authorizationPolicyDefinitions": "policy-",
|
| 8 |
+
"automationAutomationAccounts": "aa-",
|
| 9 |
+
"blueprintBlueprints": "bp-",
|
| 10 |
+
"blueprintBlueprintsArtifacts": "bpa-",
|
| 11 |
+
"cacheRedis": "redis-",
|
| 12 |
+
"cdnProfiles": "cdnp-",
|
| 13 |
+
"cdnProfilesEndpoints": "cdne-",
|
| 14 |
+
"cognitiveServicesAccounts": "cog-",
|
| 15 |
+
"cognitiveServicesFormRecognizer": "cog-fr-",
|
| 16 |
+
"cognitiveServicesTextAnalytics": "cog-ta-",
|
| 17 |
+
"computeAvailabilitySets": "avail-",
|
| 18 |
+
"computeCloudServices": "cld-",
|
| 19 |
+
"computeDiskEncryptionSets": "des",
|
| 20 |
+
"computeDisks": "disk",
|
| 21 |
+
"computeDisksOs": "osdisk",
|
| 22 |
+
"computeGalleries": "gal",
|
| 23 |
+
"computeSnapshots": "snap-",
|
| 24 |
+
"computeVirtualMachines": "vm",
|
| 25 |
+
"computeVirtualMachineScaleSets": "vmss-",
|
| 26 |
+
"containerInstanceContainerGroups": "ci",
|
| 27 |
+
"containerRegistryRegistries": "cr",
|
| 28 |
+
"containerServiceManagedClusters": "aks-",
|
| 29 |
+
"databricksWorkspaces": "dbw-",
|
| 30 |
+
"dataFactoryFactories": "adf-",
|
| 31 |
+
"dataLakeAnalyticsAccounts": "dla",
|
| 32 |
+
"dataLakeStoreAccounts": "dls",
|
| 33 |
+
"dataMigrationServices": "dms-",
|
| 34 |
+
"dBforMySQLServers": "mysql-",
|
| 35 |
+
"dBforPostgreSQLServers": "psql-",
|
| 36 |
+
"devicesIotHubs": "iot-",
|
| 37 |
+
"devicesProvisioningServices": "provs-",
|
| 38 |
+
"devicesProvisioningServicesCertificates": "pcert-",
|
| 39 |
+
"documentDBDatabaseAccounts": "cosmos-",
|
| 40 |
+
"documentDBMongoDatabaseAccounts": "cosmon-",
|
| 41 |
+
"eventGridDomains": "evgd-",
|
| 42 |
+
"eventGridDomainsTopics": "evgt-",
|
| 43 |
+
"eventGridEventSubscriptions": "evgs-",
|
| 44 |
+
"eventHubNamespaces": "evhns-",
|
| 45 |
+
"eventHubNamespacesEventHubs": "evh-",
|
| 46 |
+
"hdInsightClustersHadoop": "hadoop-",
|
| 47 |
+
"hdInsightClustersHbase": "hbase-",
|
| 48 |
+
"hdInsightClustersKafka": "kafka-",
|
| 49 |
+
"hdInsightClustersMl": "mls-",
|
| 50 |
+
"hdInsightClustersSpark": "spark-",
|
| 51 |
+
"hdInsightClustersStorm": "storm-",
|
| 52 |
+
"hybridComputeMachines": "arcs-",
|
| 53 |
+
"insightsActionGroups": "ag-",
|
| 54 |
+
"insightsComponents": "appi-",
|
| 55 |
+
"keyVaultVaults": "kv-",
|
| 56 |
+
"kubernetesConnectedClusters": "arck",
|
| 57 |
+
"kustoClusters": "dec",
|
| 58 |
+
"kustoClustersDatabases": "dedb",
|
| 59 |
+
"logicIntegrationAccounts": "ia-",
|
| 60 |
+
"logicWorkflows": "logic-",
|
| 61 |
+
"machineLearningServicesWorkspaces": "mlw-",
|
| 62 |
+
"managedIdentityUserAssignedIdentities": "id-",
|
| 63 |
+
"managementManagementGroups": "mg-",
|
| 64 |
+
"migrateAssessmentProjects": "migr-",
|
| 65 |
+
"networkApplicationGateways": "agw-",
|
| 66 |
+
"networkApplicationSecurityGroups": "asg-",
|
| 67 |
+
"networkAzureFirewalls": "afw-",
|
| 68 |
+
"networkBastionHosts": "bas-",
|
| 69 |
+
"networkConnections": "con-",
|
| 70 |
+
"networkDnsZones": "dnsz-",
|
| 71 |
+
"networkExpressRouteCircuits": "erc-",
|
| 72 |
+
"networkFirewallPolicies": "afwp-",
|
| 73 |
+
"networkFirewallPoliciesWebApplication": "waf",
|
| 74 |
+
"networkFirewallPoliciesRuleGroups": "wafrg",
|
| 75 |
+
"networkFrontDoors": "fd-",
|
| 76 |
+
"networkFrontdoorWebApplicationFirewallPolicies": "fdfp-",
|
| 77 |
+
"networkLoadBalancersExternal": "lbe-",
|
| 78 |
+
"networkLoadBalancersInternal": "lbi-",
|
| 79 |
+
"networkLoadBalancersInboundNatRules": "rule-",
|
| 80 |
+
"networkLocalNetworkGateways": "lgw-",
|
| 81 |
+
"networkNatGateways": "ng-",
|
| 82 |
+
"networkNetworkInterfaces": "nic-",
|
| 83 |
+
"networkNetworkSecurityGroups": "nsg-",
|
| 84 |
+
"networkNetworkSecurityGroupsSecurityRules": "nsgsr-",
|
| 85 |
+
"networkNetworkWatchers": "nw-",
|
| 86 |
+
"networkPrivateDnsZones": "pdnsz-",
|
| 87 |
+
"networkPrivateLinkServices": "pl-",
|
| 88 |
+
"networkPublicIPAddresses": "pip-",
|
| 89 |
+
"networkPublicIPPrefixes": "ippre-",
|
| 90 |
+
"networkRouteFilters": "rf-",
|
| 91 |
+
"networkRouteTables": "rt-",
|
| 92 |
+
"networkRouteTablesRoutes": "udr-",
|
| 93 |
+
"networkTrafficManagerProfiles": "traf-",
|
| 94 |
+
"networkVirtualNetworkGateways": "vgw-",
|
| 95 |
+
"networkVirtualNetworks": "vnet-",
|
| 96 |
+
"networkVirtualNetworksSubnets": "snet-",
|
| 97 |
+
"networkVirtualNetworksVirtualNetworkPeerings": "peer-",
|
| 98 |
+
"networkVirtualWans": "vwan-",
|
| 99 |
+
"networkVpnGateways": "vpng-",
|
| 100 |
+
"networkVpnGatewaysVpnConnections": "vcn-",
|
| 101 |
+
"networkVpnGatewaysVpnSites": "vst-",
|
| 102 |
+
"notificationHubsNamespaces": "ntfns-",
|
| 103 |
+
"notificationHubsNamespacesNotificationHubs": "ntf-",
|
| 104 |
+
"operationalInsightsWorkspaces": "log-",
|
| 105 |
+
"portalDashboards": "dash-",
|
| 106 |
+
"powerBIDedicatedCapacities": "pbi-",
|
| 107 |
+
"purviewAccounts": "pview-",
|
| 108 |
+
"recoveryServicesVaults": "rsv-",
|
| 109 |
+
"resourcesResourceGroups": "rg-",
|
| 110 |
+
"searchSearchServices": "srch-",
|
| 111 |
+
"serviceBusNamespaces": "sb-",
|
| 112 |
+
"serviceBusNamespacesQueues": "sbq-",
|
| 113 |
+
"serviceBusNamespacesTopics": "sbt-",
|
| 114 |
+
"serviceEndPointPolicies": "se-",
|
| 115 |
+
"serviceFabricClusters": "sf-",
|
| 116 |
+
"signalRServiceSignalR": "sigr",
|
| 117 |
+
"sqlManagedInstances": "sqlmi-",
|
| 118 |
+
"sqlServers": "sql-",
|
| 119 |
+
"sqlServersDataWarehouse": "sqldw-",
|
| 120 |
+
"sqlServersDatabases": "sqldb-",
|
| 121 |
+
"sqlServersDatabasesStretch": "sqlstrdb-",
|
| 122 |
+
"storageStorageAccounts": "st",
|
| 123 |
+
"storageStorageAccountsVm": "stvm",
|
| 124 |
+
"storSimpleManagers": "ssimp",
|
| 125 |
+
"streamAnalyticsCluster": "asa-",
|
| 126 |
+
"synapseWorkspaces": "syn",
|
| 127 |
+
"synapseWorkspacesAnalyticsWorkspaces": "synw",
|
| 128 |
+
"synapseWorkspacesSqlPoolsDedicated": "syndp",
|
| 129 |
+
"synapseWorkspacesSqlPoolsSpark": "synsp",
|
| 130 |
+
"timeSeriesInsightsEnvironments": "tsi-",
|
| 131 |
+
"webServerFarms": "plan-",
|
| 132 |
+
"webSitesAppService": "app-",
|
| 133 |
+
"webSitesAppServiceEnvironment": "ase-",
|
| 134 |
+
"webSitesFunctions": "func-",
|
| 135 |
+
"webStaticSites": "stapp-"
|
| 136 |
+
}
|
infra/main.bicep
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
targetScope = 'subscription'
|
| 2 |
+
|
| 3 |
+
@minLength(1)
|
| 4 |
+
@maxLength(64)
|
| 5 |
+
@description('Name of the environment that can be used as part of naming resource convention')
|
| 6 |
+
param environmentName string
|
| 7 |
+
|
| 8 |
+
@minLength(1)
|
| 9 |
+
@description('Primary location for all resources')
|
| 10 |
+
param location string
|
| 11 |
+
|
| 12 |
+
param jokesmcpHttpTypescriptExists bool
|
| 13 |
+
|
| 14 |
+
@description('Id of the user or app to assign application roles')
|
| 15 |
+
param principalId string
|
| 16 |
+
|
| 17 |
+
// Tags that should be applied to all resources.
|
| 18 |
+
//
|
| 19 |
+
// Note that 'azd-service-name' tags should be applied separately to service host resources.
|
| 20 |
+
// Example usage:
|
| 21 |
+
// tags: union(tags, { 'azd-service-name': <service name in azure.yaml> })
|
| 22 |
+
var tags = {
|
| 23 |
+
'azd-env-name': environmentName
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
// Organize resources in a resource group
|
| 27 |
+
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
|
| 28 |
+
name: 'rg-${environmentName}'
|
| 29 |
+
location: location
|
| 30 |
+
tags: tags
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
module resources 'resources.bicep' = {
|
| 34 |
+
scope: rg
|
| 35 |
+
name: 'resources'
|
| 36 |
+
params: {
|
| 37 |
+
location: location
|
| 38 |
+
tags: tags
|
| 39 |
+
principalId: principalId
|
| 40 |
+
jokesmcpHttpTypescriptExists: jokesmcpHttpTypescriptExists
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = resources.outputs.AZURE_CONTAINER_REGISTRY_ENDPOINT
|
| 44 |
+
output AZURE_RESOURCE_JOKESMCP_HTTP_TYPESCRIPT_ID string = resources.outputs.AZURE_RESOURCE_JOKESMCP_HTTP_TYPESCRIPT_ID
|
infra/main.parameters.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
|
| 3 |
+
"contentVersion": "1.0.0.0",
|
| 4 |
+
"parameters": {
|
| 5 |
+
"environmentName": {
|
| 6 |
+
"value": "${AZURE_ENV_NAME}"
|
| 7 |
+
},
|
| 8 |
+
"location": {
|
| 9 |
+
"value": "${AZURE_LOCATION}"
|
| 10 |
+
},
|
| 11 |
+
"jokesmcpHttpTypescriptExists": {
|
| 12 |
+
"value": "${SERVICE_JOKESMCP_HTTP_TYPESCRIPT_RESOURCE_EXISTS=false}"
|
| 13 |
+
},
|
| 14 |
+
"principalId": {
|
| 15 |
+
"value": "${AZURE_PRINCIPAL_ID}"
|
| 16 |
+
}
|
| 17 |
+
}
|
| 18 |
+
}
|
infra/modules/fetch-container-image.bicep
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
param exists bool
|
| 2 |
+
param name string
|
| 3 |
+
|
| 4 |
+
resource existingApp 'Microsoft.App/containerApps@2023-05-02-preview' existing = if (exists) {
|
| 5 |
+
name: name
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
output containers array = exists ? existingApp.properties.template.containers : []
|
infra/resources.bicep
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@description('The location used for all deployed resources')
|
| 2 |
+
param location string = resourceGroup().location
|
| 3 |
+
|
| 4 |
+
@description('Tags that will be applied to all resources')
|
| 5 |
+
param tags object = {}
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
param jokesmcpHttpTypescriptExists bool
|
| 9 |
+
|
| 10 |
+
@description('Id of the user or app to assign application roles')
|
| 11 |
+
param principalId string
|
| 12 |
+
|
| 13 |
+
var abbrs = loadJsonContent('./abbreviations.json')
|
| 14 |
+
var resourceToken = uniqueString(subscription().id, resourceGroup().id, location)
|
| 15 |
+
|
| 16 |
+
// Monitor application with Azure Monitor
|
| 17 |
+
module monitoring 'br/public:avm/ptn/azd/monitoring:0.1.0' = {
|
| 18 |
+
name: 'monitoring'
|
| 19 |
+
params: {
|
| 20 |
+
logAnalyticsName: '${abbrs.operationalInsightsWorkspaces}${resourceToken}'
|
| 21 |
+
applicationInsightsName: '${abbrs.insightsComponents}${resourceToken}'
|
| 22 |
+
applicationInsightsDashboardName: '${abbrs.portalDashboards}${resourceToken}'
|
| 23 |
+
location: location
|
| 24 |
+
tags: tags
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
// Container registry
|
| 28 |
+
module containerRegistry 'br/public:avm/res/container-registry/registry:0.1.1' = {
|
| 29 |
+
name: 'registry'
|
| 30 |
+
params: {
|
| 31 |
+
name: '${abbrs.containerRegistryRegistries}${resourceToken}'
|
| 32 |
+
location: location
|
| 33 |
+
tags: tags
|
| 34 |
+
publicNetworkAccess: 'Enabled'
|
| 35 |
+
roleAssignments:[
|
| 36 |
+
{
|
| 37 |
+
principalId: jokesmcpHttpTypescriptIdentity.outputs.principalId
|
| 38 |
+
principalType: 'ServicePrincipal'
|
| 39 |
+
roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
|
| 40 |
+
}
|
| 41 |
+
]
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
// Container apps environment
|
| 46 |
+
module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.4.5' = {
|
| 47 |
+
name: 'container-apps-environment'
|
| 48 |
+
params: {
|
| 49 |
+
logAnalyticsWorkspaceResourceId: monitoring.outputs.logAnalyticsWorkspaceResourceId
|
| 50 |
+
name: '${abbrs.appManagedEnvironments}${resourceToken}'
|
| 51 |
+
location: location
|
| 52 |
+
zoneRedundant: false
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
module jokesmcpHttpTypescriptIdentity 'br/public:avm/res/managed-identity/user-assigned-identity:0.2.1' = {
|
| 57 |
+
name: 'jokesmcpHttpTypescriptidentity'
|
| 58 |
+
params: {
|
| 59 |
+
name: '${abbrs.managedIdentityUserAssignedIdentities}jokesmcpHttpTypescript-${resourceToken}'
|
| 60 |
+
location: location
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
module jokesmcpHttpTypescriptFetchLatestImage './modules/fetch-container-image.bicep' = {
|
| 64 |
+
name: 'jokesmcpHttpTypescript-fetch-image'
|
| 65 |
+
params: {
|
| 66 |
+
exists: jokesmcpHttpTypescriptExists
|
| 67 |
+
name: 'jokesmcp-http-typescript'
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
module jokesmcpHttpTypescript 'br/public:avm/res/app/container-app:0.8.0' = {
|
| 72 |
+
name: 'jokesmcpHttpTypescript'
|
| 73 |
+
params: {
|
| 74 |
+
name: 'jokesmcp-http-typescript'
|
| 75 |
+
ingressTargetPort: 3000
|
| 76 |
+
scaleMinReplicas: 1
|
| 77 |
+
scaleMaxReplicas: 10
|
| 78 |
+
secrets: {
|
| 79 |
+
secureList: [
|
| 80 |
+
]
|
| 81 |
+
}
|
| 82 |
+
containers: [
|
| 83 |
+
{
|
| 84 |
+
image: jokesmcpHttpTypescriptFetchLatestImage.outputs.?containers[?0].?image ?? 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
|
| 85 |
+
name: 'main'
|
| 86 |
+
resources: {
|
| 87 |
+
cpu: json('0.5')
|
| 88 |
+
memory: '1.0Gi'
|
| 89 |
+
}
|
| 90 |
+
env: [
|
| 91 |
+
{
|
| 92 |
+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
| 93 |
+
value: monitoring.outputs.applicationInsightsConnectionString
|
| 94 |
+
}
|
| 95 |
+
{
|
| 96 |
+
name: 'AZURE_CLIENT_ID'
|
| 97 |
+
value: jokesmcpHttpTypescriptIdentity.outputs.clientId
|
| 98 |
+
}
|
| 99 |
+
{
|
| 100 |
+
name: 'PORT'
|
| 101 |
+
value: '3000'
|
| 102 |
+
}
|
| 103 |
+
]
|
| 104 |
+
}
|
| 105 |
+
]
|
| 106 |
+
managedIdentities:{
|
| 107 |
+
systemAssigned: false
|
| 108 |
+
userAssignedResourceIds: [jokesmcpHttpTypescriptIdentity.outputs.resourceId]
|
| 109 |
+
}
|
| 110 |
+
registries:[
|
| 111 |
+
{
|
| 112 |
+
server: containerRegistry.outputs.loginServer
|
| 113 |
+
identity: jokesmcpHttpTypescriptIdentity.outputs.resourceId
|
| 114 |
+
}
|
| 115 |
+
]
|
| 116 |
+
environmentResourceId: containerAppsEnvironment.outputs.resourceId
|
| 117 |
+
location: location
|
| 118 |
+
tags: union(tags, { 'azd-service-name': 'jokesmcp-http-typescript' })
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.outputs.loginServer
|
| 122 |
+
output AZURE_RESOURCE_JOKESMCP_HTTP_TYPESCRIPT_ID string = jokesmcpHttpTypescript.outputs.resourceId
|
node_modules/.bin/node-which
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
../which/bin/node-which
|