Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 149 additions & 4 deletions internal/server/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,41 @@ body {
margin: 0;
font-family: 'Trebuchet MS';
background-color: #f8f9fa;
box-sizing: border-box;
}

*, *:before, *:after {
box-sizing: inherit;
}

.left-nav {
flex: 0 0 200px;
flex: 0 0 250px;
background-color: #fff;
box-shadow: 4px 0px 12px rgba(0, 0, 0, 0.15);
z-index: 10;
display: flex;
flex-direction: column;
padding: 15px;
align-items: center;
position: relative;
z-index: 3;
}

.second-nav {
flex: 0 0 250px;
background-color: #fff;
box-shadow: 4px 0px 12px rgba(0, 0, 0, 0.15);
z-index: 10;
display: flex;
flex-direction: column;
padding: 15px;
align-items: center;
position: relative;
z-index: 2;
}

.nav-logo {
width: 100%;
width: 90%;
margin-bottom: 20px;
}

Expand All @@ -41,8 +61,8 @@ body {
}

.left-nav ul li a {
display: flex;
align-items: center;
display: flex;
align-items: center;
padding: 12px;
text-decoration: none;
color: #333;
Expand Down Expand Up @@ -87,3 +107,128 @@ body {
flex-grow: 1;
overflow-y: auto;
}

.tool-button {
display: flex;
align-items: center;
padding: 12px;
text-decoration: none;
color: #333;
background-color: transparent;
border: none;
border-radius: 0;
width: 100%;
text-align: left;
cursor: pointer;
font-family: inherit;
font-size: inherit;

transition: background-color 0.1s ease-in-out, border-radius 0.1s ease-in-out;
}

.tool-button:hover {
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated
background-color: #e9e9e9;
border-radius: 35px;
}

.tool-button:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(208, 208, 208, 0.5);
}

.tool-button.active {
background-color: #d0d0d0;
font-weight: bold;
border-radius: 35px;
}

.tool-button.active:hover {
background-color: #d0d0d0;
}

#secondary-panel-content ul {
list-style: none;
padding: 0;
margin: 0;
width: 100%;
}

.tool-details-grid {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 20px;
margin: 0 0 20px 0;
align-items: start;
}

.tool-info {
display: flex;
flex-direction: column;
gap: 15px;
}

.tool-params {
background-color: #ffffff;
padding: 15px;
border-radius: 4px;
border: 1px solid #ddd;
}

.tool-box {
background-color: #ffffff;
padding: 15px;
border-radius: 4px;
border: 1px solid #eee;
}

.tool-box h5 {
color: #4285f4ff;
margin-top: 0;
font-weight: bold;
}

.param-item {
margin-bottom: 12px;
}

.param-item label {
display: block;
margin-bottom: 4px;
font-family: inherit;
}

.param-label-extras {
font-style: italic;
font-weight: lighter;
color: rgb(125, 125, 125);
}

.param-item input[type="text"],
.param-item input[type="number"],
.param-item select,
.param-item textarea,
.param-item input[type="checkbox"] {
width: calc(100% - 12px);
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
font-family: inherit;
}

.auth-param-input {
background-color: #e0e0e0;
cursor: not-allowed;
}

.tool-response {
margin: 20px 0 0 0;
}

.tool-response textarea {
width: 100%;
min-height: 150px;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
}
8 changes: 4 additions & 4 deletions internal/server/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
<img src="/ui/assets/mcptoolboxlogo.png" alt="App Logo">
</div>
<ul>
<li><a href="sources">Sources</a></li>
<li><a href="authservices">Auth Services</a></li>
<li><a href="tools">Tools</a></li>
<li><a href="toolsets">Toolsets</a></li>
<li><a href="/ui/sources">Sources</a></li>
<li><a href="/ui/authservices">Auth Services</a></li>
<li><a href="/ui/tools">Tools</a></li>
<li><a href="/ui/toolsets">Toolsets</a></li>
</ul>
</nav>

Expand Down
126 changes: 126 additions & 0 deletions internal/server/static/js/toolDisplay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// helper function to create form inputs for parameters
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated
function createParamInput(param, toolId) {
const paramItem = document.createElement('div');
paramItem.className = 'param-item';

const label = document.createElement('label');
const inputId = `param-${toolId}-${param.name}`;
label.setAttribute('for', inputId);

const nameText = document.createTextNode(param.name);
label.appendChild(nameText);
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated

const isAuthParam = param.authServices && param.authServices.length > 0;
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated
let additionalLabelText = '';
if (isAuthParam) {
additionalLabelText += ' (auth)';
}
if (!param.required) {
additionalLabelText += ' (optional)';
}

if (additionalLabelText) {
const additionalSpan = document.createElement('span');
additionalSpan.textContent = additionalLabelText;
additionalSpan.classList.add('param-label-extras');
label.appendChild(additionalSpan);
}
paramItem.appendChild(label);

let placeholderText = param.label;
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated
let inputElement;
if (param.type === 'textarea') {
Comment thread
AlexTalreja marked this conversation as resolved.
inputElement = document.createElement('textarea');
inputElement.rows = 3;
} else if(param.type === 'checkbox') {
inputElement = document.createElement('input');
inputElement.type = 'checkbox';
Comment thread
AlexTalreja marked this conversation as resolved.
inputElement.title = placeholderText;
} else {
inputElement = document.createElement('input');
Comment thread
AlexTalreja marked this conversation as resolved.
inputElement.type = param.type;
}

inputElement.id = inputId;
inputElement.name = param.name;
if (isAuthParam) {
inputElement.disabled = true;
inputElement.classList.add('auth-param-input');
if (param.type !== 'checkbox') {
inputElement.placeholder = param.authServices;
}
} else if (param.type !== 'checkbox') {
inputElement.placeholder = placeholderText.trim();
}
paramItem.appendChild(inputElement);
return paramItem;
}

// renders the tool display area
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated
export function renderToolInterface(tool, containerElement) {
containerElement.innerHTML = '';
const toolId = tool.id;

Comment thread
AlexTalreja marked this conversation as resolved.
const gridContainer = document.createElement('div');
gridContainer.className = 'tool-details-grid';

const toolInfoContainer = document.createElement('div');
toolInfoContainer.className = 'tool-info';

const nameBox = document.createElement('div');
nameBox.className = 'tool-box tool-name';
nameBox.innerHTML = `<h5>Name:</h5><p>${tool.name}</p>`;
toolInfoContainer.appendChild(nameBox);

const descBox = document.createElement('div');
descBox.className = 'tool-box tool-description';
descBox.innerHTML = `<h5>Description:</h5><p>${tool.description}</p>`;
toolInfoContainer.appendChild(descBox);

gridContainer.appendChild(toolInfoContainer);

const paramsContainer = document.createElement('div');
paramsContainer.className = 'tool-params tool-box';
paramsContainer.innerHTML = '<h5>Parameters:</h5>';
const form = document.createElement('form');
form.id = `tool-params-form-${toolId}`;
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated

tool.parameters.forEach(param => {
form.appendChild(createParamInput(param, toolId));
});
paramsContainer.appendChild(form);

gridContainer.appendChild(paramsContainer);
containerElement.appendChild(gridContainer);

const responseContainer = document.createElement('div');
responseContainer.className = 'tool-response tool-box';

const responseHeader = document.createElement('h5');
responseHeader.textContent = 'Response:';
responseContainer.appendChild(responseHeader);

const responseAreaId = `tool-response-area-${toolId}`;
const responseArea = document.createElement('textarea');
Comment thread
AlexTalreja marked this conversation as resolved.
Outdated
responseArea.id = responseAreaId;
responseArea.readOnly = true;
responseArea.placeholder = 'Results will appear here...';
responseArea.rows = 10;
responseContainer.appendChild(responseArea);

containerElement.appendChild(responseContainer);
}
Loading
Loading